# Ark Ui > Documentation for Ark Ui --- # Ark Ui Documentation Source: https://ark-ui.com/llms-full.txt --- --- # Getting Started (REACT) ## Quickstart Running tight on schedule? No worries! Check out our quickstart examples to get started with Ark UI in seconds. - [Next.js Template](https://stackblitz.com/edit/github-qcm2dskf) - [Solid Start Template](https://stackblitz.com/edit/github-1hgkbbln) - [Nuxt Template](https://stackblitz.com/edit/github-s3sg6syq) ## Setup Guide Before you start, ensure you have a proper project setup. If not, follow your preferred application framework setup guide and then return to this guide. Install the Ark UI dependency using your preferred package manager. ```bash npm install @ark-ui/react // or pnpm install @ark-ui/react // or yarn add @ark-ui/react // or bun add @ark-ui/react ``` In this guide, we will be adding a Slider component. Copy the following code to your project. Ark UI is a headless component library that doesn't include default styles. You can leverage the `data-scope` and `data-part` attributes to style your components with custom CSS. For example, to style a slider component, you can target its parts using these attributes: ```css /* Targets the */ [data-scope='slider'][data-part='root'] { display: flex; flex-direction: column; } ``` Check out the [Styling Components guide](/react/docs/guides/styling) to learn more about styling components in Ark UI. Congratulations! You've successfully set up and styled your components using Ark UI. If you run into any issues or have questions, open an issue on our [GitHub](https://github.com/chakra-ui/ark/issues/new/choose) or reach out on [Discord](https://discord.gg/ww6HE5xaZ2). Happy hacking! ✌️ --- # Getting Started (VUE) ## Quickstart Running tight on schedule? No worries! Check out our quickstart examples to get started with Ark UI in seconds. - [Next.js Template](https://stackblitz.com/edit/github-qcm2dskf) - [Solid Start Template](https://stackblitz.com/edit/github-1hgkbbln) - [Nuxt Template](https://stackblitz.com/edit/github-s3sg6syq) ## Setup Guide Before you start, ensure you have a proper project setup. If not, follow your preferred application framework setup guide and then return to this guide. Install the Ark UI dependency using your preferred package manager. ```bash npm install @ark-ui/vue // or pnpm install @ark-ui/vue // or yarn add @ark-ui/vue // or bun add @ark-ui/vue ``` In this guide, we will be adding a Slider component. Copy the following code to your project. Ark UI is a headless component library that doesn't include default styles. You can leverage the `data-scope` and `data-part` attributes to style your components with custom CSS. For example, to style a slider component, you can target its parts using these attributes: ```css /* Targets the */ [data-scope='slider'][data-part='root'] { display: flex; flex-direction: column; } ``` Check out the [Styling Components guide](/react/docs/guides/styling) to learn more about styling components in Ark UI. Congratulations! You've successfully set up and styled your components using Ark UI. If you run into any issues or have questions, open an issue on our [GitHub](https://github.com/chakra-ui/ark/issues/new/choose) or reach out on [Discord](https://discord.gg/ww6HE5xaZ2). Happy hacking! ✌️ --- # Getting Started (SVELTE) ## Quickstart Running tight on schedule? No worries! Check out our quickstart examples to get started with Ark UI in seconds. - [Next.js Template](https://stackblitz.com/edit/github-qcm2dskf) - [Solid Start Template](https://stackblitz.com/edit/github-1hgkbbln) - [Nuxt Template](https://stackblitz.com/edit/github-s3sg6syq) ## Setup Guide Before you start, ensure you have a proper project setup. If not, follow your preferred application framework setup guide and then return to this guide. Install the Ark UI dependency using your preferred package manager. ```bash npm install @ark-ui/svelte // or pnpm install @ark-ui/svelte // or yarn add @ark-ui/svelte // or bun add @ark-ui/svelte ``` In this guide, we will be adding a Slider component. Copy the following code to your project. Ark UI is a headless component library that doesn't include default styles. You can leverage the `data-scope` and `data-part` attributes to style your components with custom CSS. For example, to style a slider component, you can target its parts using these attributes: ```css /* Targets the */ [data-scope='slider'][data-part='root'] { display: flex; flex-direction: column; } ``` Check out the [Styling Components guide](/react/docs/guides/styling) to learn more about styling components in Ark UI. Congratulations! You've successfully set up and styled your components using Ark UI. If you run into any issues or have questions, open an issue on our [GitHub](https://github.com/chakra-ui/ark/issues/new/choose) or reach out on [Discord](https://discord.gg/ww6HE5xaZ2). Happy hacking! ✌️ --- # Getting Started (SOLID) ## Quickstart Running tight on schedule? No worries! Check out our quickstart examples to get started with Ark UI in seconds. - [Next.js Template](https://stackblitz.com/edit/github-qcm2dskf) - [Solid Start Template](https://stackblitz.com/edit/github-1hgkbbln) - [Nuxt Template](https://stackblitz.com/edit/github-s3sg6syq) ## Setup Guide Before you start, ensure you have a proper project setup. If not, follow your preferred application framework setup guide and then return to this guide. Install the Ark UI dependency using your preferred package manager. ```bash npm install @ark-ui/solid // or pnpm install @ark-ui/solid // or yarn add @ark-ui/solid // or bun add @ark-ui/solid ``` In this guide, we will be adding a Slider component. Copy the following code to your project. Ark UI is a headless component library that doesn't include default styles. You can leverage the `data-scope` and `data-part` attributes to style your components with custom CSS. For example, to style a slider component, you can target its parts using these attributes: ```css /* Targets the */ [data-scope='slider'][data-part='root'] { display: flex; flex-direction: column; } ``` Check out the [Styling Components guide](/react/docs/guides/styling) to learn more about styling components in Ark UI. Congratulations! You've successfully set up and styled your components using Ark UI. If you run into any issues or have questions, open an issue on our [GitHub](https://github.com/chakra-ui/ark/issues/new/choose) or reach out on [Discord](https://discord.gg/ww6HE5xaZ2). Happy hacking! ✌️ --- # Changelog (REACT) ## [Unreleased] ### Added - **Date Picker**: Added `ValueText` component for displaying selected date value(s) with placeholder support and render prop for custom formatting - **Scroll Area**: Added overflow CSS variables (`--scroll-area-overflow-{x,y}-{start,end}`) for scroll fade effects - **Slider**: Added `thumbCollisionBehavior` prop (`none`, `push`, `swap`) - **Steps**: Added `isStepValid`, `isStepSkippable`, and `onStepInvalid` for validation support - **Tags Input**: Added `placeholder` prop (shown only when no tags exist) - **Tooltip**: Added `data-instant` attribute for instant animations ### Fixed - **Auto Resize**: Fixed change event not emitted after clearing controlled textarea - **Date Picker**: Fixed `visibleRangeText` to show correct format based on current view (year/month/day) - **Dismissable**: Fixed issue where closing a nested dialog/popover would incorrectly close its parent layers - **Menu**: Fixed glitchy submenu behavior when hovering between trigger items quickly - **Checkbox**: Fixed individual checkbox props being overridden by `CheckboxGroup` - **Collection, Tree View**: Fixed initial focus when first node/branch is disabled - **Color Picker**: Fixed color not updating when selecting black shades in controlled mode - **Floating Panel**: Fixed double-click on minimized title bar incorrectly maximizing - **Image Cropper**: Fixed `reset()` destroying cropper, prop changes not updating instantly, and panning bounds - **Number Input**: Fixed cursor positioning after clicking label or scrubbing - **Pagination**: Fixed next trigger not disabled when `count` is `0` - **Slider**: Fixed thumb drag from edge in `thumbAlignment="contain"` mode - **Switch**: Fixed `api.toggleChecked()` not working - **Toast**: Fixed toasts created before state machine connects not showing - **Tour**: Fixed janky scroll between steps ## [5.30.0] - 2025-12-10 ### Added - **Date Picker**: Added `required` and `invalid` props - **Number Input**: Added `onValueCommit` callback that fires when the input loses focus or Enter is pressed - **Pagination**: - Added `FirstTrigger` and `LastTrigger` components for navigating to first/last page - Added `boundaryCount` parameter for controlling boundary pages (start/end) - Implemented balanced pagination algorithm for consistent UI with max 7 elements - **Radio Group**: Added `invalid` and `required` props with corresponding `data-*` and `aria-*` attributes - **Tree View**: Added `scrollToIndexFn` prop to enable keyboard navigation in virtualized trees ### Fixed - **Accordion, Menu**: Fixed issue where querying elements by `aria-controls` attribute could fail when lazy mounting the content - **Color Picker**: Added `role="dialog"` to content and `aria-haspopup="dialog"` to trigger when not inline for better accessibility - **Date Picker**: Fixed issue where date picker input does not update format when locale changes - **Floating Panel**: - Fixed `dir` prop now properly delegated to all panel parts - Fixed double-click behavior improvements and to check `event.defaultPrevented` for custom behavior - **Listbox**: - Fixed issue in React where filtering items with an input would throw a `flushSync was called from inside a lifecycle method` warning - Fixed issue where `data-highlighted` wasn't applied to the first item when using `autoHighlight` with input filtering - **Number Input**: - Fixed improved controlled usage sync - Fixed issue where input element doesn't sync when `formatOptions` changes dynamically - Ensured cursor position is preserved when `Enter` key is pressed and formatting is triggered - Fixed cursor jumping to start when value is changed externally via props while user is typing - **Pagination**: Fixed ellipsis showing when only 1 page gap - **Rating Group**: Fixed issue where rating group becomes unfocusable via keyboard when value is 0 - **Tooltip**: Fixed tooltip not showing when scrolling with pointer over trigger ### Changed - **Tree View**: `getVisibleNodes()` now returns `{ node, indexPath }[]` instead of `node[]` ## [5.29.1] - 2025-11-22 ### Fixed - **Fieldset**: Fixed `aria-describedby` resolution to correctly reference helper text and error text IDs - **Floating Panel**: - Fixed resize trigger issue with `n` axis by explicitly setting `top: 0` - Fixed `draggable` and `resizable` options not being respected when set to `false` - **Presence**: Fixed regression where UNMOUNT transition might not be called consistently ## [5.29.0] - 2025-11-20 ### Added - **Carousel, Color Picker, Combobox, Date Picker, Select**: Added `value` to `OpenChangeDetails` for better context when handling open state changes - **Carousel**: Added support for `autoSize` prop to allow variable width/height slide items - **Splitter**: - Added `Splitter.ResizeTriggerIndicator` to render an indicator when resizing - Exported `getLayout` and `getSplitterLayout` functions for calculating splitter panel layouts - **Toast**: Exposed viewport offset as CSS variables on the toast group element ### Fixed - **Carousel**: - Fixed dragging behavior that stops working after switching browser tabs or scrolling the page - Fixed dragging not working after scrolling with mouse wheel when `allowMouseDrag` is enabled - **Combobox**: Fixed `onHighlightChange` not being invoked when collection is filtered to empty - **Date Picker**: Fixed issue where the range date picker crashes when typing the end date first and blurring the input field multiple times - **File Upload**: Fixed issue where clicking on non-interactive children inside the dropzone doesn't open the file picker - **Presence**: Fixed a bug where elements get stuck in unmountSuspended state during rapid state updates - **Radio Group**: - Fixed inconsistent application of `data-focus-visible` and `data-focus` attributes - **Splitter**: Fixed disabled splitter showing resize cursor and allowing dragging - **Tabs**: - Fixed tabs indicator position not updating when inactive tabs change size - **Tags Input**: Fixed issue where item delete trigger doesn't have `data-*` attached ## [5.28.0] - 2025-11-14 ### Added - **General**: Exported `InteractOutsideEvent`, `FocusOutsideEvent`, and `PointerDownOutsideEvent` types for better type safety - **Carousel**: - Added `Carousel.AutoplayIndicator` component for conditionally rendering content based on autoplay state - Added `Carousel.ProgressText` component for displaying current page progress (e.g., "1 / 5") - **Toast**: Exported `ToastOptions` and `ToastStoreProps` types for better type safety ### Changed - **useListCollection**: Updated `initialItems` to accept `readonly` arrays for better compatibility with immutable data patterns. ### Fixed - **Combobox**: - Fixed focus stealing in controlled open mode - Removed problematic `aria-hidden` behavior to allow interaction with other page elements ## [5.27.1] - 2025-11-02 ### Fixed - **Dialog, Popover**: Improved shadow DOM support for interact outside and focus trap detection - **Marquee**: Fixed Firefox flicker and added GPU acceleration - **Dialog**: Fixed layout shift issue when using `scrollbar-gutter: stable` in CSS - **Slider**: Fixed `onValueChangeEnd` callback not triggering for programmatic value changes ## [5.27.0] - 2025-11-01 ### Added - **Marquee** [New]: Initial release of marquee component for continuously scrolling content ### Fixed - **Angle Slider**: Resolved an issue where dragging the thumb from non-center positions caused unexpected value jumps. The thumb now maintains consistent positioning relative to the initial click point. - **Slider**: Fixed a problem where the thumb offset shifted dynamically during dragging, resulting in value jumps. The offset now remains constant from the pointer throughout the drag operation. - **Date Picker**: Resolved a crash in the range date picker occurring when users typed the end date first by implementing `null`/`undefined` checks for date property access. - **Radio Group**: Reverted to `offsetLeft`/`offsetTop` calculations to restore correct indicator positioning within scrollable container contexts. - **Tabs**: Reverted to `offsetLeft`/`offsetTop` calculations to fix indicator positioning issues in scrollable containers. - **Tour**: - Corrected improper effect cleanup procedures - Fixed wait step functionality - Added step validation on mount to verify configuration validity ## [5.26.2] - 2025-10-18 ### Fixed - **Angle Slider**: Fix accessibility violation where the slider thumb element lacked an accessible name. The thumb now supports `aria-label` and `aria-labelledby` props, and automatically falls back to the label element's ID for proper ARIA labeling. - **Select**: Fix accessibility violation where the required state was not set correctly to on the trigger. - **Tags Input**: Fix issue where entering a custom tag with combobox integration required pressing `Enter` twice. The tags-input now correctly handles custom values when the combobox has no highlighted item (`aria-activedescendant` is empty), allowing the tag to be added on the first `Enter` press. ## [5.26.1] - 2025-10-15 ### Fixed - **Checkbox** - Fix issue where setting initial checked state to `indeterminate` doesn't work - Ensure `api.checkedState` returns the correct checked state (`boolean | "indeterminate"`) - **Collapsible**: Fix issue where `dir` prop value was hardcoded to `ltr` instead of using the provided value - **Combobox**: Fix issue where controlled single-select combobox does not propagate its initial value to `inputValue` - **Listbox**: Fix issue where pressing Enter key when no highlighted item still calls `event.preventDefault()` - **Radio Group**: Refactor to use `getBoundingClientRect()` for precise indicator positioning - **Slider** - Fix issue where slider could stop abruptly when scrubbing thumb - Fix issue where range slider thumbs become stuck when dragged to the same position without `minStepsBetweenThumbs` - **Tabs**: Refactor to use `getBoundingClientRect()` for precise indicator positioning - **Tags Input**: Fix issue where `maxLength` doesn't apply to the edit input as well ## [5.26.0] - 2025-10-08 ### Added - **Collapsible**: Add support for `collapsedHeight` and `collapsedWidth` props to control the dimensions of the collapsible content when in its collapsed state. - **Focus Trap**: Allow elements referenced by `aria-controls` to be included in the trap scope. This makes it possible for menus, popovers, etc. to be portalled and work correctly. - **Pagination**: Add `getPageUrl` prop for generating `href` attributes when using pagination as links. ```ts const service = useMachine(pagination.machine, { type: 'link', getPageUrl: ({ page, pageSize }) => `/products?page=${page}&size=${pageSize}`, }) ``` - **Select**: Add `SelectRootComponentProps` type export for better component type composition. - **Listbox**: Add `ListboxRootComponentProps` type export for better component type composition. - **Combobox**: Add `ComboboxRootComponentProps` type export for better component type composition. - **TreeView**: - Add `TreeViewRootComponentProps` type export for better component type composition. - (Experimental) Add support for node renaming functionality: - Add `TreeViewNodeRenameInput` component for inline node label editing - Add `canRename` prop to control which nodes can be renamed - Add `onRenameStart`, `onBeforeRename`, and `onRenameComplete` callbacks for rename lifecycle - Add `CheckedChangeDetails`, `LoadChildrenErrorDetails`, `RenameStartDetails`, and `RenameCompleteDetails` type exports ### Fixed - **Scroll Area**: Fix RTL horizontal scrollbar positioning on Safari - **Slider**: Fix issue where slider continues dragging when disabled during drag operation. - **Switch**: Fix issue where `data-active` is inconsistently applied when `disabled` state changes at runtime ## [5.25.1] - 2025-09-27 ### Fixed - **Date Picker** - Fix issue where year range picker doesn't show the hovered range - Fix issue where quarter presets returns incorrect date - **FormatByte**: Add support for `unitSystem` property to allow changing between decimal (1000 bytes) and binary (1024 bytes) systems. - **Number Input**: When `formatOptions` is used (like `style: "currency"`), the cursor would jump to the end of the input when typing in the middle. The cursor now maintains its relative position during formatting changes. - **Pin Input**: Fix issue where using the keyboard shortcuts `Cmd+Backspace` and `Cmd+Delete` to delete text in pin inputs would insert "undefined" instead of clearing the field. - **Scroll Area**: Fix issue where resize tracking was not observing the root element, which caused the scrollbar to not update when the root element's size changed. ## [5.25.0] - 2025-09-16 ### Added - Added `mergeProps` utility for combining multiple props objects with proper event handler and className merging. - Added `createContext` utility for creating typed React contexts with improved DX. ```tsx import { createContext } from '@ark-ui/react/utils' ``` ### Fixed - **AngleSlider**: Export `angleSliderAnatomy` from the anatomy exports ## [5.24.1] - 2025-09-14 ### Fixed - **General**: Fix issue where `mergeProps` throws when `props` is `undefined` or `null` ## [5.24.0] - 2025-09-14 ### Added - **Combobox**: Add `alwaysSubmitOnEnter` prop to allow bypassing the default two-step behavior (Enter to close combobox, then Enter to submit form) and instead submit the form immediately on Enter press. This is useful for single-field autocomplete forms where Enter should submit the form directly. - **Dismissable**: Add support for layer types in dismissable layer stack. Layers can now be categorized as `dialog`, `popover`, `menu`, or `listbox`. This enables: - `data-nested` attribute on nested layers of the same type - `data-has-nested` attribute on parent layers with nested children of the same type - `--nested-layer-count` CSS variable indicating the number of nested layers of the same type ### Changed - **Hover Card**: Change default delay values for hover card to improve accessibility. - `openDelay`: from `700ms` to `600ms` - **Tooltip**: Change default delay values for tooltip to improve accessibility. [Learn more](https://www.nngroup.com/articles/timing-exposing-content) - `openDelay`: from `1000ms` to `400ms` - `closeDelay`: from `500ms` to `150ms` ### Removed - **TimePicker**: The TimePicker component has been removed from this release. This component was never part of the public API and was considered experimental. It had significant bugs and usability issues across all frameworks and locales, making it unsuitable for production use. **Migration**: We recommend building a custom time picker using the Select component for simple use cases, or implementing a time grid pattern for more complex scenarios. ### Fixed - **Editable**: Allow text selection in editable preview when `autoResize` is enabled Previously, when `autoResize` was set to `true`, the preview element had `userSelect: "none"` applied, preventing users from selecting text. This has been fixed by removing the `userSelect` style property. - **File Upload**: Fix regression where clicking the trigger doesn't open the file picker when used within the dropzone - **Menu**: - Fix issue where keyboard activation of menu items with `target="_blank"` would open two tabs - Fix issue where hovering a partially visible item with pointer causes it to scroll into view - **Tabs**: Fix issue where `ids` for `item` and `content` could not be customized - **Toast**: Allow creating a toast store without any arguments ## [5.23.0] - 2025-09-08 ### Added - **Field**: Add `data-required` attribute to `Field.Label` - **Select, Combobox, Listbox, TreeView**: Export `RootComponent` and `RootProviderComponent` types which are useful when building compositions that wrap the `Root` and `RootProvider` components and you still want type-safety for the collection. ### Fixed - **Menu**: Fix `Menu.ItemText` not working inside `Menu.TriggerItem` ```tsx import { Select } from '@ark-ui/react/select' import { styled } from 'styling-lib' const Root = styled(Select.Root) as Select.RootComponent<{}> ``` ## [5.22.0] - 2025-08-28 ### Added - **Combobox**: Add `ComboboxEmpty` component to display content when the combobox has no items - **Listbox**: Add `ListboxEmpty` component to display content when the listbox has no items - **Hover Card**: Add support for `disabled` prop ### Fixed - **Collection**: Fix issue where disabled items could be reached via typeahead - **Color Picker**: Fix issue where color picker was not working correctly in RTL mode - **Date Picker**: Fix issue where datepicker doesn't revert to a valid value when the input value exceeds the min/max and blurred - **Dismissable**: Expose `onRequestDismiss` custom event handler for event a parent layer requests the child layer to dismiss. If prevented via `event.preventDefault()`, the child layer will not dismiss when the parent layer is dismissed. - **Number Input** - Omit the input `pattern` when `formatOptions` is provided. This prevents native pattern validation from conflicting with formatted values (e.g., currency or percent). - Handle empty values consistently across all format options. - Add `data-scrubbing` attribute to the number input parts. - **Tags Input**: Fix issue where highlighted item doesn't clear when tabbing out of the input to an external button within the `control` part. - **Tooltip** - Set `closeOnPointerdown` to `false` when `closeOnClick` is set to `false` - Reduce bundle size by replacing `@zag-js/store` dependency with a lightweight store implementation. ## [5.21.0] - 2025-08-24 ### Added - **Hooks**: Add `useAsyncList` and `useCollator` hooks for managing asynchronous list operations and locale-aware string comparison - **Toast**: Export type definitions `ToastActionOptions`, `ToastPlacement`, `ToastPromiseOptions`, `ToastStatus`, `ToastStatusChangeDetails`, and `ToastType` ### Changed - **Fieldset** - Update Legend component to render as `div` instead of `legend` element for improved styling flexibility - Add `aria-labelledby` attribute to fieldset root for better accessibility by linking to legend ### Fixed - **Date Picker** - Clear hovered range state after completing range selection instead of waiting for pointer to leave the calendar area. - Fix issue where month and year select labels don't update correctly when using `min`/`max` constraints. - Expose `disabled` on `api.getMonths()` and `api.getYears()` results to indicate options out of range for current constraints. - **Listbox** - Fix issue where first enabled item should be highlighted by default when listbox receives focus and no item is currently highlighted. - Add `getElement` to `scrollToIndexFn` details - Track collection changes and clear `highlightedValue` if the item is no longer in the collection. - **Scroll Area** - Avoid detecting hover state from portalled descendants. - Add `data-dragging` attribute to scroll area parts. - **Select**: Add `getElement` to `scrollToIndexFn` details - **Combobox**: Add `getElement` to `scrollToIndexFn` details - **Tabs**: Fix inconsistent keyboard navigation where TabPanel intermittently receives focus before focusable elements ## [5.20.0] - 2025-08-20 ### Added - **Highlight Word**: Add `exactMatch` option that enables whole-word matching using regex word boundaries. ### Fixed - **Menu**: Fix context menu repositioning logic - **ScrollArea**: Add `data-hover` to scroll area ## [5.19.0] - 2025-08-18 ### Added - **ScrollArea [NEW]**: Add support for new scroll area component. ### Fixed - **ListCollection** - Avoid recomputing groups on every call to `at()` and `indexOf()` - Fixed bug in `find()` method (was checking `!= null` instead of `!== -1`) - **GridCollection**: Avoid recomputing rows on every call to `getRows()` - **Menu** - Add `data-state` attribute for context menu trigger - Fix context menu positioning bug where reopening at the same coordinates fails to reposition ## [5.18.4] - 2025-08-14 ### Fixed - **Listbox**: Add support for navigating grid collections - **Carousel**: - Fix an issue where the carousel would not update when `slideCount` or `autoplay` props change. - Fix an issue where `loop: false` was ignored when using autoplay. Now, the carousel will stop when it gets to the last slide. - **Date Picker**: Expose `data-inline` attribute on Content part to enable distinct styling for inline date pickers versus popover date pickers. - **Menu**: Fix issue where `onCheckedChange` could be called twice on checkbox or radio item - **Radio Group**: Fixed issue where arrow key navigation doesn't apply `data-focus-visible` on the newly focused item. - **TagsInput**: Export `InputValueChangeDetails` type ### Changed - **Async List**: Improve type inference for descriptors ## [5.18.3] - 2025-08-01 ### Fixed - **Factory**: Check if `children` is a valid React element before calling `Children.only()` - **Carousel**: Fix issue where controlled carousel ignores last slide ## [5.18.2] - 2025-07-26 ### Fixed - **Dialog** - Sync content `--layer-index` with positioner and backdrop - Decouple `trapFocus` from `modal` so it's possible to set `modal=false` and `trapFocus=true` ## [5.18.1] - 2025-07-23 ### Fixed - **Date Picker**: Fixed issue where hovered range was connect to selected values, when it shouldn't - **Tree View**: Fixed issue where tree view doesn't scroll into view when content overflows. ## [5.18.0] - 2025-07-22 ### Added - **Collection**: Add `useListSelection` hook for managing collection item selection with support for single/multiple selection modes ```jsx const collection = createListCollection({ items: ['React', 'Vue', 'Angular'] }) const selection = useListSelection({ collection }) // Check if item is selected const isSelected = selection.isSelected('React') // Select/deselect items selection.select('React') selection.toggle('Vue') ``` - **File Upload**: Add support for programmatically controlling the accepted files via `acceptedFiles` and `defaultAcceptedFiles` - **Signature Pad**: Add support for programmatically controlling the paths via `paths` and `defaultPaths` props. - **Date Picker**: Added hover range preview support for date picker range selection. Added `inHoveredRange`, `firstInHoveredRange`, and `lastInHoveredRange` properties to `DayTableCellState` with corresponding data attributes `data-in-hover-range`, `data-hover-range-start`, and `data-hover-range-end`. Hover range states are only active when not overlapping with actual selected range, enabling distinct styling for hover preview vs actual selection in range mode. ### Fixed - **Date Picker**: Fix date comparison issues when time components are involved. This resolves critical issues with date comparison operations when different date types (`CalendarDate`, `CalendarDateTime`, `ZonedDateTime`) are mixed, particularly in scenarios involving time components. ## [5.17.0] - 2025-07-18 ### Added - **Checkbox**: Add `CheckboxGroupProvider` component for external checkbox group state management ### Fixed - **Carousel**: Fix issue where full page carousel could trap scrolling - **ListCollection**:Export `UseListCollectionReturn` type - **TreeCollection**: Fix issue where the `filter` method completely deletes the children key from the node when there are no matching children - **Number Input**: Fix issue where default pattern does not allow negative numbers with decimal point - **File Upload** - Export `FileError`, `FileMimeType`, and `FileRejection` types - Fix issue where calling `api.setFiles` invokes validation with incorrect `acceptedFiles` - Fix issue where the browser might not be able to infer the mime type of a file due to limitations, drag source or security restrictions. As a fallback in the file validation logic, we now infer the mime type from the file extension. ## [5.16.1] - 2025-07-05 ### Fixed - **Combobox** - Expose `reason` to `onOpenChange` and `onInputValueChange` callbacks - Expose `api.clearHighlightedValue` function to clear highlighted value - **Date Picker** - Fix issue where datepicker errors when setting `selectionMode=range` and `minView=year` - Fix issue where `focusedValue` could not be fully controlled - **Toast**: Fix issue where toast `title` or `description` could not accept React element - **Listbox**: Select highlighted item only if it exists in the collection - **Progress**: Improve `valueAsString` formatting - **Select** - Select highlighted item only if it exists in the collection - Expose `api.clearHighlightedValue` function to clear highlighted value - **Tour**: Fix an issue where the `goto` function in `StepActionMap` doesn't work when passing step IDs (string) - **Tree View**: Expose `id` in the tree node state - **ClientOnly**: Support `children` as a function ## [5.16.0] - 2025-07-01 ### Added - **Color Picker**: Add support for `inline` prop to render color picker inline - **Date Picker**: Add support for `inline` prop to render the date calendar inline ### Fixed - **Color Picker**: Auto-prefix Hex values with `#` if missing when using the `hex` channel input - **Menu**: Fix interaction outside detection for focusable context trigger - **Tree View**: Improve support for rendering tree items as links ## [5.15.4] - 2025-06-27 ### Fixed - **Combobox, Select, Listbox**: Fix issue where rehydrating `defaultValue` or `value` after fetching items doesn't update the `valueAsString` ## [5.15.3] - 2025-06-27 ### Fixed - **Tree View**: Fix tree traversal for querying last node ## [5.15.2] - 2025-06-26 ### Fixed - **Date Picker**: Fix issue with keyboard selection where setting unavailable date causes month view to behave differently from clicking with mouse - **Toast**: Fix issue where app crashes when `toaster.promise` is called without loading option. The `loading` option is now required. A warning will be logged if it is not provided - **Tree View** - Fix issue where clicking a branch with indeterminate state doesn't check its child nodes - Remove `aria-busy` attribute from branch trigger when not loading children - Expose node details in `onExpandChange`, `onSelectionChange` and `onFocusChange` - **Angle Slider**: Fix issue where scrubbing doesn't feel smooth on touch devices - **Timer**: - Fix issue where timer could continue beyond `targetMs` when window is not visible - Add validation to ensure `startMs` and `targetMs` are configured correctly - Fix `progressPercent` calculation for countdown timers ## [5.15.1] - 2025-06-23 ### Fixed - **Listbox**: Fix issue where `Listbox.ItemContext` was not exported ## [5.15.0] - 2025-06-23 ### Added - **Tree View** - Add support for checkbox state for checkbox trees via `defaultCheckedValue`, `checkedValue`, `onCheckedChange` props - Add callback for when `loadChildren` fails via `onLoadChildrenError` prop ### Fixed - **Progress** - Fix issue where setting orientation to `vertical` don't work - Fix issue where setting `defaultValue` to `null` doesn't show indeterminate state ## [5.14.2] - 2025-06-19 ### Fixed - **General**: Ensure pointerdown or click event handlers only execute when the main button is clicked - **Tree View**: Exported `TreeViewNodeState` and `TreeViewNodeProps` types from `@zag-js/tree-view` ### Changed - **Collection**: Improve the APIs around `tree.flatten(...)` and `flattenedToTree` to ensure the original node properties are preserved. > Previously, `tree.flatten()` would return an array of objects with `value` and `label` stripping out the original > node properties. ```ts const tree = new TreeCollection({ rootNode: { value: 'ROOT', children: [{ value: 'child1' }, { value: 'child2' }], }, }) const flattened = tree.flatten() const reconstructed = flattenedToTree(flattened) console.log(reconstructed.rootNode) // { // value: "ROOT", // children: [{ value: "child1" }, { value: "child2" }], // } ``` ## [5.14.1] - 2025-06-17 ### Fixed - **Popover**: Fixed issue where `onOpenChange` could be called twice when controlled - **File Utils**: Improved `downloadFile` function to handle webview scenarios - **Combobox**: - Fixed issue where `onInputValueChange` could be called twice when selecting an item - Fixed issue where combobox with `allowCustomValue: true` used within in a form requires two enter keypress to submit ## [5.14.0] - 2025-06-10 ### Added - **Editable**: Added support for `activationMode=none` - **Collection** - Exposed `copy` method - Added support for `getParentNodes` to accept a value or index path ### Fixed - **Collection**: Fixed issue where entrypoint `@ark-ui/react/collection` was not working as expected - **Carousel**: Fixed issue where carousel crashes when `slidesPerPage` is 0 - **File Upload**: Prevented `undefined` in `acceptedFiles` when no files accepted - **Select**: Fixed issue where highlighted item could be cleared when navigating up/down the list with keyboard - **Tabs**: Fixed issue where tabs with links should not trigger tab change upon cmd/middle click - **Menu**: Fixed issue where `Menu.ItemText` could not be used with `Menu.Item` ## [5.13.0] - 2025-06-07 ### Added - **Collection**: Added new `useListCollection` hook to create a dynamic list collection. ### Fixed - **Progress**: Exported `ProgressValueChangeDetails` and `ProgressValueTranslationDetails` types from `@zag-js/progress` ## [5.12.0] - 2025-06-05 ### Added - **Tree View**: Added support for lazy loading node children. To use this, you need to provide: - `loadChildren` is a function that is used to load the children of a node. - `onLoadChildrenComplete` is a callback that is called when the children of a node are loaded. Used to update the tree collection. - Add `childrenCount` to the node object to indicate the number of children. ### Fixed - **Slider** - Fixed issue where `Shift` + `ArrowRight` set value to `0` instead of `max` when step is too large (e.g. `20`) - Fixed issue where `onValueChangeEnd` doesn't return the latest value when dragging very fast ## [5.11.0] - 2025-05-30 ### Added - **File Upload**: Added support for transforming uploaded files via `transformFiles` context property. ### Fixed - **Slider**: Fixed issue where `minStepsBetweenThumbs` isn't computed correctly when interacting with pointer or keyboard. ## [5.10.0] - 2025-05-29 ### Added - **[NEW] Password Input**: Added `PasswordInput` component for creating password inputs ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' export const Basic = () => ( Password }> ) ``` - **Select**: Added `onSelect` callback that gets fired when an item is selected via keyboard/mouse. ### Fixed - **Color Picker**: Fixed issue where value change end event is invoked when committing via an input. - **Toast**: Fixed issue where calling `toast.remove()` without an id shows a TypeScript error. - **Field**: Fixed issue where helper text and error text could not be detected in shadow DOM environments. ## [5.9.2] - 2025-05-24 ### Fixed - **Collection**: Export `CollectionOptions`, `TreeCollectionOptions`, `GridCollectionOptions` types. - **Carousel** - Fixed issue where focusing on carousel region and navigating with keyboard doesn't work as expected - Fixed issue when `allowMouseDrag` is set where carousel no longer snaps after mouse interaction - **Combobox**: Fixed issue where `onInputValueChange` doesn't get called when `autoFocus` is set to `true` - **Slider**: Fixed issue where slider could throw a error when rendered in an popover or dialog - **Tour**: Fixed issue where calling `api.start()` with a step id doesn't work as expected ## [5.9.1] - 2025-05-12 ### Fixed - **Combobox**: Fixed issue where `focusable` prop was not being applied to the trigger element. - **Collection**: Fixed issue where `getNextValue` and `getPreviousValue` doesn't work as expected when `groupBy` is used. ## [5.9.0] - 2025-05-05 ### Added - **Locale**: Added `useFilter` hook to filter data based on the current locale. - **Format**: Added `FormatRelativeTime` component for formatting relative time. ## [5.8.0] - 2025-05-01 ### Added - **Date Picker**: Added support for `outsideDaySelectable` prop to allow selecting days outside the current month (on the same visible date range) ### Fixed - **Collapsible**: Fixed issue in React.js <= v18.x where collapse animation might not work as expected ## [5.7.0] - 2025-04-25 ### Added - **[NEW] Listbox**: Introduced the `Listbox` component for selecting a single or multiple items from a list. See the [documentation](https://ark-ui.com/docs/components/listbox) for details. - Improved support for grouping collection items. Check the `Listbox`, `Select` or `Combobox` documentation for more details. ### Changed - Added `package.json` to `exports` for improved compatibility with tools like Vite. ## [5.6.0] - 2025-04-15 ### Added - **[NEW] AngleSlider**: Introduced the `AngleSlider` component for selecting an angle. See the [documentation](https://ark-ui.com/docs/components/angle-slider) for details. - **[NEW] FloatingPanel**: Introduced the `FloatingPanel` component for creating floating windows. See the [documentation](https://ark-ui.com/docs/components/floating-panel) for details. - **Toast**: Added toast queuing when the max limit is reached: - New toasts were queued instead of dropped - Queued toasts were shown when space became available - Queue cleared when all toasts were removed - **Combobox**: - Fallbacked to the trigger element as the positioning anchor - Added `data-empty` attribute to indicate an empty listbox or content ## [5.5.0] - 2025-04-05 ### Added - **Presence**: Added support for skipping the initial animation when the component is mounted. This can be used in all disclosure components (e.g., `Dialog`, `DatePicker`, `Menu` etc). ### Fixed - **Tabs**: Fixed issue where tabs indicator animation behaves inconsistently. - **Date Picker** - Fixed issue where datepicker throws error when navigating month view. - Fixed issue where range selection doesn't reset correctly when clicking the same start date. - **Disclosure Components** - Fixed issue where pointerdown outside doesn't work consistently on mobile devices. - Improved pointerdown outside click detection in shadow DOM environments. ## [5.4.0] - 2025-03-28 ### Added - **Slider** - Add support for `origin: end` to align the thumb to the end of the track. - Expose `thumbSize` as CSS variables in the root element. Can be useful for styling the slider. - **Menu** - Added `onSelect` event to the `Menu.Item` component. ### Fixed - Ensured each component's state machine starts before processing events. - **HoverCard, ColorPicker**: Added missing `tabIndex` for better dialog support. - **Menu**: Assigned unique IDs to menu items to improve accessibility and HTML validation. ## [5.3.1] - 2025-03-24 ### Fixed - Fixed an issue where a function was imported from a package that wasn't declared as a dependency. ## [5.3.0] - 2025-03-24 ### Added - **Collapsible**: Added an `Indicator` part to display whether the collapsible was open or closed. - **ColorPicker**: Added support for formatting the `ValueText` component. ```tsx // #ff0000 ``` ### Fixed - **Combobox**: Fixed an issue where `onOpenChange` was called with the same `open` value. - **DownloadTrigger**: Added the missing `use client` directive. - **Splitter**: Fixed an issue where `onResizeStart` and `onResizeEnd` callbacks weren't triggered during keyboard interactions. ## [5.2.0] - 2025-03-22 ### Added - **[NEW] DownloadTrigger**: Added Component for downloading a blob or file, whether retrieved synchronously or asynchronously. ```tsx import { DownloadTrigger } from '@ark-ui/react/download-trigger' export const DownloadImage = () => { async function fetchImage() { const response = await fetch('https://picsum.photos/200/300') return response.blob() } return ( Download Image ) } ``` ### Changed - **NumberInput**: Set the default step to `0.01` when `formatOptions.style` was set to `percent`. - **[Breaking] Splitter**: Redesigned splitter machine to support more use cases and improve DX. Check out the [Splitter](https://ark-ui.com/docs/components/splitter) documentation for more details. ### Fixed - **Toast**: Fixed issue where setting `offsets` to `undefined` caused the machine to throw. - **Select**: Fixed issue where select `valueAsString` lost reactivity. ## [5.1.0] - 2025-03-17 ### Added - Added support for a cleanup function in `ref`. ### Fixed - **Field**: Exported the missing `useField` hook. - **NumberInput**: `onValueChange` correctly received `valueAsNumber`. - **Slider**: Thumbs initialized correctly when `min` was set to a non-zero value. ## [5.0.1] - 2025-03-11 ### Fixed - Effects now flush synchronously instead of using a microtask. - **Checkbox**: `data-invalid` is no longer set when `invalid` is `false`. - **Combobox**: Fixed unexpected cursor movement when editing input. - **PinInput**: OTP SMS autofill now works as expected. - **RatingGroup**: Fixed incorrect focus placement on the label. - **TagsInput**: Improved caret detection to prevent unintended tag removal. - **Timer** - Fixed slowdown when switching tabs/windows. - Changed default `interval` from `250` to `1000`. ## [5.0.0] - 2025-03-06 Ark UI just got a major performance boost! 🚀 ### What’s new in v5? - **Blazing-fast performance** – Every component runs smoother and renders faster. - **Smaller bundle size** – Leaner components and adapters for a more efficient build. We made this happen by using React’s native reactive primitives instead of external stores. In our stress tests with **10,000 components**, Ark v5 delivered **1.5x–4x** better performance across the board. ![Performance comparison showing Ark v5 is 1.5x-4x faster than other libraries](./v5.svg) ### A quick note on tests Most component updates are non-breaking, but due to this change, some tests may need adjustments. For example: ```jsx // Before it('should open by default', () => { render() expect(screen.getByRole('dialog')).toBeInTheDocument() }) // After it('should open by default', async () => { render() expect(await screen.findByRole('dialog')).toBeInTheDocument() }) ``` #### Added - **Carousel**: ⚠️ Breaking change: Added required prop `slideCount` to `Carousel.Root` component. - **Clipboard**: Added `onValueChange` and `defaultValue` props. - **ColorPicker**: Added `defaultFormat` prop. - **Combobox**: Added `defaultHighlightedValue` and `defaultInputValue` props. - **DatePicker**: Added `defaultFocusedValue` prop, `getViewProps`, and `visibleRangeText`. - **HoverCard**: Expanded interaction handlers. - **Menu**: Added `defaultHighlightedValue` prop. - **Pagination**: Added `defaultPageSize` prop. - **PinInput**: Added `count` prop for better SSR aria-label. - **Progress**: Added `locale` and `formatOptions` props. - **QrCode**: Added `pixelSize` prop. - **Select**: Added `defaultHighlightedValue` prop. - **TagsInput**: Added `defaultInputValue` prop. - **Toggle**: Reintroduced toggle machine. #### Fixed - **Accordion**: Fixed issue in Safari where clicking triggers didn't show content. - **Avatar**: Fixed `api.setSrc` not working. - **Carousel**: Fixed pagination sync and initial page issues. - **File Upload**: Fixed drag-and-drop when `directory: true`. - **Menu**: Fixed context menu positioning not updating on right-click. - **Number Input**: Fixed `value` prop not being consumed. - **Pin Input**: Fixed focus warnings and editing issues. - **Progress**: Allowed more precise (decimal) values. - **Radio Group, Switch**: Improved focus behavior in Safari. - **Select**: Fixed regression where `multiple: true` didn't work. - **Steps**: Ensured ARIA attributes use valid values and wrapped `
  • ` elements correctly within `
      ` or `
        `. - **Textarea**: Fixed `ResizeObserver` warning. - **Timer**: Fixed stopping issue when switching tabs; resolved issue where `action` prop was passed to `ActionTrigger`. - **Toast**: Fixed keyboard navigation skipping close button. - **Toggle Group**: Fixed `data-focus` not being removed on blur. --- # Changelog (VUE) ## [Unreleased] ### Added - **Date Picker**: Added `ValueText` component for displaying selected date value(s) with placeholder support and render prop for custom formatting - **Scroll Area**: Added overflow CSS variables (`--scroll-area-overflow-{x,y}-{start,end}`) for scroll fade effects - **Slider**: Added `thumbCollisionBehavior` prop (`none`, `push`, `swap`) - **Steps**: Added `isStepValid`, `isStepSkippable`, and `onStepInvalid` for validation support - **Tags Input**: Added `placeholder` prop (shown only when no tags exist) - **Tooltip**: Added `data-instant` attribute for instant animations ### Fixed - **Auto Resize**: Fixed change event not emitted after clearing controlled textarea - **Date Picker**: Fixed `visibleRangeText` to show correct format based on current view (year/month/day) - **Dismissable**: Fixed issue where closing a nested dialog/popover would incorrectly close its parent layers - **Menu**: Fixed glitchy submenu behavior when hovering between trigger items quickly - **Checkbox**: Fixed individual checkbox props being overridden by `CheckboxGroup` - **Collection, Tree View**: Fixed initial focus when first node/branch is disabled - **Color Picker**: Fixed color not updating when selecting black shades in controlled mode - **Floating Panel**: Fixed double-click on minimized title bar incorrectly maximizing - **Image Cropper**: Fixed `reset()` destroying cropper, prop changes not updating instantly, and panning bounds - **Number Input**: Fixed cursor positioning after clicking label or scrubbing - **Pagination**: Fixed next trigger not disabled when `count` is `0` - **Slider**: Fixed thumb drag from edge in `thumbAlignment="contain"` mode - **Switch**: Fixed `api.toggleChecked()` not working - **Toast**: Fixed toasts created before state machine connects not showing - **Tour**: Fixed janky scroll between steps ## [5.30.0] - 2025-12-10 ### Added - **Date Picker**: Added `required` and `invalid` props - **Number Input**: Added `onValueCommit` callback that fires when the input loses focus or Enter is pressed - **Pagination**: - Added `FirstTrigger` and `LastTrigger` components for navigating to first/last page - Added `boundaryCount` parameter for controlling boundary pages (start/end) - Implemented balanced pagination algorithm for consistent UI with max 7 elements - **Radio Group**: Added `invalid` and `required` props with corresponding `data-*` and `aria-*` attributes - **Tree View**: Added `scrollToIndexFn` prop to enable keyboard navigation in virtualized trees ### Fixed - **Accordion, Menu**: Fixed issue where querying elements by `aria-controls` attribute could fail when lazy mounting the content - **Color Picker**: Added `role="dialog"` to content and `aria-haspopup="dialog"` to trigger when not inline for better accessibility - **Date Picker**: Fixed issue where date picker input does not update format when locale changes - **Floating Panel**: - Fixed `dir` prop now properly delegated to all panel parts - Fixed double-click behavior improvements and to check `event.defaultPrevented` for custom behavior - **Listbox**: - Fixed issue in React where filtering items with an input would throw a `flushSync was called from inside a lifecycle method` warning - Fixed issue where `data-highlighted` wasn't applied to the first item when using `autoHighlight` with input filtering - **Number Input**: - Fixed improved controlled usage sync - Fixed issue where input element doesn't sync when `formatOptions` changes dynamically - Ensured cursor position is preserved when `Enter` key is pressed and formatting is triggered - Fixed cursor jumping to start when value is changed externally via props while user is typing - **Pagination**: Fixed ellipsis showing when only 1 page gap - **Rating Group**: Fixed issue where rating group becomes unfocusable via keyboard when value is 0 - **Tooltip**: Fixed tooltip not showing when scrolling with pointer over trigger ### Changed - **Tree View**: `getVisibleNodes()` now returns `{ node, indexPath }[]` instead of `node[]` ## [5.29.1] - 2025-11-22 ### Fixed - **Fieldset**: Fixed `aria-describedby` resolution to correctly reference helper text and error text IDs - **Floating Panel**: - Fixed resize trigger issue with `n` axis by explicitly setting `top: 0` - Fixed `draggable` and `resizable` options not being respected when set to `false` - **Presence**: Fixed regression where UNMOUNT transition might not be called consistently ## [5.29.0] - 2025-11-20 ### Added - **Carousel, Color Picker, Combobox, Date Picker, Select**: Added `value` to `OpenChangeDetails` for better context when handling open state changes - **Carousel**: Added support for `autoSize` prop to allow variable width/height slide items - **Splitter**: - Added `Splitter.ResizeTriggerIndicator` to render an indicator when resizing - Exported `getLayout` and `getSplitterLayout` functions for calculating splitter panel layouts - **Toast**: Exposed viewport offset as CSS variables on the toast group element ### Fixed - **Carousel**: - Fixed dragging behavior that stops working after switching browser tabs or scrolling the page - Fixed dragging not working after scrolling with mouse wheel when `allowMouseDrag` is enabled - **Combobox**: Fixed `onHighlightChange` not being invoked when collection is filtered to empty - **Date Picker**: Fixed issue where the range date picker crashes when typing the end date first and blurring the input field multiple times - **File Upload**: Fixed issue where clicking on non-interactive children inside the dropzone doesn't open the file picker - **Presence**: Fixed a bug where elements get stuck in unmountSuspended state during rapid state updates - **Radio Group**: - Fixed inconsistent application of `data-focus-visible` and `data-focus` attributes - **Splitter**: Fixed disabled splitter showing resize cursor and allowing dragging - **Tabs**: - Fixed tabs indicator position not updating when inactive tabs change size - **Tags Input**: Fixed issue where item delete trigger doesn't have `data-*` attached ## [5.28.0] - 2025-11-14 ### Added - **General**: Exported `InteractOutsideEvent`, `FocusOutsideEvent`, and `PointerDownOutsideEvent` types for better type safety - **Carousel**: - Added `Carousel.AutoplayIndicator` component for conditionally rendering content based on autoplay state - Added `Carousel.ProgressText` component for displaying current page progress (e.g., "1 / 5") - **Toast**: Exported `ToastOptions` and `ToastStoreProps` types for better type safety ### Changed - **useListCollection**: Updated `initialItems` to accept `readonly` arrays for better compatibility with immutable data patterns. ### Fixed - **Combobox**: - Fixed focus stealing in controlled open mode - Removed problematic `aria-hidden` behavior to allow interaction with other page elements ## [5.27.1] - 2025-11-02 ### Fixed - **Dialog, Popover**: Improved shadow DOM support for interact outside and focus trap detection - **Marquee**: Fixed Firefox flicker and added GPU acceleration - **Dialog**: Fixed layout shift issue when using `scrollbar-gutter: stable` in CSS - **Slider**: Fixed `onValueChangeEnd` callback not triggering for programmatic value changes ## [5.27.0] - 2025-11-01 ### Added - **Marquee** [New]: Initial release of marquee component for continuously scrolling content ### Fixed - **Angle Slider**: Resolved an issue where dragging the thumb from non-center positions caused unexpected value jumps. The thumb now maintains consistent positioning relative to the initial click point. - **Slider**: Fixed a problem where the thumb offset shifted dynamically during dragging, resulting in value jumps. The offset now remains constant from the pointer throughout the drag operation. - **Date Picker**: Resolved a crash in the range date picker occurring when users typed the end date first by implementing `null`/`undefined` checks for date property access. - **Radio Group**: Reverted to `offsetLeft`/`offsetTop` calculations to restore correct indicator positioning within scrollable container contexts. - **Tabs**: Reverted to `offsetLeft`/`offsetTop` calculations to fix indicator positioning issues in scrollable containers. - **Tour**: - Corrected improper effect cleanup procedures - Fixed wait step functionality - Added step validation on mount to verify configuration validity ## [5.26.2] - 2025-10-18 ### Fixed - **Angle Slider**: Fix accessibility violation where the slider thumb element lacked an accessible name. The thumb now supports `aria-label` and `aria-labelledby` props, and automatically falls back to the label element's ID for proper ARIA labeling. - **Select**: Fix accessibility violation where the required state was not set correctly to on the trigger. - **Tags Input**: Fix issue where entering a custom tag with combobox integration required pressing `Enter` twice. The tags-input now correctly handles custom values when the combobox has no highlighted item (`aria-activedescendant` is empty), allowing the tag to be added on the first `Enter` press. ## [5.26.1] - 2025-10-15 ### Fixed - **Checkbox** - Fix issue where setting initial checked state to `indeterminate` doesn't work - Ensure `api.checkedState` returns the correct checked state (`boolean | "indeterminate"`) - **Collapsible**: Fix issue where `dir` prop value was hardcoded to `ltr` instead of using the provided value - **Combobox**: Fix issue where controlled single-select combobox does not propagate its initial value to `inputValue` - **Listbox**: Fix issue where pressing Enter key when no highlighted item still calls `event.preventDefault()` - **Radio Group**: Refactor to use `getBoundingClientRect()` for precise indicator positioning - **Slider** - Fix issue where slider could stop abruptly when scrubbing thumb - Fix issue where range slider thumbs become stuck when dragged to the same position without `minStepsBetweenThumbs` - **Tabs**: Refactor to use `getBoundingClientRect()` for precise indicator positioning - **Tags Input**: Fix issue where `maxLength` doesn't apply to the edit input as well ## [5.26.0] - 2025-10-08 ### Added - **Collapsible**: Add support for `collapsedHeight` and `collapsedWidth` props to control the dimensions of the collapsible content when in its collapsed state. - **Focus Trap**: Allow elements referenced by `aria-controls` to be included in the trap scope. This makes it possible for menus, popovers, etc. to be portalled and work correctly. - **Pagination**: Add `getPageUrl` prop for generating `href` attributes when using pagination as links. ```ts const service = useMachine(pagination.machine, { type: 'link', getPageUrl: ({ page, pageSize }) => `/products?page=${page}&size=${pageSize}`, }) ``` - **Select**: Add `SelectRootComponentProps` type export for better component type composition. - **Listbox**: Add `ListboxRootComponentProps` type export for better component type composition. - **Combobox**: Add `ComboboxRootComponentProps` type export for better component type composition. - **TreeView**: - Add `TreeViewRootComponentProps` type export for better component type composition. - (Experimental) Add support for node renaming functionality: - Add `TreeViewNodeRenameInput` component for inline node label editing - Add `canRename` prop to control which nodes can be renamed - Add `onRenameStart`, `onBeforeRename`, and `onRenameComplete` callbacks for rename lifecycle - Add `CheckedChangeDetails`, `LoadChildrenErrorDetails`, `RenameStartDetails`, and `RenameCompleteDetails` type exports ### Fixed - **Scroll Area**: Fix RTL horizontal scrollbar positioning on Safari - **Slider**: Fix issue where slider continues dragging when disabled during drag operation. - **Switch**: Fix issue where `data-active` is inconsistently applied when `disabled` state changes at runtime ## [5.25.1] - 2025-09-27 ### Fixed - **Date Picker** - Fix issue where year range picker doesn't show the hovered range - Fix issue where quarter presets returns incorrect date - **FormatByte**: Add support for `unitSystem` property to allow changing between decimal (1000 bytes) and binary (1024 bytes) systems. - **Number Input**: When `formatOptions` is used (like `style: "currency"`), the cursor would jump to the end of the input when typing in the middle. The cursor now maintains its relative position during formatting changes. - **Pin Input**: Fix issue where using the keyboard shortcuts `Cmd+Backspace` and `Cmd+Delete` to delete text in pin inputs would insert "undefined" instead of clearing the field. - **Scroll Area**: Fix issue where resize tracking was not observing the root element, which caused the scrollbar to not update when the root element's size changed. ## [5.25.0] - 2025-09-16 ### Added - Added `mergeProps` utility for combining multiple props objects with proper event handler and className merging. - Added `createContext` utility for creating typed React contexts with improved DX. ```tsx import { createContext } from '@ark-ui/react/utils' ``` ### Fixed - **AngleSlider**: Export `angleSliderAnatomy` from the anatomy exports ## [5.24.1] - 2025-09-14 ### Fixed - **General**: Fix issue where `mergeProps` throws when `props` is `undefined` or `null` ## [5.24.0] - 2025-09-14 ### Added - **Combobox**: Add `alwaysSubmitOnEnter` prop to allow bypassing the default two-step behavior (Enter to close combobox, then Enter to submit form) and instead submit the form immediately on Enter press. This is useful for single-field autocomplete forms where Enter should submit the form directly. - **Dismissable**: Add support for layer types in dismissable layer stack. Layers can now be categorized as `dialog`, `popover`, `menu`, or `listbox`. This enables: - `data-nested` attribute on nested layers of the same type - `data-has-nested` attribute on parent layers with nested children of the same type - `--nested-layer-count` CSS variable indicating the number of nested layers of the same type ### Changed - **Hover Card**: Change default delay values for hover card to improve accessibility. - `openDelay`: from `700ms` to `600ms` - **Tooltip**: Change default delay values for tooltip to improve accessibility. [Learn more](https://www.nngroup.com/articles/timing-exposing-content) - `openDelay`: from `1000ms` to `400ms` - `closeDelay`: from `500ms` to `150ms` ### Removed - **TimePicker**: The TimePicker component has been removed from this release. This component was never part of the public API and was considered experimental. It had significant bugs and usability issues across all frameworks and locales, making it unsuitable for production use. **Migration**: We recommend building a custom time picker using the Select component for simple use cases, or implementing a time grid pattern for more complex scenarios. ### Fixed - **Editable**: Allow text selection in editable preview when `autoResize` is enabled Previously, when `autoResize` was set to `true`, the preview element had `userSelect: "none"` applied, preventing users from selecting text. This has been fixed by removing the `userSelect` style property. - **File Upload**: Fix regression where clicking the trigger doesn't open the file picker when used within the dropzone - **Menu**: - Fix issue where keyboard activation of menu items with `target="_blank"` would open two tabs - Fix issue where hovering a partially visible item with pointer causes it to scroll into view - **Tabs**: Fix issue where `ids` for `item` and `content` could not be customized - **Toast**: Allow creating a toast store without any arguments ## [5.23.0] - 2025-09-08 ### Added - **Field**: Add `data-required` attribute to `Field.Label` - **Select, Combobox, Listbox, TreeView**: Export `RootComponent` and `RootProviderComponent` types which are useful when building compositions that wrap the `Root` and `RootProvider` components and you still want type-safety for the collection. ### Fixed - **Menu**: Fix `Menu.ItemText` not working inside `Menu.TriggerItem` ```tsx import { Select } from '@ark-ui/react/select' import { styled } from 'styling-lib' const Root = styled(Select.Root) as Select.RootComponent<{}> ``` ## [5.22.0] - 2025-08-28 ### Added - **Combobox**: Add `ComboboxEmpty` component to display content when the combobox has no items - **Listbox**: Add `ListboxEmpty` component to display content when the listbox has no items - **Hover Card**: Add support for `disabled` prop ### Fixed - **Collection**: Fix issue where disabled items could be reached via typeahead - **Color Picker**: Fix issue where color picker was not working correctly in RTL mode - **Date Picker**: Fix issue where datepicker doesn't revert to a valid value when the input value exceeds the min/max and blurred - **Dismissable**: Expose `onRequestDismiss` custom event handler for event a parent layer requests the child layer to dismiss. If prevented via `event.preventDefault()`, the child layer will not dismiss when the parent layer is dismissed. - **Number Input** - Omit the input `pattern` when `formatOptions` is provided. This prevents native pattern validation from conflicting with formatted values (e.g., currency or percent). - Handle empty values consistently across all format options. - Add `data-scrubbing` attribute to the number input parts. - **Tags Input**: Fix issue where highlighted item doesn't clear when tabbing out of the input to an external button within the `control` part. - **Tooltip** - Set `closeOnPointerdown` to `false` when `closeOnClick` is set to `false` - Reduce bundle size by replacing `@zag-js/store` dependency with a lightweight store implementation. ## [5.21.0] - 2025-08-24 ### Added - **Hooks**: Add `useAsyncList` and `useCollator` hooks for managing asynchronous list operations and locale-aware string comparison - **Toast**: Export type definitions `ToastActionOptions`, `ToastPlacement`, `ToastPromiseOptions`, `ToastStatus`, `ToastStatusChangeDetails`, and `ToastType` ### Changed - **Fieldset** - Update Legend component to render as `div` instead of `legend` element for improved styling flexibility - Add `aria-labelledby` attribute to fieldset root for better accessibility by linking to legend ### Fixed - **Date Picker** - Clear hovered range state after completing range selection instead of waiting for pointer to leave the calendar area. - Fix issue where month and year select labels don't update correctly when using `min`/`max` constraints. - Expose `disabled` on `api.getMonths()` and `api.getYears()` results to indicate options out of range for current constraints. - **Listbox** - Fix issue where first enabled item should be highlighted by default when listbox receives focus and no item is currently highlighted. - Add `getElement` to `scrollToIndexFn` details - Track collection changes and clear `highlightedValue` if the item is no longer in the collection. - **Scroll Area** - Avoid detecting hover state from portalled descendants. - Add `data-dragging` attribute to scroll area parts. - **Select**: Add `getElement` to `scrollToIndexFn` details - **Combobox**: Add `getElement` to `scrollToIndexFn` details - **Tabs**: Fix inconsistent keyboard navigation where TabPanel intermittently receives focus before focusable elements ## [5.20.0] - 2025-08-20 ### Added - **Highlight Word**: Add `exactMatch` option that enables whole-word matching using regex word boundaries. ### Fixed - **Menu**: Fix context menu repositioning logic - **ScrollArea**: Add `data-hover` to scroll area ## [5.19.0] - 2025-08-18 ### Added - **ScrollArea [NEW]**: Add support for new scroll area component. ### Fixed - **ListCollection** - Avoid recomputing groups on every call to `at()` and `indexOf()` - Fixed bug in `find()` method (was checking `!= null` instead of `!== -1`) - **GridCollection**: Avoid recomputing rows on every call to `getRows()` - **Menu** - Add `data-state` attribute for context menu trigger - Fix context menu positioning bug where reopening at the same coordinates fails to reposition ## [5.18.4] - 2025-08-14 ### Fixed - **Listbox**: Add support for navigating grid collections - **Carousel**: - Fix an issue where the carousel would not update when `slideCount` or `autoplay` props change. - Fix an issue where `loop: false` was ignored when using autoplay. Now, the carousel will stop when it gets to the last slide. - **Date Picker**: Expose `data-inline` attribute on Content part to enable distinct styling for inline date pickers versus popover date pickers. - **Menu**: Fix issue where `onCheckedChange` could be called twice on checkbox or radio item - **Radio Group**: Fixed issue where arrow key navigation doesn't apply `data-focus-visible` on the newly focused item. - **TagsInput**: Export `InputValueChangeDetails` type ### Changed - **Async List**: Improve type inference for descriptors ## [5.18.3] - 2025-08-01 ### Fixed - **Factory**: Check if `children` is a valid React element before calling `Children.only()` - **Carousel**: Fix issue where controlled carousel ignores last slide ## [5.18.2] - 2025-07-26 ### Fixed - **Dialog** - Sync content `--layer-index` with positioner and backdrop - Decouple `trapFocus` from `modal` so it's possible to set `modal=false` and `trapFocus=true` ## [5.18.1] - 2025-07-23 ### Fixed - **Date Picker**: Fixed issue where hovered range was connect to selected values, when it shouldn't - **Tree View**: Fixed issue where tree view doesn't scroll into view when content overflows. ## [5.18.0] - 2025-07-22 ### Added - **Collection**: Add `useListSelection` hook for managing collection item selection with support for single/multiple selection modes ```jsx const collection = createListCollection({ items: ['React', 'Vue', 'Angular'] }) const selection = useListSelection({ collection }) // Check if item is selected const isSelected = selection.isSelected('React') // Select/deselect items selection.select('React') selection.toggle('Vue') ``` - **File Upload**: Add support for programmatically controlling the accepted files via `acceptedFiles` and `defaultAcceptedFiles` - **Signature Pad**: Add support for programmatically controlling the paths via `paths` and `defaultPaths` props. - **Date Picker**: Added hover range preview support for date picker range selection. Added `inHoveredRange`, `firstInHoveredRange`, and `lastInHoveredRange` properties to `DayTableCellState` with corresponding data attributes `data-in-hover-range`, `data-hover-range-start`, and `data-hover-range-end`. Hover range states are only active when not overlapping with actual selected range, enabling distinct styling for hover preview vs actual selection in range mode. ### Fixed - **Date Picker**: Fix date comparison issues when time components are involved. This resolves critical issues with date comparison operations when different date types (`CalendarDate`, `CalendarDateTime`, `ZonedDateTime`) are mixed, particularly in scenarios involving time components. ## [5.17.0] - 2025-07-18 ### Added - **Checkbox**: Add `CheckboxGroupProvider` component for external checkbox group state management ### Fixed - **Carousel**: Fix issue where full page carousel could trap scrolling - **ListCollection**:Export `UseListCollectionReturn` type - **TreeCollection**: Fix issue where the `filter` method completely deletes the children key from the node when there are no matching children - **Number Input**: Fix issue where default pattern does not allow negative numbers with decimal point - **File Upload** - Export `FileError`, `FileMimeType`, and `FileRejection` types - Fix issue where calling `api.setFiles` invokes validation with incorrect `acceptedFiles` - Fix issue where the browser might not be able to infer the mime type of a file due to limitations, drag source or security restrictions. As a fallback in the file validation logic, we now infer the mime type from the file extension. ## [5.16.1] - 2025-07-05 ### Fixed - **Combobox** - Expose `reason` to `onOpenChange` and `onInputValueChange` callbacks - Expose `api.clearHighlightedValue` function to clear highlighted value - **Date Picker** - Fix issue where datepicker errors when setting `selectionMode=range` and `minView=year` - Fix issue where `focusedValue` could not be fully controlled - **Toast**: Fix issue where toast `title` or `description` could not accept React element - **Listbox**: Select highlighted item only if it exists in the collection - **Progress**: Improve `valueAsString` formatting - **Select** - Select highlighted item only if it exists in the collection - Expose `api.clearHighlightedValue` function to clear highlighted value - **Tour**: Fix an issue where the `goto` function in `StepActionMap` doesn't work when passing step IDs (string) - **Tree View**: Expose `id` in the tree node state - **ClientOnly**: Support `children` as a function ## [5.16.0] - 2025-07-01 ### Added - **Color Picker**: Add support for `inline` prop to render color picker inline - **Date Picker**: Add support for `inline` prop to render the date calendar inline ### Fixed - **Color Picker**: Auto-prefix Hex values with `#` if missing when using the `hex` channel input - **Menu**: Fix interaction outside detection for focusable context trigger - **Tree View**: Improve support for rendering tree items as links ## [5.15.4] - 2025-06-27 ### Fixed - **Combobox, Select, Listbox**: Fix issue where rehydrating `defaultValue` or `value` after fetching items doesn't update the `valueAsString` ## [5.15.3] - 2025-06-27 ### Fixed - **Tree View**: Fix tree traversal for querying last node ## [5.15.2] - 2025-06-26 ### Fixed - **Date Picker**: Fix issue with keyboard selection where setting unavailable date causes month view to behave differently from clicking with mouse - **Toast**: Fix issue where app crashes when `toaster.promise` is called without loading option. The `loading` option is now required. A warning will be logged if it is not provided - **Tree View** - Fix issue where clicking a branch with indeterminate state doesn't check its child nodes - Remove `aria-busy` attribute from branch trigger when not loading children - Expose node details in `onExpandChange`, `onSelectionChange` and `onFocusChange` - **Angle Slider**: Fix issue where scrubbing doesn't feel smooth on touch devices - **Timer**: - Fix issue where timer could continue beyond `targetMs` when window is not visible - Add validation to ensure `startMs` and `targetMs` are configured correctly - Fix `progressPercent` calculation for countdown timers ## [5.15.1] - 2025-06-23 ### Fixed - **Listbox**: Fix issue where `Listbox.ItemContext` was not exported ## [5.15.0] - 2025-06-23 ### Added - **Tree View** - Add support for checkbox state for checkbox trees via `defaultCheckedValue`, `checkedValue`, `onCheckedChange` props - Add callback for when `loadChildren` fails via `onLoadChildrenError` prop ### Fixed - **Progress** - Fix issue where setting orientation to `vertical` don't work - Fix issue where setting `defaultValue` to `null` doesn't show indeterminate state ## [5.14.2] - 2025-06-19 ### Fixed - **General**: Ensure pointerdown or click event handlers only execute when the main button is clicked - **Tree View**: Exported `TreeViewNodeState` and `TreeViewNodeProps` types from `@zag-js/tree-view` ### Changed - **Collection**: Improve the APIs around `tree.flatten(...)` and `flattenedToTree` to ensure the original node properties are preserved. > Previously, `tree.flatten()` would return an array of objects with `value` and `label` stripping out the original > node properties. ```ts const tree = new TreeCollection({ rootNode: { value: 'ROOT', children: [{ value: 'child1' }, { value: 'child2' }], }, }) const flattened = tree.flatten() const reconstructed = flattenedToTree(flattened) console.log(reconstructed.rootNode) // { // value: "ROOT", // children: [{ value: "child1" }, { value: "child2" }], // } ``` ## [5.14.1] - 2025-06-17 ### Fixed - **Popover**: Fixed issue where `onOpenChange` could be called twice when controlled - **File Utils**: Improved `downloadFile` function to handle webview scenarios - **Combobox**: - Fixed issue where `onInputValueChange` could be called twice when selecting an item - Fixed issue where combobox with `allowCustomValue: true` used within in a form requires two enter keypress to submit ## [5.14.0] - 2025-06-10 ### Added - **Editable**: Added support for `activationMode=none` - **Collection** - Exposed `copy` method - Added support for `getParentNodes` to accept a value or index path ### Fixed - **Collection**: Fixed issue where entrypoint `@ark-ui/react/collection` was not working as expected - **Carousel**: Fixed issue where carousel crashes when `slidesPerPage` is 0 - **File Upload**: Prevented `undefined` in `acceptedFiles` when no files accepted - **Select**: Fixed issue where highlighted item could be cleared when navigating up/down the list with keyboard - **Tabs**: Fixed issue where tabs with links should not trigger tab change upon cmd/middle click - **Menu**: Fixed issue where `Menu.ItemText` could not be used with `Menu.Item` ## [5.13.0] - 2025-06-07 ### Added - **Collection**: Added new `useListCollection` hook to create a dynamic list collection. ### Fixed - **Progress**: Exported `ProgressValueChangeDetails` and `ProgressValueTranslationDetails` types from `@zag-js/progress` ## [5.12.0] - 2025-06-05 ### Added - **Tree View**: Added support for lazy loading node children. To use this, you need to provide: - `loadChildren` is a function that is used to load the children of a node. - `onLoadChildrenComplete` is a callback that is called when the children of a node are loaded. Used to update the tree collection. - Add `childrenCount` to the node object to indicate the number of children. ### Fixed - **Slider** - Fixed issue where `Shift` + `ArrowRight` set value to `0` instead of `max` when step is too large (e.g. `20`) - Fixed issue where `onValueChangeEnd` doesn't return the latest value when dragging very fast ## [5.11.0] - 2025-05-30 ### Added - **File Upload**: Added support for transforming uploaded files via `transformFiles` context property. ### Fixed - **Slider**: Fixed issue where `minStepsBetweenThumbs` isn't computed correctly when interacting with pointer or keyboard. ## [5.10.0] - 2025-05-29 ### Added - **[NEW] Password Input**: Added `PasswordInput` component for creating password inputs ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' export const Basic = () => ( Password }> ) ``` - **Select**: Added `onSelect` callback that gets fired when an item is selected via keyboard/mouse. ### Fixed - **Color Picker**: Fixed issue where value change end event is invoked when committing via an input. - **Toast**: Fixed issue where calling `toast.remove()` without an id shows a TypeScript error. - **Field**: Fixed issue where helper text and error text could not be detected in shadow DOM environments. ## [5.9.2] - 2025-05-24 ### Fixed - **Collection**: Export `CollectionOptions`, `TreeCollectionOptions`, `GridCollectionOptions` types. - **Carousel** - Fixed issue where focusing on carousel region and navigating with keyboard doesn't work as expected - Fixed issue when `allowMouseDrag` is set where carousel no longer snaps after mouse interaction - **Combobox**: Fixed issue where `onInputValueChange` doesn't get called when `autoFocus` is set to `true` - **Slider**: Fixed issue where slider could throw a error when rendered in an popover or dialog - **Tour**: Fixed issue where calling `api.start()` with a step id doesn't work as expected ## [5.9.1] - 2025-05-12 ### Fixed - **Combobox**: Fixed issue where `focusable` prop was not being applied to the trigger element. - **Collection**: Fixed issue where `getNextValue` and `getPreviousValue` doesn't work as expected when `groupBy` is used. ## [5.9.0] - 2025-05-05 ### Added - **Locale**: Added `useFilter` hook to filter data based on the current locale. - **Format**: Added `FormatRelativeTime` component for formatting relative time. ## [5.8.0] - 2025-05-01 ### Added - **Date Picker**: Added support for `outsideDaySelectable` prop to allow selecting days outside the current month (on the same visible date range) ### Fixed - **Collapsible**: Fixed issue in React.js <= v18.x where collapse animation might not work as expected ## [5.7.0] - 2025-04-25 ### Added - **[NEW] Listbox**: Introduced the `Listbox` component for selecting a single or multiple items from a list. See the [documentation](https://ark-ui.com/docs/components/listbox) for details. - Improved support for grouping collection items. Check the `Listbox`, `Select` or `Combobox` documentation for more details. ### Changed - Added `package.json` to `exports` for improved compatibility with tools like Vite. ## [5.6.0] - 2025-04-15 ### Added - **[NEW] AngleSlider**: Introduced the `AngleSlider` component for selecting an angle. See the [documentation](https://ark-ui.com/docs/components/angle-slider) for details. - **[NEW] FloatingPanel**: Introduced the `FloatingPanel` component for creating floating windows. See the [documentation](https://ark-ui.com/docs/components/floating-panel) for details. - **Toast**: Added toast queuing when the max limit is reached: - New toasts were queued instead of dropped - Queued toasts were shown when space became available - Queue cleared when all toasts were removed - **Combobox**: - Fallbacked to the trigger element as the positioning anchor - Added `data-empty` attribute to indicate an empty listbox or content ## [5.5.0] - 2025-04-05 ### Added - **Presence**: Added support for skipping the initial animation when the component is mounted. This can be used in all disclosure components (e.g., `Dialog`, `DatePicker`, `Menu` etc). ### Fixed - **Tabs**: Fixed issue where tabs indicator animation behaves inconsistently. - **Date Picker** - Fixed issue where datepicker throws error when navigating month view. - Fixed issue where range selection doesn't reset correctly when clicking the same start date. - **Disclosure Components** - Fixed issue where pointerdown outside doesn't work consistently on mobile devices. - Improved pointerdown outside click detection in shadow DOM environments. ## [5.4.0] - 2025-03-28 ### Added - **Slider** - Add support for `origin: end` to align the thumb to the end of the track. - Expose `thumbSize` as CSS variables in the root element. Can be useful for styling the slider. - **Menu** - Added `onSelect` event to the `Menu.Item` component. ### Fixed - Ensured each component's state machine starts before processing events. - **HoverCard, ColorPicker**: Added missing `tabIndex` for better dialog support. - **Menu**: Assigned unique IDs to menu items to improve accessibility and HTML validation. ## [5.3.1] - 2025-03-24 ### Fixed - Fixed an issue where a function was imported from a package that wasn't declared as a dependency. ## [5.3.0] - 2025-03-24 ### Added - **Collapsible**: Added an `Indicator` part to display whether the collapsible was open or closed. - **ColorPicker**: Added support for formatting the `ValueText` component. ```tsx // #ff0000 ``` ### Fixed - **Combobox**: Fixed an issue where `onOpenChange` was called with the same `open` value. - **DownloadTrigger**: Added the missing `use client` directive. - **Splitter**: Fixed an issue where `onResizeStart` and `onResizeEnd` callbacks weren't triggered during keyboard interactions. ## [5.2.0] - 2025-03-22 ### Added - **[NEW] DownloadTrigger**: Added Component for downloading a blob or file, whether retrieved synchronously or asynchronously. ```tsx import { DownloadTrigger } from '@ark-ui/react/download-trigger' export const DownloadImage = () => { async function fetchImage() { const response = await fetch('https://picsum.photos/200/300') return response.blob() } return ( Download Image ) } ``` ### Changed - **NumberInput**: Set the default step to `0.01` when `formatOptions.style` was set to `percent`. - **[Breaking] Splitter**: Redesigned splitter machine to support more use cases and improve DX. Check out the [Splitter](https://ark-ui.com/docs/components/splitter) documentation for more details. ### Fixed - **Toast**: Fixed issue where setting `offsets` to `undefined` caused the machine to throw. - **Select**: Fixed issue where select `valueAsString` lost reactivity. ## [5.1.0] - 2025-03-17 ### Added - Added support for a cleanup function in `ref`. ### Fixed - **Field**: Exported the missing `useField` hook. - **NumberInput**: `onValueChange` correctly received `valueAsNumber`. - **Slider**: Thumbs initialized correctly when `min` was set to a non-zero value. ## [5.0.1] - 2025-03-11 ### Fixed - Effects now flush synchronously instead of using a microtask. - **Checkbox**: `data-invalid` is no longer set when `invalid` is `false`. - **Combobox**: Fixed unexpected cursor movement when editing input. - **PinInput**: OTP SMS autofill now works as expected. - **RatingGroup**: Fixed incorrect focus placement on the label. - **TagsInput**: Improved caret detection to prevent unintended tag removal. - **Timer** - Fixed slowdown when switching tabs/windows. - Changed default `interval` from `250` to `1000`. ## [5.0.0] - 2025-03-06 Ark UI just got a major performance boost! 🚀 ### What’s new in v5? - **Blazing-fast performance** – Every component runs smoother and renders faster. - **Smaller bundle size** – Leaner components and adapters for a more efficient build. We made this happen by using React’s native reactive primitives instead of external stores. In our stress tests with **10,000 components**, Ark v5 delivered **1.5x–4x** better performance across the board. ![Performance comparison showing Ark v5 is 1.5x-4x faster than other libraries](./v5.svg) ### A quick note on tests Most component updates are non-breaking, but due to this change, some tests may need adjustments. For example: ```jsx // Before it('should open by default', () => { render() expect(screen.getByRole('dialog')).toBeInTheDocument() }) // After it('should open by default', async () => { render() expect(await screen.findByRole('dialog')).toBeInTheDocument() }) ``` #### Added - **Carousel**: ⚠️ Breaking change: Added required prop `slideCount` to `Carousel.Root` component. - **Clipboard**: Added `onValueChange` and `defaultValue` props. - **ColorPicker**: Added `defaultFormat` prop. - **Combobox**: Added `defaultHighlightedValue` and `defaultInputValue` props. - **DatePicker**: Added `defaultFocusedValue` prop, `getViewProps`, and `visibleRangeText`. - **HoverCard**: Expanded interaction handlers. - **Menu**: Added `defaultHighlightedValue` prop. - **Pagination**: Added `defaultPageSize` prop. - **PinInput**: Added `count` prop for better SSR aria-label. - **Progress**: Added `locale` and `formatOptions` props. - **QrCode**: Added `pixelSize` prop. - **Select**: Added `defaultHighlightedValue` prop. - **TagsInput**: Added `defaultInputValue` prop. - **Toggle**: Reintroduced toggle machine. #### Fixed - **Accordion**: Fixed issue in Safari where clicking triggers didn't show content. - **Avatar**: Fixed `api.setSrc` not working. - **Carousel**: Fixed pagination sync and initial page issues. - **File Upload**: Fixed drag-and-drop when `directory: true`. - **Menu**: Fixed context menu positioning not updating on right-click. - **Number Input**: Fixed `value` prop not being consumed. - **Pin Input**: Fixed focus warnings and editing issues. - **Progress**: Allowed more precise (decimal) values. - **Radio Group, Switch**: Improved focus behavior in Safari. - **Select**: Fixed regression where `multiple: true` didn't work. - **Steps**: Ensured ARIA attributes use valid values and wrapped `
      1. ` elements correctly within `
          ` or `
            `. - **Textarea**: Fixed `ResizeObserver` warning. - **Timer**: Fixed stopping issue when switching tabs; resolved issue where `action` prop was passed to `ActionTrigger`. - **Toast**: Fixed keyboard navigation skipping close button. - **Toggle Group**: Fixed `data-focus` not being removed on blur. --- # Changelog (SVELTE) ## [Unreleased] ### Added - **Date Picker**: Added `ValueText` component for displaying selected date value(s) with placeholder support and render prop for custom formatting - **Scroll Area**: Added overflow CSS variables (`--scroll-area-overflow-{x,y}-{start,end}`) for scroll fade effects - **Slider**: Added `thumbCollisionBehavior` prop (`none`, `push`, `swap`) - **Steps**: Added `isStepValid`, `isStepSkippable`, and `onStepInvalid` for validation support - **Tags Input**: Added `placeholder` prop (shown only when no tags exist) - **Tooltip**: Added `data-instant` attribute for instant animations ### Fixed - **Auto Resize**: Fixed change event not emitted after clearing controlled textarea - **Date Picker**: Fixed `visibleRangeText` to show correct format based on current view (year/month/day) - **Dismissable**: Fixed issue where closing a nested dialog/popover would incorrectly close its parent layers - **Menu**: Fixed glitchy submenu behavior when hovering between trigger items quickly - **Checkbox**: Fixed individual checkbox props being overridden by `CheckboxGroup` - **Collection, Tree View**: Fixed initial focus when first node/branch is disabled - **Color Picker**: Fixed color not updating when selecting black shades in controlled mode - **Floating Panel**: Fixed double-click on minimized title bar incorrectly maximizing - **Image Cropper**: Fixed `reset()` destroying cropper, prop changes not updating instantly, and panning bounds - **Number Input**: Fixed cursor positioning after clicking label or scrubbing - **Pagination**: Fixed next trigger not disabled when `count` is `0` - **Slider**: Fixed thumb drag from edge in `thumbAlignment="contain"` mode - **Switch**: Fixed `api.toggleChecked()` not working - **Toast**: Fixed toasts created before state machine connects not showing - **Tour**: Fixed janky scroll between steps ## [5.30.0] - 2025-12-10 ### Added - **Date Picker**: Added `required` and `invalid` props - **Number Input**: Added `onValueCommit` callback that fires when the input loses focus or Enter is pressed - **Pagination**: - Added `FirstTrigger` and `LastTrigger` components for navigating to first/last page - Added `boundaryCount` parameter for controlling boundary pages (start/end) - Implemented balanced pagination algorithm for consistent UI with max 7 elements - **Radio Group**: Added `invalid` and `required` props with corresponding `data-*` and `aria-*` attributes - **Tree View**: Added `scrollToIndexFn` prop to enable keyboard navigation in virtualized trees ### Fixed - **Accordion, Menu**: Fixed issue where querying elements by `aria-controls` attribute could fail when lazy mounting the content - **Color Picker**: Added `role="dialog"` to content and `aria-haspopup="dialog"` to trigger when not inline for better accessibility - **Date Picker**: Fixed issue where date picker input does not update format when locale changes - **Floating Panel**: - Fixed `dir` prop now properly delegated to all panel parts - Fixed double-click behavior improvements and to check `event.defaultPrevented` for custom behavior - **Listbox**: - Fixed issue in React where filtering items with an input would throw a `flushSync was called from inside a lifecycle method` warning - Fixed issue where `data-highlighted` wasn't applied to the first item when using `autoHighlight` with input filtering - **Number Input**: - Fixed improved controlled usage sync - Fixed issue where input element doesn't sync when `formatOptions` changes dynamically - Ensured cursor position is preserved when `Enter` key is pressed and formatting is triggered - Fixed cursor jumping to start when value is changed externally via props while user is typing - **Pagination**: Fixed ellipsis showing when only 1 page gap - **Rating Group**: Fixed issue where rating group becomes unfocusable via keyboard when value is 0 - **Tooltip**: Fixed tooltip not showing when scrolling with pointer over trigger ### Changed - **Tree View**: `getVisibleNodes()` now returns `{ node, indexPath }[]` instead of `node[]` ## [5.29.1] - 2025-11-22 ### Fixed - **Fieldset**: Fixed `aria-describedby` resolution to correctly reference helper text and error text IDs - **Floating Panel**: - Fixed resize trigger issue with `n` axis by explicitly setting `top: 0` - Fixed `draggable` and `resizable` options not being respected when set to `false` - **Presence**: Fixed regression where UNMOUNT transition might not be called consistently ## [5.29.0] - 2025-11-20 ### Added - **Carousel, Color Picker, Combobox, Date Picker, Select**: Added `value` to `OpenChangeDetails` for better context when handling open state changes - **Carousel**: Added support for `autoSize` prop to allow variable width/height slide items - **Splitter**: - Added `Splitter.ResizeTriggerIndicator` to render an indicator when resizing - Exported `getLayout` and `getSplitterLayout` functions for calculating splitter panel layouts - **Toast**: Exposed viewport offset as CSS variables on the toast group element ### Fixed - **Carousel**: - Fixed dragging behavior that stops working after switching browser tabs or scrolling the page - Fixed dragging not working after scrolling with mouse wheel when `allowMouseDrag` is enabled - **Combobox**: Fixed `onHighlightChange` not being invoked when collection is filtered to empty - **Date Picker**: Fixed issue where the range date picker crashes when typing the end date first and blurring the input field multiple times - **File Upload**: Fixed issue where clicking on non-interactive children inside the dropzone doesn't open the file picker - **Presence**: Fixed a bug where elements get stuck in unmountSuspended state during rapid state updates - **Radio Group**: - Fixed inconsistent application of `data-focus-visible` and `data-focus` attributes - **Splitter**: Fixed disabled splitter showing resize cursor and allowing dragging - **Tabs**: - Fixed tabs indicator position not updating when inactive tabs change size - **Tags Input**: Fixed issue where item delete trigger doesn't have `data-*` attached ## [5.28.0] - 2025-11-14 ### Added - **General**: Exported `InteractOutsideEvent`, `FocusOutsideEvent`, and `PointerDownOutsideEvent` types for better type safety - **Carousel**: - Added `Carousel.AutoplayIndicator` component for conditionally rendering content based on autoplay state - Added `Carousel.ProgressText` component for displaying current page progress (e.g., "1 / 5") - **Toast**: Exported `ToastOptions` and `ToastStoreProps` types for better type safety ### Changed - **useListCollection**: Updated `initialItems` to accept `readonly` arrays for better compatibility with immutable data patterns. ### Fixed - **Combobox**: - Fixed focus stealing in controlled open mode - Removed problematic `aria-hidden` behavior to allow interaction with other page elements ## [5.27.1] - 2025-11-02 ### Fixed - **Dialog, Popover**: Improved shadow DOM support for interact outside and focus trap detection - **Marquee**: Fixed Firefox flicker and added GPU acceleration - **Dialog**: Fixed layout shift issue when using `scrollbar-gutter: stable` in CSS - **Slider**: Fixed `onValueChangeEnd` callback not triggering for programmatic value changes ## [5.27.0] - 2025-11-01 ### Added - **Marquee** [New]: Initial release of marquee component for continuously scrolling content ### Fixed - **Angle Slider**: Resolved an issue where dragging the thumb from non-center positions caused unexpected value jumps. The thumb now maintains consistent positioning relative to the initial click point. - **Slider**: Fixed a problem where the thumb offset shifted dynamically during dragging, resulting in value jumps. The offset now remains constant from the pointer throughout the drag operation. - **Date Picker**: Resolved a crash in the range date picker occurring when users typed the end date first by implementing `null`/`undefined` checks for date property access. - **Radio Group**: Reverted to `offsetLeft`/`offsetTop` calculations to restore correct indicator positioning within scrollable container contexts. - **Tabs**: Reverted to `offsetLeft`/`offsetTop` calculations to fix indicator positioning issues in scrollable containers. - **Tour**: - Corrected improper effect cleanup procedures - Fixed wait step functionality - Added step validation on mount to verify configuration validity ## [5.26.2] - 2025-10-18 ### Fixed - **Angle Slider**: Fix accessibility violation where the slider thumb element lacked an accessible name. The thumb now supports `aria-label` and `aria-labelledby` props, and automatically falls back to the label element's ID for proper ARIA labeling. - **Select**: Fix accessibility violation where the required state was not set correctly to on the trigger. - **Tags Input**: Fix issue where entering a custom tag with combobox integration required pressing `Enter` twice. The tags-input now correctly handles custom values when the combobox has no highlighted item (`aria-activedescendant` is empty), allowing the tag to be added on the first `Enter` press. ## [5.26.1] - 2025-10-15 ### Fixed - **Checkbox** - Fix issue where setting initial checked state to `indeterminate` doesn't work - Ensure `api.checkedState` returns the correct checked state (`boolean | "indeterminate"`) - **Collapsible**: Fix issue where `dir` prop value was hardcoded to `ltr` instead of using the provided value - **Combobox**: Fix issue where controlled single-select combobox does not propagate its initial value to `inputValue` - **Listbox**: Fix issue where pressing Enter key when no highlighted item still calls `event.preventDefault()` - **Radio Group**: Refactor to use `getBoundingClientRect()` for precise indicator positioning - **Slider** - Fix issue where slider could stop abruptly when scrubbing thumb - Fix issue where range slider thumbs become stuck when dragged to the same position without `minStepsBetweenThumbs` - **Tabs**: Refactor to use `getBoundingClientRect()` for precise indicator positioning - **Tags Input**: Fix issue where `maxLength` doesn't apply to the edit input as well ## [5.26.0] - 2025-10-08 ### Added - **Collapsible**: Add support for `collapsedHeight` and `collapsedWidth` props to control the dimensions of the collapsible content when in its collapsed state. - **Focus Trap**: Allow elements referenced by `aria-controls` to be included in the trap scope. This makes it possible for menus, popovers, etc. to be portalled and work correctly. - **Pagination**: Add `getPageUrl` prop for generating `href` attributes when using pagination as links. ```ts const service = useMachine(pagination.machine, { type: 'link', getPageUrl: ({ page, pageSize }) => `/products?page=${page}&size=${pageSize}`, }) ``` - **Select**: Add `SelectRootComponentProps` type export for better component type composition. - **Listbox**: Add `ListboxRootComponentProps` type export for better component type composition. - **Combobox**: Add `ComboboxRootComponentProps` type export for better component type composition. - **TreeView**: - Add `TreeViewRootComponentProps` type export for better component type composition. - (Experimental) Add support for node renaming functionality: - Add `TreeViewNodeRenameInput` component for inline node label editing - Add `canRename` prop to control which nodes can be renamed - Add `onRenameStart`, `onBeforeRename`, and `onRenameComplete` callbacks for rename lifecycle - Add `CheckedChangeDetails`, `LoadChildrenErrorDetails`, `RenameStartDetails`, and `RenameCompleteDetails` type exports ### Fixed - **Scroll Area**: Fix RTL horizontal scrollbar positioning on Safari - **Slider**: Fix issue where slider continues dragging when disabled during drag operation. - **Switch**: Fix issue where `data-active` is inconsistently applied when `disabled` state changes at runtime ## [5.25.1] - 2025-09-27 ### Fixed - **Date Picker** - Fix issue where year range picker doesn't show the hovered range - Fix issue where quarter presets returns incorrect date - **FormatByte**: Add support for `unitSystem` property to allow changing between decimal (1000 bytes) and binary (1024 bytes) systems. - **Number Input**: When `formatOptions` is used (like `style: "currency"`), the cursor would jump to the end of the input when typing in the middle. The cursor now maintains its relative position during formatting changes. - **Pin Input**: Fix issue where using the keyboard shortcuts `Cmd+Backspace` and `Cmd+Delete` to delete text in pin inputs would insert "undefined" instead of clearing the field. - **Scroll Area**: Fix issue where resize tracking was not observing the root element, which caused the scrollbar to not update when the root element's size changed. ## [5.25.0] - 2025-09-16 ### Added - Added `mergeProps` utility for combining multiple props objects with proper event handler and className merging. - Added `createContext` utility for creating typed React contexts with improved DX. ```tsx import { createContext } from '@ark-ui/react/utils' ``` ### Fixed - **AngleSlider**: Export `angleSliderAnatomy` from the anatomy exports ## [5.24.1] - 2025-09-14 ### Fixed - **General**: Fix issue where `mergeProps` throws when `props` is `undefined` or `null` ## [5.24.0] - 2025-09-14 ### Added - **Combobox**: Add `alwaysSubmitOnEnter` prop to allow bypassing the default two-step behavior (Enter to close combobox, then Enter to submit form) and instead submit the form immediately on Enter press. This is useful for single-field autocomplete forms where Enter should submit the form directly. - **Dismissable**: Add support for layer types in dismissable layer stack. Layers can now be categorized as `dialog`, `popover`, `menu`, or `listbox`. This enables: - `data-nested` attribute on nested layers of the same type - `data-has-nested` attribute on parent layers with nested children of the same type - `--nested-layer-count` CSS variable indicating the number of nested layers of the same type ### Changed - **Hover Card**: Change default delay values for hover card to improve accessibility. - `openDelay`: from `700ms` to `600ms` - **Tooltip**: Change default delay values for tooltip to improve accessibility. [Learn more](https://www.nngroup.com/articles/timing-exposing-content) - `openDelay`: from `1000ms` to `400ms` - `closeDelay`: from `500ms` to `150ms` ### Removed - **TimePicker**: The TimePicker component has been removed from this release. This component was never part of the public API and was considered experimental. It had significant bugs and usability issues across all frameworks and locales, making it unsuitable for production use. **Migration**: We recommend building a custom time picker using the Select component for simple use cases, or implementing a time grid pattern for more complex scenarios. ### Fixed - **Editable**: Allow text selection in editable preview when `autoResize` is enabled Previously, when `autoResize` was set to `true`, the preview element had `userSelect: "none"` applied, preventing users from selecting text. This has been fixed by removing the `userSelect` style property. - **File Upload**: Fix regression where clicking the trigger doesn't open the file picker when used within the dropzone - **Menu**: - Fix issue where keyboard activation of menu items with `target="_blank"` would open two tabs - Fix issue where hovering a partially visible item with pointer causes it to scroll into view - **Tabs**: Fix issue where `ids` for `item` and `content` could not be customized - **Toast**: Allow creating a toast store without any arguments ## [5.23.0] - 2025-09-08 ### Added - **Field**: Add `data-required` attribute to `Field.Label` - **Select, Combobox, Listbox, TreeView**: Export `RootComponent` and `RootProviderComponent` types which are useful when building compositions that wrap the `Root` and `RootProvider` components and you still want type-safety for the collection. ### Fixed - **Menu**: Fix `Menu.ItemText` not working inside `Menu.TriggerItem` ```tsx import { Select } from '@ark-ui/react/select' import { styled } from 'styling-lib' const Root = styled(Select.Root) as Select.RootComponent<{}> ``` ## [5.22.0] - 2025-08-28 ### Added - **Combobox**: Add `ComboboxEmpty` component to display content when the combobox has no items - **Listbox**: Add `ListboxEmpty` component to display content when the listbox has no items - **Hover Card**: Add support for `disabled` prop ### Fixed - **Collection**: Fix issue where disabled items could be reached via typeahead - **Color Picker**: Fix issue where color picker was not working correctly in RTL mode - **Date Picker**: Fix issue where datepicker doesn't revert to a valid value when the input value exceeds the min/max and blurred - **Dismissable**: Expose `onRequestDismiss` custom event handler for event a parent layer requests the child layer to dismiss. If prevented via `event.preventDefault()`, the child layer will not dismiss when the parent layer is dismissed. - **Number Input** - Omit the input `pattern` when `formatOptions` is provided. This prevents native pattern validation from conflicting with formatted values (e.g., currency or percent). - Handle empty values consistently across all format options. - Add `data-scrubbing` attribute to the number input parts. - **Tags Input**: Fix issue where highlighted item doesn't clear when tabbing out of the input to an external button within the `control` part. - **Tooltip** - Set `closeOnPointerdown` to `false` when `closeOnClick` is set to `false` - Reduce bundle size by replacing `@zag-js/store` dependency with a lightweight store implementation. ## [5.21.0] - 2025-08-24 ### Added - **Hooks**: Add `useAsyncList` and `useCollator` hooks for managing asynchronous list operations and locale-aware string comparison - **Toast**: Export type definitions `ToastActionOptions`, `ToastPlacement`, `ToastPromiseOptions`, `ToastStatus`, `ToastStatusChangeDetails`, and `ToastType` ### Changed - **Fieldset** - Update Legend component to render as `div` instead of `legend` element for improved styling flexibility - Add `aria-labelledby` attribute to fieldset root for better accessibility by linking to legend ### Fixed - **Date Picker** - Clear hovered range state after completing range selection instead of waiting for pointer to leave the calendar area. - Fix issue where month and year select labels don't update correctly when using `min`/`max` constraints. - Expose `disabled` on `api.getMonths()` and `api.getYears()` results to indicate options out of range for current constraints. - **Listbox** - Fix issue where first enabled item should be highlighted by default when listbox receives focus and no item is currently highlighted. - Add `getElement` to `scrollToIndexFn` details - Track collection changes and clear `highlightedValue` if the item is no longer in the collection. - **Scroll Area** - Avoid detecting hover state from portalled descendants. - Add `data-dragging` attribute to scroll area parts. - **Select**: Add `getElement` to `scrollToIndexFn` details - **Combobox**: Add `getElement` to `scrollToIndexFn` details - **Tabs**: Fix inconsistent keyboard navigation where TabPanel intermittently receives focus before focusable elements ## [5.20.0] - 2025-08-20 ### Added - **Highlight Word**: Add `exactMatch` option that enables whole-word matching using regex word boundaries. ### Fixed - **Menu**: Fix context menu repositioning logic - **ScrollArea**: Add `data-hover` to scroll area ## [5.19.0] - 2025-08-18 ### Added - **ScrollArea [NEW]**: Add support for new scroll area component. ### Fixed - **ListCollection** - Avoid recomputing groups on every call to `at()` and `indexOf()` - Fixed bug in `find()` method (was checking `!= null` instead of `!== -1`) - **GridCollection**: Avoid recomputing rows on every call to `getRows()` - **Menu** - Add `data-state` attribute for context menu trigger - Fix context menu positioning bug where reopening at the same coordinates fails to reposition ## [5.18.4] - 2025-08-14 ### Fixed - **Listbox**: Add support for navigating grid collections - **Carousel**: - Fix an issue where the carousel would not update when `slideCount` or `autoplay` props change. - Fix an issue where `loop: false` was ignored when using autoplay. Now, the carousel will stop when it gets to the last slide. - **Date Picker**: Expose `data-inline` attribute on Content part to enable distinct styling for inline date pickers versus popover date pickers. - **Menu**: Fix issue where `onCheckedChange` could be called twice on checkbox or radio item - **Radio Group**: Fixed issue where arrow key navigation doesn't apply `data-focus-visible` on the newly focused item. - **TagsInput**: Export `InputValueChangeDetails` type ### Changed - **Async List**: Improve type inference for descriptors ## [5.18.3] - 2025-08-01 ### Fixed - **Factory**: Check if `children` is a valid React element before calling `Children.only()` - **Carousel**: Fix issue where controlled carousel ignores last slide ## [5.18.2] - 2025-07-26 ### Fixed - **Dialog** - Sync content `--layer-index` with positioner and backdrop - Decouple `trapFocus` from `modal` so it's possible to set `modal=false` and `trapFocus=true` ## [5.18.1] - 2025-07-23 ### Fixed - **Date Picker**: Fixed issue where hovered range was connect to selected values, when it shouldn't - **Tree View**: Fixed issue where tree view doesn't scroll into view when content overflows. ## [5.18.0] - 2025-07-22 ### Added - **Collection**: Add `useListSelection` hook for managing collection item selection with support for single/multiple selection modes ```jsx const collection = createListCollection({ items: ['React', 'Vue', 'Angular'] }) const selection = useListSelection({ collection }) // Check if item is selected const isSelected = selection.isSelected('React') // Select/deselect items selection.select('React') selection.toggle('Vue') ``` - **File Upload**: Add support for programmatically controlling the accepted files via `acceptedFiles` and `defaultAcceptedFiles` - **Signature Pad**: Add support for programmatically controlling the paths via `paths` and `defaultPaths` props. - **Date Picker**: Added hover range preview support for date picker range selection. Added `inHoveredRange`, `firstInHoveredRange`, and `lastInHoveredRange` properties to `DayTableCellState` with corresponding data attributes `data-in-hover-range`, `data-hover-range-start`, and `data-hover-range-end`. Hover range states are only active when not overlapping with actual selected range, enabling distinct styling for hover preview vs actual selection in range mode. ### Fixed - **Date Picker**: Fix date comparison issues when time components are involved. This resolves critical issues with date comparison operations when different date types (`CalendarDate`, `CalendarDateTime`, `ZonedDateTime`) are mixed, particularly in scenarios involving time components. ## [5.17.0] - 2025-07-18 ### Added - **Checkbox**: Add `CheckboxGroupProvider` component for external checkbox group state management ### Fixed - **Carousel**: Fix issue where full page carousel could trap scrolling - **ListCollection**:Export `UseListCollectionReturn` type - **TreeCollection**: Fix issue where the `filter` method completely deletes the children key from the node when there are no matching children - **Number Input**: Fix issue where default pattern does not allow negative numbers with decimal point - **File Upload** - Export `FileError`, `FileMimeType`, and `FileRejection` types - Fix issue where calling `api.setFiles` invokes validation with incorrect `acceptedFiles` - Fix issue where the browser might not be able to infer the mime type of a file due to limitations, drag source or security restrictions. As a fallback in the file validation logic, we now infer the mime type from the file extension. ## [5.16.1] - 2025-07-05 ### Fixed - **Combobox** - Expose `reason` to `onOpenChange` and `onInputValueChange` callbacks - Expose `api.clearHighlightedValue` function to clear highlighted value - **Date Picker** - Fix issue where datepicker errors when setting `selectionMode=range` and `minView=year` - Fix issue where `focusedValue` could not be fully controlled - **Toast**: Fix issue where toast `title` or `description` could not accept React element - **Listbox**: Select highlighted item only if it exists in the collection - **Progress**: Improve `valueAsString` formatting - **Select** - Select highlighted item only if it exists in the collection - Expose `api.clearHighlightedValue` function to clear highlighted value - **Tour**: Fix an issue where the `goto` function in `StepActionMap` doesn't work when passing step IDs (string) - **Tree View**: Expose `id` in the tree node state - **ClientOnly**: Support `children` as a function ## [5.16.0] - 2025-07-01 ### Added - **Color Picker**: Add support for `inline` prop to render color picker inline - **Date Picker**: Add support for `inline` prop to render the date calendar inline ### Fixed - **Color Picker**: Auto-prefix Hex values with `#` if missing when using the `hex` channel input - **Menu**: Fix interaction outside detection for focusable context trigger - **Tree View**: Improve support for rendering tree items as links ## [5.15.4] - 2025-06-27 ### Fixed - **Combobox, Select, Listbox**: Fix issue where rehydrating `defaultValue` or `value` after fetching items doesn't update the `valueAsString` ## [5.15.3] - 2025-06-27 ### Fixed - **Tree View**: Fix tree traversal for querying last node ## [5.15.2] - 2025-06-26 ### Fixed - **Date Picker**: Fix issue with keyboard selection where setting unavailable date causes month view to behave differently from clicking with mouse - **Toast**: Fix issue where app crashes when `toaster.promise` is called without loading option. The `loading` option is now required. A warning will be logged if it is not provided - **Tree View** - Fix issue where clicking a branch with indeterminate state doesn't check its child nodes - Remove `aria-busy` attribute from branch trigger when not loading children - Expose node details in `onExpandChange`, `onSelectionChange` and `onFocusChange` - **Angle Slider**: Fix issue where scrubbing doesn't feel smooth on touch devices - **Timer**: - Fix issue where timer could continue beyond `targetMs` when window is not visible - Add validation to ensure `startMs` and `targetMs` are configured correctly - Fix `progressPercent` calculation for countdown timers ## [5.15.1] - 2025-06-23 ### Fixed - **Listbox**: Fix issue where `Listbox.ItemContext` was not exported ## [5.15.0] - 2025-06-23 ### Added - **Tree View** - Add support for checkbox state for checkbox trees via `defaultCheckedValue`, `checkedValue`, `onCheckedChange` props - Add callback for when `loadChildren` fails via `onLoadChildrenError` prop ### Fixed - **Progress** - Fix issue where setting orientation to `vertical` don't work - Fix issue where setting `defaultValue` to `null` doesn't show indeterminate state ## [5.14.2] - 2025-06-19 ### Fixed - **General**: Ensure pointerdown or click event handlers only execute when the main button is clicked - **Tree View**: Exported `TreeViewNodeState` and `TreeViewNodeProps` types from `@zag-js/tree-view` ### Changed - **Collection**: Improve the APIs around `tree.flatten(...)` and `flattenedToTree` to ensure the original node properties are preserved. > Previously, `tree.flatten()` would return an array of objects with `value` and `label` stripping out the original > node properties. ```ts const tree = new TreeCollection({ rootNode: { value: 'ROOT', children: [{ value: 'child1' }, { value: 'child2' }], }, }) const flattened = tree.flatten() const reconstructed = flattenedToTree(flattened) console.log(reconstructed.rootNode) // { // value: "ROOT", // children: [{ value: "child1" }, { value: "child2" }], // } ``` ## [5.14.1] - 2025-06-17 ### Fixed - **Popover**: Fixed issue where `onOpenChange` could be called twice when controlled - **File Utils**: Improved `downloadFile` function to handle webview scenarios - **Combobox**: - Fixed issue where `onInputValueChange` could be called twice when selecting an item - Fixed issue where combobox with `allowCustomValue: true` used within in a form requires two enter keypress to submit ## [5.14.0] - 2025-06-10 ### Added - **Editable**: Added support for `activationMode=none` - **Collection** - Exposed `copy` method - Added support for `getParentNodes` to accept a value or index path ### Fixed - **Collection**: Fixed issue where entrypoint `@ark-ui/react/collection` was not working as expected - **Carousel**: Fixed issue where carousel crashes when `slidesPerPage` is 0 - **File Upload**: Prevented `undefined` in `acceptedFiles` when no files accepted - **Select**: Fixed issue where highlighted item could be cleared when navigating up/down the list with keyboard - **Tabs**: Fixed issue where tabs with links should not trigger tab change upon cmd/middle click - **Menu**: Fixed issue where `Menu.ItemText` could not be used with `Menu.Item` ## [5.13.0] - 2025-06-07 ### Added - **Collection**: Added new `useListCollection` hook to create a dynamic list collection. ### Fixed - **Progress**: Exported `ProgressValueChangeDetails` and `ProgressValueTranslationDetails` types from `@zag-js/progress` ## [5.12.0] - 2025-06-05 ### Added - **Tree View**: Added support for lazy loading node children. To use this, you need to provide: - `loadChildren` is a function that is used to load the children of a node. - `onLoadChildrenComplete` is a callback that is called when the children of a node are loaded. Used to update the tree collection. - Add `childrenCount` to the node object to indicate the number of children. ### Fixed - **Slider** - Fixed issue where `Shift` + `ArrowRight` set value to `0` instead of `max` when step is too large (e.g. `20`) - Fixed issue where `onValueChangeEnd` doesn't return the latest value when dragging very fast ## [5.11.0] - 2025-05-30 ### Added - **File Upload**: Added support for transforming uploaded files via `transformFiles` context property. ### Fixed - **Slider**: Fixed issue where `minStepsBetweenThumbs` isn't computed correctly when interacting with pointer or keyboard. ## [5.10.0] - 2025-05-29 ### Added - **[NEW] Password Input**: Added `PasswordInput` component for creating password inputs ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' export const Basic = () => ( Password }> ) ``` - **Select**: Added `onSelect` callback that gets fired when an item is selected via keyboard/mouse. ### Fixed - **Color Picker**: Fixed issue where value change end event is invoked when committing via an input. - **Toast**: Fixed issue where calling `toast.remove()` without an id shows a TypeScript error. - **Field**: Fixed issue where helper text and error text could not be detected in shadow DOM environments. ## [5.9.2] - 2025-05-24 ### Fixed - **Collection**: Export `CollectionOptions`, `TreeCollectionOptions`, `GridCollectionOptions` types. - **Carousel** - Fixed issue where focusing on carousel region and navigating with keyboard doesn't work as expected - Fixed issue when `allowMouseDrag` is set where carousel no longer snaps after mouse interaction - **Combobox**: Fixed issue where `onInputValueChange` doesn't get called when `autoFocus` is set to `true` - **Slider**: Fixed issue where slider could throw a error when rendered in an popover or dialog - **Tour**: Fixed issue where calling `api.start()` with a step id doesn't work as expected ## [5.9.1] - 2025-05-12 ### Fixed - **Combobox**: Fixed issue where `focusable` prop was not being applied to the trigger element. - **Collection**: Fixed issue where `getNextValue` and `getPreviousValue` doesn't work as expected when `groupBy` is used. ## [5.9.0] - 2025-05-05 ### Added - **Locale**: Added `useFilter` hook to filter data based on the current locale. - **Format**: Added `FormatRelativeTime` component for formatting relative time. ## [5.8.0] - 2025-05-01 ### Added - **Date Picker**: Added support for `outsideDaySelectable` prop to allow selecting days outside the current month (on the same visible date range) ### Fixed - **Collapsible**: Fixed issue in React.js <= v18.x where collapse animation might not work as expected ## [5.7.0] - 2025-04-25 ### Added - **[NEW] Listbox**: Introduced the `Listbox` component for selecting a single or multiple items from a list. See the [documentation](https://ark-ui.com/docs/components/listbox) for details. - Improved support for grouping collection items. Check the `Listbox`, `Select` or `Combobox` documentation for more details. ### Changed - Added `package.json` to `exports` for improved compatibility with tools like Vite. ## [5.6.0] - 2025-04-15 ### Added - **[NEW] AngleSlider**: Introduced the `AngleSlider` component for selecting an angle. See the [documentation](https://ark-ui.com/docs/components/angle-slider) for details. - **[NEW] FloatingPanel**: Introduced the `FloatingPanel` component for creating floating windows. See the [documentation](https://ark-ui.com/docs/components/floating-panel) for details. - **Toast**: Added toast queuing when the max limit is reached: - New toasts were queued instead of dropped - Queued toasts were shown when space became available - Queue cleared when all toasts were removed - **Combobox**: - Fallbacked to the trigger element as the positioning anchor - Added `data-empty` attribute to indicate an empty listbox or content ## [5.5.0] - 2025-04-05 ### Added - **Presence**: Added support for skipping the initial animation when the component is mounted. This can be used in all disclosure components (e.g., `Dialog`, `DatePicker`, `Menu` etc). ### Fixed - **Tabs**: Fixed issue where tabs indicator animation behaves inconsistently. - **Date Picker** - Fixed issue where datepicker throws error when navigating month view. - Fixed issue where range selection doesn't reset correctly when clicking the same start date. - **Disclosure Components** - Fixed issue where pointerdown outside doesn't work consistently on mobile devices. - Improved pointerdown outside click detection in shadow DOM environments. ## [5.4.0] - 2025-03-28 ### Added - **Slider** - Add support for `origin: end` to align the thumb to the end of the track. - Expose `thumbSize` as CSS variables in the root element. Can be useful for styling the slider. - **Menu** - Added `onSelect` event to the `Menu.Item` component. ### Fixed - Ensured each component's state machine starts before processing events. - **HoverCard, ColorPicker**: Added missing `tabIndex` for better dialog support. - **Menu**: Assigned unique IDs to menu items to improve accessibility and HTML validation. ## [5.3.1] - 2025-03-24 ### Fixed - Fixed an issue where a function was imported from a package that wasn't declared as a dependency. ## [5.3.0] - 2025-03-24 ### Added - **Collapsible**: Added an `Indicator` part to display whether the collapsible was open or closed. - **ColorPicker**: Added support for formatting the `ValueText` component. ```tsx // #ff0000 ``` ### Fixed - **Combobox**: Fixed an issue where `onOpenChange` was called with the same `open` value. - **DownloadTrigger**: Added the missing `use client` directive. - **Splitter**: Fixed an issue where `onResizeStart` and `onResizeEnd` callbacks weren't triggered during keyboard interactions. ## [5.2.0] - 2025-03-22 ### Added - **[NEW] DownloadTrigger**: Added Component for downloading a blob or file, whether retrieved synchronously or asynchronously. ```tsx import { DownloadTrigger } from '@ark-ui/react/download-trigger' export const DownloadImage = () => { async function fetchImage() { const response = await fetch('https://picsum.photos/200/300') return response.blob() } return ( Download Image ) } ``` ### Changed - **NumberInput**: Set the default step to `0.01` when `formatOptions.style` was set to `percent`. - **[Breaking] Splitter**: Redesigned splitter machine to support more use cases and improve DX. Check out the [Splitter](https://ark-ui.com/docs/components/splitter) documentation for more details. ### Fixed - **Toast**: Fixed issue where setting `offsets` to `undefined` caused the machine to throw. - **Select**: Fixed issue where select `valueAsString` lost reactivity. ## [5.1.0] - 2025-03-17 ### Added - Added support for a cleanup function in `ref`. ### Fixed - **Field**: Exported the missing `useField` hook. - **NumberInput**: `onValueChange` correctly received `valueAsNumber`. - **Slider**: Thumbs initialized correctly when `min` was set to a non-zero value. ## [5.0.1] - 2025-03-11 ### Fixed - Effects now flush synchronously instead of using a microtask. - **Checkbox**: `data-invalid` is no longer set when `invalid` is `false`. - **Combobox**: Fixed unexpected cursor movement when editing input. - **PinInput**: OTP SMS autofill now works as expected. - **RatingGroup**: Fixed incorrect focus placement on the label. - **TagsInput**: Improved caret detection to prevent unintended tag removal. - **Timer** - Fixed slowdown when switching tabs/windows. - Changed default `interval` from `250` to `1000`. ## [5.0.0] - 2025-03-06 Ark UI just got a major performance boost! 🚀 ### What’s new in v5? - **Blazing-fast performance** – Every component runs smoother and renders faster. - **Smaller bundle size** – Leaner components and adapters for a more efficient build. We made this happen by using React’s native reactive primitives instead of external stores. In our stress tests with **10,000 components**, Ark v5 delivered **1.5x–4x** better performance across the board. ![Performance comparison showing Ark v5 is 1.5x-4x faster than other libraries](./v5.svg) ### A quick note on tests Most component updates are non-breaking, but due to this change, some tests may need adjustments. For example: ```jsx // Before it('should open by default', () => { render() expect(screen.getByRole('dialog')).toBeInTheDocument() }) // After it('should open by default', async () => { render() expect(await screen.findByRole('dialog')).toBeInTheDocument() }) ``` #### Added - **Carousel**: ⚠️ Breaking change: Added required prop `slideCount` to `Carousel.Root` component. - **Clipboard**: Added `onValueChange` and `defaultValue` props. - **ColorPicker**: Added `defaultFormat` prop. - **Combobox**: Added `defaultHighlightedValue` and `defaultInputValue` props. - **DatePicker**: Added `defaultFocusedValue` prop, `getViewProps`, and `visibleRangeText`. - **HoverCard**: Expanded interaction handlers. - **Menu**: Added `defaultHighlightedValue` prop. - **Pagination**: Added `defaultPageSize` prop. - **PinInput**: Added `count` prop for better SSR aria-label. - **Progress**: Added `locale` and `formatOptions` props. - **QrCode**: Added `pixelSize` prop. - **Select**: Added `defaultHighlightedValue` prop. - **TagsInput**: Added `defaultInputValue` prop. - **Toggle**: Reintroduced toggle machine. #### Fixed - **Accordion**: Fixed issue in Safari where clicking triggers didn't show content. - **Avatar**: Fixed `api.setSrc` not working. - **Carousel**: Fixed pagination sync and initial page issues. - **File Upload**: Fixed drag-and-drop when `directory: true`. - **Menu**: Fixed context menu positioning not updating on right-click. - **Number Input**: Fixed `value` prop not being consumed. - **Pin Input**: Fixed focus warnings and editing issues. - **Progress**: Allowed more precise (decimal) values. - **Radio Group, Switch**: Improved focus behavior in Safari. - **Select**: Fixed regression where `multiple: true` didn't work. - **Steps**: Ensured ARIA attributes use valid values and wrapped `
          1. ` elements correctly within `
              ` or `
                `. - **Textarea**: Fixed `ResizeObserver` warning. - **Timer**: Fixed stopping issue when switching tabs; resolved issue where `action` prop was passed to `ActionTrigger`. - **Toast**: Fixed keyboard navigation skipping close button. - **Toggle Group**: Fixed `data-focus` not being removed on blur. --- # Changelog (SOLID) ## [Unreleased] ### Added - **Date Picker**: Added `ValueText` component for displaying selected date value(s) with placeholder support and render prop for custom formatting - **Scroll Area**: Added overflow CSS variables (`--scroll-area-overflow-{x,y}-{start,end}`) for scroll fade effects - **Slider**: Added `thumbCollisionBehavior` prop (`none`, `push`, `swap`) - **Steps**: Added `isStepValid`, `isStepSkippable`, and `onStepInvalid` for validation support - **Tags Input**: Added `placeholder` prop (shown only when no tags exist) - **Tooltip**: Added `data-instant` attribute for instant animations ### Fixed - **Auto Resize**: Fixed change event not emitted after clearing controlled textarea - **Date Picker**: Fixed `visibleRangeText` to show correct format based on current view (year/month/day) - **Dismissable**: Fixed issue where closing a nested dialog/popover would incorrectly close its parent layers - **Menu**: Fixed glitchy submenu behavior when hovering between trigger items quickly - **Checkbox**: Fixed individual checkbox props being overridden by `CheckboxGroup` - **Collection, Tree View**: Fixed initial focus when first node/branch is disabled - **Color Picker**: Fixed color not updating when selecting black shades in controlled mode - **Floating Panel**: Fixed double-click on minimized title bar incorrectly maximizing - **Image Cropper**: Fixed `reset()` destroying cropper, prop changes not updating instantly, and panning bounds - **Number Input**: Fixed cursor positioning after clicking label or scrubbing - **Pagination**: Fixed next trigger not disabled when `count` is `0` - **Slider**: Fixed thumb drag from edge in `thumbAlignment="contain"` mode - **Switch**: Fixed `api.toggleChecked()` not working - **Toast**: Fixed toasts created before state machine connects not showing - **Tour**: Fixed janky scroll between steps ## [5.30.0] - 2025-12-10 ### Added - **Date Picker**: Added `required` and `invalid` props - **Number Input**: Added `onValueCommit` callback that fires when the input loses focus or Enter is pressed - **Pagination**: - Added `FirstTrigger` and `LastTrigger` components for navigating to first/last page - Added `boundaryCount` parameter for controlling boundary pages (start/end) - Implemented balanced pagination algorithm for consistent UI with max 7 elements - **Radio Group**: Added `invalid` and `required` props with corresponding `data-*` and `aria-*` attributes - **Tree View**: Added `scrollToIndexFn` prop to enable keyboard navigation in virtualized trees ### Fixed - **Accordion, Menu**: Fixed issue where querying elements by `aria-controls` attribute could fail when lazy mounting the content - **Color Picker**: Added `role="dialog"` to content and `aria-haspopup="dialog"` to trigger when not inline for better accessibility - **Date Picker**: Fixed issue where date picker input does not update format when locale changes - **Floating Panel**: - Fixed `dir` prop now properly delegated to all panel parts - Fixed double-click behavior improvements and to check `event.defaultPrevented` for custom behavior - **Listbox**: - Fixed issue in React where filtering items with an input would throw a `flushSync was called from inside a lifecycle method` warning - Fixed issue where `data-highlighted` wasn't applied to the first item when using `autoHighlight` with input filtering - **Number Input**: - Fixed improved controlled usage sync - Fixed issue where input element doesn't sync when `formatOptions` changes dynamically - Ensured cursor position is preserved when `Enter` key is pressed and formatting is triggered - Fixed cursor jumping to start when value is changed externally via props while user is typing - **Pagination**: Fixed ellipsis showing when only 1 page gap - **Rating Group**: Fixed issue where rating group becomes unfocusable via keyboard when value is 0 - **Tooltip**: Fixed tooltip not showing when scrolling with pointer over trigger ### Changed - **Tree View**: `getVisibleNodes()` now returns `{ node, indexPath }[]` instead of `node[]` ## [5.29.1] - 2025-11-22 ### Fixed - **Fieldset**: Fixed `aria-describedby` resolution to correctly reference helper text and error text IDs - **Floating Panel**: - Fixed resize trigger issue with `n` axis by explicitly setting `top: 0` - Fixed `draggable` and `resizable` options not being respected when set to `false` - **Presence**: Fixed regression where UNMOUNT transition might not be called consistently ## [5.29.0] - 2025-11-20 ### Added - **Carousel, Color Picker, Combobox, Date Picker, Select**: Added `value` to `OpenChangeDetails` for better context when handling open state changes - **Carousel**: Added support for `autoSize` prop to allow variable width/height slide items - **Splitter**: - Added `Splitter.ResizeTriggerIndicator` to render an indicator when resizing - Exported `getLayout` and `getSplitterLayout` functions for calculating splitter panel layouts - **Toast**: Exposed viewport offset as CSS variables on the toast group element ### Fixed - **Carousel**: - Fixed dragging behavior that stops working after switching browser tabs or scrolling the page - Fixed dragging not working after scrolling with mouse wheel when `allowMouseDrag` is enabled - **Combobox**: Fixed `onHighlightChange` not being invoked when collection is filtered to empty - **Date Picker**: Fixed issue where the range date picker crashes when typing the end date first and blurring the input field multiple times - **File Upload**: Fixed issue where clicking on non-interactive children inside the dropzone doesn't open the file picker - **Presence**: Fixed a bug where elements get stuck in unmountSuspended state during rapid state updates - **Radio Group**: - Fixed inconsistent application of `data-focus-visible` and `data-focus` attributes - **Splitter**: Fixed disabled splitter showing resize cursor and allowing dragging - **Tabs**: - Fixed tabs indicator position not updating when inactive tabs change size - **Tags Input**: Fixed issue where item delete trigger doesn't have `data-*` attached ## [5.28.0] - 2025-11-14 ### Added - **General**: Exported `InteractOutsideEvent`, `FocusOutsideEvent`, and `PointerDownOutsideEvent` types for better type safety - **Carousel**: - Added `Carousel.AutoplayIndicator` component for conditionally rendering content based on autoplay state - Added `Carousel.ProgressText` component for displaying current page progress (e.g., "1 / 5") - **Toast**: Exported `ToastOptions` and `ToastStoreProps` types for better type safety ### Changed - **useListCollection**: Updated `initialItems` to accept `readonly` arrays for better compatibility with immutable data patterns. ### Fixed - **Combobox**: - Fixed focus stealing in controlled open mode - Removed problematic `aria-hidden` behavior to allow interaction with other page elements ## [5.27.1] - 2025-11-02 ### Fixed - **Dialog, Popover**: Improved shadow DOM support for interact outside and focus trap detection - **Marquee**: Fixed Firefox flicker and added GPU acceleration - **Dialog**: Fixed layout shift issue when using `scrollbar-gutter: stable` in CSS - **Slider**: Fixed `onValueChangeEnd` callback not triggering for programmatic value changes ## [5.27.0] - 2025-11-01 ### Added - **Marquee** [New]: Initial release of marquee component for continuously scrolling content ### Fixed - **Angle Slider**: Resolved an issue where dragging the thumb from non-center positions caused unexpected value jumps. The thumb now maintains consistent positioning relative to the initial click point. - **Slider**: Fixed a problem where the thumb offset shifted dynamically during dragging, resulting in value jumps. The offset now remains constant from the pointer throughout the drag operation. - **Date Picker**: Resolved a crash in the range date picker occurring when users typed the end date first by implementing `null`/`undefined` checks for date property access. - **Radio Group**: Reverted to `offsetLeft`/`offsetTop` calculations to restore correct indicator positioning within scrollable container contexts. - **Tabs**: Reverted to `offsetLeft`/`offsetTop` calculations to fix indicator positioning issues in scrollable containers. - **Tour**: - Corrected improper effect cleanup procedures - Fixed wait step functionality - Added step validation on mount to verify configuration validity ## [5.26.2] - 2025-10-18 ### Fixed - **Angle Slider**: Fix accessibility violation where the slider thumb element lacked an accessible name. The thumb now supports `aria-label` and `aria-labelledby` props, and automatically falls back to the label element's ID for proper ARIA labeling. - **Select**: Fix accessibility violation where the required state was not set correctly to on the trigger. - **Tags Input**: Fix issue where entering a custom tag with combobox integration required pressing `Enter` twice. The tags-input now correctly handles custom values when the combobox has no highlighted item (`aria-activedescendant` is empty), allowing the tag to be added on the first `Enter` press. ## [5.26.1] - 2025-10-15 ### Fixed - **Checkbox** - Fix issue where setting initial checked state to `indeterminate` doesn't work - Ensure `api.checkedState` returns the correct checked state (`boolean | "indeterminate"`) - **Collapsible**: Fix issue where `dir` prop value was hardcoded to `ltr` instead of using the provided value - **Combobox**: Fix issue where controlled single-select combobox does not propagate its initial value to `inputValue` - **Listbox**: Fix issue where pressing Enter key when no highlighted item still calls `event.preventDefault()` - **Radio Group**: Refactor to use `getBoundingClientRect()` for precise indicator positioning - **Slider** - Fix issue where slider could stop abruptly when scrubbing thumb - Fix issue where range slider thumbs become stuck when dragged to the same position without `minStepsBetweenThumbs` - **Tabs**: Refactor to use `getBoundingClientRect()` for precise indicator positioning - **Tags Input**: Fix issue where `maxLength` doesn't apply to the edit input as well ## [5.26.0] - 2025-10-08 ### Added - **Collapsible**: Add support for `collapsedHeight` and `collapsedWidth` props to control the dimensions of the collapsible content when in its collapsed state. - **Focus Trap**: Allow elements referenced by `aria-controls` to be included in the trap scope. This makes it possible for menus, popovers, etc. to be portalled and work correctly. - **Pagination**: Add `getPageUrl` prop for generating `href` attributes when using pagination as links. ```ts const service = useMachine(pagination.machine, { type: 'link', getPageUrl: ({ page, pageSize }) => `/products?page=${page}&size=${pageSize}`, }) ``` - **Select**: Add `SelectRootComponentProps` type export for better component type composition. - **Listbox**: Add `ListboxRootComponentProps` type export for better component type composition. - **Combobox**: Add `ComboboxRootComponentProps` type export for better component type composition. - **TreeView**: - Add `TreeViewRootComponentProps` type export for better component type composition. - (Experimental) Add support for node renaming functionality: - Add `TreeViewNodeRenameInput` component for inline node label editing - Add `canRename` prop to control which nodes can be renamed - Add `onRenameStart`, `onBeforeRename`, and `onRenameComplete` callbacks for rename lifecycle - Add `CheckedChangeDetails`, `LoadChildrenErrorDetails`, `RenameStartDetails`, and `RenameCompleteDetails` type exports ### Fixed - **Scroll Area**: Fix RTL horizontal scrollbar positioning on Safari - **Slider**: Fix issue where slider continues dragging when disabled during drag operation. - **Switch**: Fix issue where `data-active` is inconsistently applied when `disabled` state changes at runtime ## [5.25.1] - 2025-09-27 ### Fixed - **Date Picker** - Fix issue where year range picker doesn't show the hovered range - Fix issue where quarter presets returns incorrect date - **FormatByte**: Add support for `unitSystem` property to allow changing between decimal (1000 bytes) and binary (1024 bytes) systems. - **Number Input**: When `formatOptions` is used (like `style: "currency"`), the cursor would jump to the end of the input when typing in the middle. The cursor now maintains its relative position during formatting changes. - **Pin Input**: Fix issue where using the keyboard shortcuts `Cmd+Backspace` and `Cmd+Delete` to delete text in pin inputs would insert "undefined" instead of clearing the field. - **Scroll Area**: Fix issue where resize tracking was not observing the root element, which caused the scrollbar to not update when the root element's size changed. ## [5.25.0] - 2025-09-16 ### Added - Added `mergeProps` utility for combining multiple props objects with proper event handler and className merging. - Added `createContext` utility for creating typed React contexts with improved DX. ```tsx import { createContext } from '@ark-ui/react/utils' ``` ### Fixed - **AngleSlider**: Export `angleSliderAnatomy` from the anatomy exports ## [5.24.1] - 2025-09-14 ### Fixed - **General**: Fix issue where `mergeProps` throws when `props` is `undefined` or `null` ## [5.24.0] - 2025-09-14 ### Added - **Combobox**: Add `alwaysSubmitOnEnter` prop to allow bypassing the default two-step behavior (Enter to close combobox, then Enter to submit form) and instead submit the form immediately on Enter press. This is useful for single-field autocomplete forms where Enter should submit the form directly. - **Dismissable**: Add support for layer types in dismissable layer stack. Layers can now be categorized as `dialog`, `popover`, `menu`, or `listbox`. This enables: - `data-nested` attribute on nested layers of the same type - `data-has-nested` attribute on parent layers with nested children of the same type - `--nested-layer-count` CSS variable indicating the number of nested layers of the same type ### Changed - **Hover Card**: Change default delay values for hover card to improve accessibility. - `openDelay`: from `700ms` to `600ms` - **Tooltip**: Change default delay values for tooltip to improve accessibility. [Learn more](https://www.nngroup.com/articles/timing-exposing-content) - `openDelay`: from `1000ms` to `400ms` - `closeDelay`: from `500ms` to `150ms` ### Removed - **TimePicker**: The TimePicker component has been removed from this release. This component was never part of the public API and was considered experimental. It had significant bugs and usability issues across all frameworks and locales, making it unsuitable for production use. **Migration**: We recommend building a custom time picker using the Select component for simple use cases, or implementing a time grid pattern for more complex scenarios. ### Fixed - **Editable**: Allow text selection in editable preview when `autoResize` is enabled Previously, when `autoResize` was set to `true`, the preview element had `userSelect: "none"` applied, preventing users from selecting text. This has been fixed by removing the `userSelect` style property. - **File Upload**: Fix regression where clicking the trigger doesn't open the file picker when used within the dropzone - **Menu**: - Fix issue where keyboard activation of menu items with `target="_blank"` would open two tabs - Fix issue where hovering a partially visible item with pointer causes it to scroll into view - **Tabs**: Fix issue where `ids` for `item` and `content` could not be customized - **Toast**: Allow creating a toast store without any arguments ## [5.23.0] - 2025-09-08 ### Added - **Field**: Add `data-required` attribute to `Field.Label` - **Select, Combobox, Listbox, TreeView**: Export `RootComponent` and `RootProviderComponent` types which are useful when building compositions that wrap the `Root` and `RootProvider` components and you still want type-safety for the collection. ### Fixed - **Menu**: Fix `Menu.ItemText` not working inside `Menu.TriggerItem` ```tsx import { Select } from '@ark-ui/react/select' import { styled } from 'styling-lib' const Root = styled(Select.Root) as Select.RootComponent<{}> ``` ## [5.22.0] - 2025-08-28 ### Added - **Combobox**: Add `ComboboxEmpty` component to display content when the combobox has no items - **Listbox**: Add `ListboxEmpty` component to display content when the listbox has no items - **Hover Card**: Add support for `disabled` prop ### Fixed - **Collection**: Fix issue where disabled items could be reached via typeahead - **Color Picker**: Fix issue where color picker was not working correctly in RTL mode - **Date Picker**: Fix issue where datepicker doesn't revert to a valid value when the input value exceeds the min/max and blurred - **Dismissable**: Expose `onRequestDismiss` custom event handler for event a parent layer requests the child layer to dismiss. If prevented via `event.preventDefault()`, the child layer will not dismiss when the parent layer is dismissed. - **Number Input** - Omit the input `pattern` when `formatOptions` is provided. This prevents native pattern validation from conflicting with formatted values (e.g., currency or percent). - Handle empty values consistently across all format options. - Add `data-scrubbing` attribute to the number input parts. - **Tags Input**: Fix issue where highlighted item doesn't clear when tabbing out of the input to an external button within the `control` part. - **Tooltip** - Set `closeOnPointerdown` to `false` when `closeOnClick` is set to `false` - Reduce bundle size by replacing `@zag-js/store` dependency with a lightweight store implementation. ## [5.21.0] - 2025-08-24 ### Added - **Hooks**: Add `useAsyncList` and `useCollator` hooks for managing asynchronous list operations and locale-aware string comparison - **Toast**: Export type definitions `ToastActionOptions`, `ToastPlacement`, `ToastPromiseOptions`, `ToastStatus`, `ToastStatusChangeDetails`, and `ToastType` ### Changed - **Fieldset** - Update Legend component to render as `div` instead of `legend` element for improved styling flexibility - Add `aria-labelledby` attribute to fieldset root for better accessibility by linking to legend ### Fixed - **Date Picker** - Clear hovered range state after completing range selection instead of waiting for pointer to leave the calendar area. - Fix issue where month and year select labels don't update correctly when using `min`/`max` constraints. - Expose `disabled` on `api.getMonths()` and `api.getYears()` results to indicate options out of range for current constraints. - **Listbox** - Fix issue where first enabled item should be highlighted by default when listbox receives focus and no item is currently highlighted. - Add `getElement` to `scrollToIndexFn` details - Track collection changes and clear `highlightedValue` if the item is no longer in the collection. - **Scroll Area** - Avoid detecting hover state from portalled descendants. - Add `data-dragging` attribute to scroll area parts. - **Select**: Add `getElement` to `scrollToIndexFn` details - **Combobox**: Add `getElement` to `scrollToIndexFn` details - **Tabs**: Fix inconsistent keyboard navigation where TabPanel intermittently receives focus before focusable elements ## [5.20.0] - 2025-08-20 ### Added - **Highlight Word**: Add `exactMatch` option that enables whole-word matching using regex word boundaries. ### Fixed - **Menu**: Fix context menu repositioning logic - **ScrollArea**: Add `data-hover` to scroll area ## [5.19.0] - 2025-08-18 ### Added - **ScrollArea [NEW]**: Add support for new scroll area component. ### Fixed - **ListCollection** - Avoid recomputing groups on every call to `at()` and `indexOf()` - Fixed bug in `find()` method (was checking `!= null` instead of `!== -1`) - **GridCollection**: Avoid recomputing rows on every call to `getRows()` - **Menu** - Add `data-state` attribute for context menu trigger - Fix context menu positioning bug where reopening at the same coordinates fails to reposition ## [5.18.4] - 2025-08-14 ### Fixed - **Listbox**: Add support for navigating grid collections - **Carousel**: - Fix an issue where the carousel would not update when `slideCount` or `autoplay` props change. - Fix an issue where `loop: false` was ignored when using autoplay. Now, the carousel will stop when it gets to the last slide. - **Date Picker**: Expose `data-inline` attribute on Content part to enable distinct styling for inline date pickers versus popover date pickers. - **Menu**: Fix issue where `onCheckedChange` could be called twice on checkbox or radio item - **Radio Group**: Fixed issue where arrow key navigation doesn't apply `data-focus-visible` on the newly focused item. - **TagsInput**: Export `InputValueChangeDetails` type ### Changed - **Async List**: Improve type inference for descriptors ## [5.18.3] - 2025-08-01 ### Fixed - **Factory**: Check if `children` is a valid React element before calling `Children.only()` - **Carousel**: Fix issue where controlled carousel ignores last slide ## [5.18.2] - 2025-07-26 ### Fixed - **Dialog** - Sync content `--layer-index` with positioner and backdrop - Decouple `trapFocus` from `modal` so it's possible to set `modal=false` and `trapFocus=true` ## [5.18.1] - 2025-07-23 ### Fixed - **Date Picker**: Fixed issue where hovered range was connect to selected values, when it shouldn't - **Tree View**: Fixed issue where tree view doesn't scroll into view when content overflows. ## [5.18.0] - 2025-07-22 ### Added - **Collection**: Add `useListSelection` hook for managing collection item selection with support for single/multiple selection modes ```jsx const collection = createListCollection({ items: ['React', 'Vue', 'Angular'] }) const selection = useListSelection({ collection }) // Check if item is selected const isSelected = selection.isSelected('React') // Select/deselect items selection.select('React') selection.toggle('Vue') ``` - **File Upload**: Add support for programmatically controlling the accepted files via `acceptedFiles` and `defaultAcceptedFiles` - **Signature Pad**: Add support for programmatically controlling the paths via `paths` and `defaultPaths` props. - **Date Picker**: Added hover range preview support for date picker range selection. Added `inHoveredRange`, `firstInHoveredRange`, and `lastInHoveredRange` properties to `DayTableCellState` with corresponding data attributes `data-in-hover-range`, `data-hover-range-start`, and `data-hover-range-end`. Hover range states are only active when not overlapping with actual selected range, enabling distinct styling for hover preview vs actual selection in range mode. ### Fixed - **Date Picker**: Fix date comparison issues when time components are involved. This resolves critical issues with date comparison operations when different date types (`CalendarDate`, `CalendarDateTime`, `ZonedDateTime`) are mixed, particularly in scenarios involving time components. ## [5.17.0] - 2025-07-18 ### Added - **Checkbox**: Add `CheckboxGroupProvider` component for external checkbox group state management ### Fixed - **Carousel**: Fix issue where full page carousel could trap scrolling - **ListCollection**:Export `UseListCollectionReturn` type - **TreeCollection**: Fix issue where the `filter` method completely deletes the children key from the node when there are no matching children - **Number Input**: Fix issue where default pattern does not allow negative numbers with decimal point - **File Upload** - Export `FileError`, `FileMimeType`, and `FileRejection` types - Fix issue where calling `api.setFiles` invokes validation with incorrect `acceptedFiles` - Fix issue where the browser might not be able to infer the mime type of a file due to limitations, drag source or security restrictions. As a fallback in the file validation logic, we now infer the mime type from the file extension. ## [5.16.1] - 2025-07-05 ### Fixed - **Combobox** - Expose `reason` to `onOpenChange` and `onInputValueChange` callbacks - Expose `api.clearHighlightedValue` function to clear highlighted value - **Date Picker** - Fix issue where datepicker errors when setting `selectionMode=range` and `minView=year` - Fix issue where `focusedValue` could not be fully controlled - **Toast**: Fix issue where toast `title` or `description` could not accept React element - **Listbox**: Select highlighted item only if it exists in the collection - **Progress**: Improve `valueAsString` formatting - **Select** - Select highlighted item only if it exists in the collection - Expose `api.clearHighlightedValue` function to clear highlighted value - **Tour**: Fix an issue where the `goto` function in `StepActionMap` doesn't work when passing step IDs (string) - **Tree View**: Expose `id` in the tree node state - **ClientOnly**: Support `children` as a function ## [5.16.0] - 2025-07-01 ### Added - **Color Picker**: Add support for `inline` prop to render color picker inline - **Date Picker**: Add support for `inline` prop to render the date calendar inline ### Fixed - **Color Picker**: Auto-prefix Hex values with `#` if missing when using the `hex` channel input - **Menu**: Fix interaction outside detection for focusable context trigger - **Tree View**: Improve support for rendering tree items as links ## [5.15.4] - 2025-06-27 ### Fixed - **Combobox, Select, Listbox**: Fix issue where rehydrating `defaultValue` or `value` after fetching items doesn't update the `valueAsString` ## [5.15.3] - 2025-06-27 ### Fixed - **Tree View**: Fix tree traversal for querying last node ## [5.15.2] - 2025-06-26 ### Fixed - **Date Picker**: Fix issue with keyboard selection where setting unavailable date causes month view to behave differently from clicking with mouse - **Toast**: Fix issue where app crashes when `toaster.promise` is called without loading option. The `loading` option is now required. A warning will be logged if it is not provided - **Tree View** - Fix issue where clicking a branch with indeterminate state doesn't check its child nodes - Remove `aria-busy` attribute from branch trigger when not loading children - Expose node details in `onExpandChange`, `onSelectionChange` and `onFocusChange` - **Angle Slider**: Fix issue where scrubbing doesn't feel smooth on touch devices - **Timer**: - Fix issue where timer could continue beyond `targetMs` when window is not visible - Add validation to ensure `startMs` and `targetMs` are configured correctly - Fix `progressPercent` calculation for countdown timers ## [5.15.1] - 2025-06-23 ### Fixed - **Listbox**: Fix issue where `Listbox.ItemContext` was not exported ## [5.15.0] - 2025-06-23 ### Added - **Tree View** - Add support for checkbox state for checkbox trees via `defaultCheckedValue`, `checkedValue`, `onCheckedChange` props - Add callback for when `loadChildren` fails via `onLoadChildrenError` prop ### Fixed - **Progress** - Fix issue where setting orientation to `vertical` don't work - Fix issue where setting `defaultValue` to `null` doesn't show indeterminate state ## [5.14.2] - 2025-06-19 ### Fixed - **General**: Ensure pointerdown or click event handlers only execute when the main button is clicked - **Tree View**: Exported `TreeViewNodeState` and `TreeViewNodeProps` types from `@zag-js/tree-view` ### Changed - **Collection**: Improve the APIs around `tree.flatten(...)` and `flattenedToTree` to ensure the original node properties are preserved. > Previously, `tree.flatten()` would return an array of objects with `value` and `label` stripping out the original > node properties. ```ts const tree = new TreeCollection({ rootNode: { value: 'ROOT', children: [{ value: 'child1' }, { value: 'child2' }], }, }) const flattened = tree.flatten() const reconstructed = flattenedToTree(flattened) console.log(reconstructed.rootNode) // { // value: "ROOT", // children: [{ value: "child1" }, { value: "child2" }], // } ``` ## [5.14.1] - 2025-06-17 ### Fixed - **Popover**: Fixed issue where `onOpenChange` could be called twice when controlled - **File Utils**: Improved `downloadFile` function to handle webview scenarios - **Combobox**: - Fixed issue where `onInputValueChange` could be called twice when selecting an item - Fixed issue where combobox with `allowCustomValue: true` used within in a form requires two enter keypress to submit ## [5.14.0] - 2025-06-10 ### Added - **Editable**: Added support for `activationMode=none` - **Collection** - Exposed `copy` method - Added support for `getParentNodes` to accept a value or index path ### Fixed - **Collection**: Fixed issue where entrypoint `@ark-ui/react/collection` was not working as expected - **Carousel**: Fixed issue where carousel crashes when `slidesPerPage` is 0 - **File Upload**: Prevented `undefined` in `acceptedFiles` when no files accepted - **Select**: Fixed issue where highlighted item could be cleared when navigating up/down the list with keyboard - **Tabs**: Fixed issue where tabs with links should not trigger tab change upon cmd/middle click - **Menu**: Fixed issue where `Menu.ItemText` could not be used with `Menu.Item` ## [5.13.0] - 2025-06-07 ### Added - **Collection**: Added new `useListCollection` hook to create a dynamic list collection. ### Fixed - **Progress**: Exported `ProgressValueChangeDetails` and `ProgressValueTranslationDetails` types from `@zag-js/progress` ## [5.12.0] - 2025-06-05 ### Added - **Tree View**: Added support for lazy loading node children. To use this, you need to provide: - `loadChildren` is a function that is used to load the children of a node. - `onLoadChildrenComplete` is a callback that is called when the children of a node are loaded. Used to update the tree collection. - Add `childrenCount` to the node object to indicate the number of children. ### Fixed - **Slider** - Fixed issue where `Shift` + `ArrowRight` set value to `0` instead of `max` when step is too large (e.g. `20`) - Fixed issue where `onValueChangeEnd` doesn't return the latest value when dragging very fast ## [5.11.0] - 2025-05-30 ### Added - **File Upload**: Added support for transforming uploaded files via `transformFiles` context property. ### Fixed - **Slider**: Fixed issue where `minStepsBetweenThumbs` isn't computed correctly when interacting with pointer or keyboard. ## [5.10.0] - 2025-05-29 ### Added - **[NEW] Password Input**: Added `PasswordInput` component for creating password inputs ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' export const Basic = () => ( Password }> ) ``` - **Select**: Added `onSelect` callback that gets fired when an item is selected via keyboard/mouse. ### Fixed - **Color Picker**: Fixed issue where value change end event is invoked when committing via an input. - **Toast**: Fixed issue where calling `toast.remove()` without an id shows a TypeScript error. - **Field**: Fixed issue where helper text and error text could not be detected in shadow DOM environments. ## [5.9.2] - 2025-05-24 ### Fixed - **Collection**: Export `CollectionOptions`, `TreeCollectionOptions`, `GridCollectionOptions` types. - **Carousel** - Fixed issue where focusing on carousel region and navigating with keyboard doesn't work as expected - Fixed issue when `allowMouseDrag` is set where carousel no longer snaps after mouse interaction - **Combobox**: Fixed issue where `onInputValueChange` doesn't get called when `autoFocus` is set to `true` - **Slider**: Fixed issue where slider could throw a error when rendered in an popover or dialog - **Tour**: Fixed issue where calling `api.start()` with a step id doesn't work as expected ## [5.9.1] - 2025-05-12 ### Fixed - **Combobox**: Fixed issue where `focusable` prop was not being applied to the trigger element. - **Collection**: Fixed issue where `getNextValue` and `getPreviousValue` doesn't work as expected when `groupBy` is used. ## [5.9.0] - 2025-05-05 ### Added - **Locale**: Added `useFilter` hook to filter data based on the current locale. - **Format**: Added `FormatRelativeTime` component for formatting relative time. ## [5.8.0] - 2025-05-01 ### Added - **Date Picker**: Added support for `outsideDaySelectable` prop to allow selecting days outside the current month (on the same visible date range) ### Fixed - **Collapsible**: Fixed issue in React.js <= v18.x where collapse animation might not work as expected ## [5.7.0] - 2025-04-25 ### Added - **[NEW] Listbox**: Introduced the `Listbox` component for selecting a single or multiple items from a list. See the [documentation](https://ark-ui.com/docs/components/listbox) for details. - Improved support for grouping collection items. Check the `Listbox`, `Select` or `Combobox` documentation for more details. ### Changed - Added `package.json` to `exports` for improved compatibility with tools like Vite. ## [5.6.0] - 2025-04-15 ### Added - **[NEW] AngleSlider**: Introduced the `AngleSlider` component for selecting an angle. See the [documentation](https://ark-ui.com/docs/components/angle-slider) for details. - **[NEW] FloatingPanel**: Introduced the `FloatingPanel` component for creating floating windows. See the [documentation](https://ark-ui.com/docs/components/floating-panel) for details. - **Toast**: Added toast queuing when the max limit is reached: - New toasts were queued instead of dropped - Queued toasts were shown when space became available - Queue cleared when all toasts were removed - **Combobox**: - Fallbacked to the trigger element as the positioning anchor - Added `data-empty` attribute to indicate an empty listbox or content ## [5.5.0] - 2025-04-05 ### Added - **Presence**: Added support for skipping the initial animation when the component is mounted. This can be used in all disclosure components (e.g., `Dialog`, `DatePicker`, `Menu` etc). ### Fixed - **Tabs**: Fixed issue where tabs indicator animation behaves inconsistently. - **Date Picker** - Fixed issue where datepicker throws error when navigating month view. - Fixed issue where range selection doesn't reset correctly when clicking the same start date. - **Disclosure Components** - Fixed issue where pointerdown outside doesn't work consistently on mobile devices. - Improved pointerdown outside click detection in shadow DOM environments. ## [5.4.0] - 2025-03-28 ### Added - **Slider** - Add support for `origin: end` to align the thumb to the end of the track. - Expose `thumbSize` as CSS variables in the root element. Can be useful for styling the slider. - **Menu** - Added `onSelect` event to the `Menu.Item` component. ### Fixed - Ensured each component's state machine starts before processing events. - **HoverCard, ColorPicker**: Added missing `tabIndex` for better dialog support. - **Menu**: Assigned unique IDs to menu items to improve accessibility and HTML validation. ## [5.3.1] - 2025-03-24 ### Fixed - Fixed an issue where a function was imported from a package that wasn't declared as a dependency. ## [5.3.0] - 2025-03-24 ### Added - **Collapsible**: Added an `Indicator` part to display whether the collapsible was open or closed. - **ColorPicker**: Added support for formatting the `ValueText` component. ```tsx // #ff0000 ``` ### Fixed - **Combobox**: Fixed an issue where `onOpenChange` was called with the same `open` value. - **DownloadTrigger**: Added the missing `use client` directive. - **Splitter**: Fixed an issue where `onResizeStart` and `onResizeEnd` callbacks weren't triggered during keyboard interactions. ## [5.2.0] - 2025-03-22 ### Added - **[NEW] DownloadTrigger**: Added Component for downloading a blob or file, whether retrieved synchronously or asynchronously. ```tsx import { DownloadTrigger } from '@ark-ui/react/download-trigger' export const DownloadImage = () => { async function fetchImage() { const response = await fetch('https://picsum.photos/200/300') return response.blob() } return ( Download Image ) } ``` ### Changed - **NumberInput**: Set the default step to `0.01` when `formatOptions.style` was set to `percent`. - **[Breaking] Splitter**: Redesigned splitter machine to support more use cases and improve DX. Check out the [Splitter](https://ark-ui.com/docs/components/splitter) documentation for more details. ### Fixed - **Toast**: Fixed issue where setting `offsets` to `undefined` caused the machine to throw. - **Select**: Fixed issue where select `valueAsString` lost reactivity. ## [5.1.0] - 2025-03-17 ### Added - Added support for a cleanup function in `ref`. ### Fixed - **Field**: Exported the missing `useField` hook. - **NumberInput**: `onValueChange` correctly received `valueAsNumber`. - **Slider**: Thumbs initialized correctly when `min` was set to a non-zero value. ## [5.0.1] - 2025-03-11 ### Fixed - Effects now flush synchronously instead of using a microtask. - **Checkbox**: `data-invalid` is no longer set when `invalid` is `false`. - **Combobox**: Fixed unexpected cursor movement when editing input. - **PinInput**: OTP SMS autofill now works as expected. - **RatingGroup**: Fixed incorrect focus placement on the label. - **TagsInput**: Improved caret detection to prevent unintended tag removal. - **Timer** - Fixed slowdown when switching tabs/windows. - Changed default `interval` from `250` to `1000`. ## [5.0.0] - 2025-03-06 Ark UI just got a major performance boost! 🚀 ### What’s new in v5? - **Blazing-fast performance** – Every component runs smoother and renders faster. - **Smaller bundle size** – Leaner components and adapters for a more efficient build. We made this happen by using React’s native reactive primitives instead of external stores. In our stress tests with **10,000 components**, Ark v5 delivered **1.5x–4x** better performance across the board. ![Performance comparison showing Ark v5 is 1.5x-4x faster than other libraries](./v5.svg) ### A quick note on tests Most component updates are non-breaking, but due to this change, some tests may need adjustments. For example: ```jsx // Before it('should open by default', () => { render() expect(screen.getByRole('dialog')).toBeInTheDocument() }) // After it('should open by default', async () => { render() expect(await screen.findByRole('dialog')).toBeInTheDocument() }) ``` #### Added - **Carousel**: ⚠️ Breaking change: Added required prop `slideCount` to `Carousel.Root` component. - **Clipboard**: Added `onValueChange` and `defaultValue` props. - **ColorPicker**: Added `defaultFormat` prop. - **Combobox**: Added `defaultHighlightedValue` and `defaultInputValue` props. - **DatePicker**: Added `defaultFocusedValue` prop, `getViewProps`, and `visibleRangeText`. - **HoverCard**: Expanded interaction handlers. - **Menu**: Added `defaultHighlightedValue` prop. - **Pagination**: Added `defaultPageSize` prop. - **PinInput**: Added `count` prop for better SSR aria-label. - **Progress**: Added `locale` and `formatOptions` props. - **QrCode**: Added `pixelSize` prop. - **Select**: Added `defaultHighlightedValue` prop. - **TagsInput**: Added `defaultInputValue` prop. - **Toggle**: Reintroduced toggle machine. #### Fixed - **Accordion**: Fixed issue in Safari where clicking triggers didn't show content. - **Avatar**: Fixed `api.setSrc` not working. - **Carousel**: Fixed pagination sync and initial page issues. - **File Upload**: Fixed drag-and-drop when `directory: true`. - **Menu**: Fixed context menu positioning not updating on right-click. - **Number Input**: Fixed `value` prop not being consumed. - **Pin Input**: Fixed focus warnings and editing issues. - **Progress**: Allowed more precise (decimal) values. - **Radio Group, Switch**: Improved focus behavior in Safari. - **Select**: Fixed regression where `multiple: true` didn't work. - **Steps**: Ensured ARIA attributes use valid values and wrapped `
              1. ` elements correctly within `
                  ` or `
                    `. - **Textarea**: Fixed `ResizeObserver` warning. - **Timer**: Fixed stopping issue when switching tabs; resolved issue where `action` prop was passed to `ActionTrigger`. - **Toast**: Fixed keyboard navigation skipping close button. - **Toggle Group**: Fixed `data-focus` not being removed on blur. --- # About Ark UI (REACT) ## Motivation Most popular UI component libraries are designed to work with a specific JavaScript framework. Building UI components that work across different JavaScript frameworks presents significant challenges for organizations working with diverse technology stacks. ## Solution Ark UI provides components for building complex, interactive, and accessible user interfaces across multiple JavaScript frameworks. To achieve this, Ark UI is built on top of [Zag.js](https://zagjs.com), a UI component library powered by Finite State Machines. Check out the architecture diagram below for a high-level overview. ## Team Ark UI is built and maintained by the team behind [Chakra UI](https://chakra-ui.com). - [Segun Adebayo](https://github.com/segunadebayo) - Creator of Chakra UI and Zag.js - [Christian Busch](https://github.com/cschroeter) - Core maintainer - [Esther Agbaje](https://github.com/estheragbaje) - Developer Advocate ## Acknowledgments We are committed to open source and the power of collaboration. Our work has been inspired by numerous projects and individuals who continually drive us to innovate and improve. - [Zag.js](https://zagjs.com/) - The foundation of this project - [Park UI](https://park-ui.com) - For providing the styled component demos featured in this project - [Radix Vue](https://www.radix-vue.com/) - For `useForwardPropsEmits`, which we re-export to build closed Vue components ## License This project is licensed under the terms of the [MIT license](https://github.com/chakra-ui/ark/blob/main/LICENSE). --- # About Ark UI (VUE) ## Motivation Most popular UI component libraries are designed to work with a specific JavaScript framework. Building UI components that work across different JavaScript frameworks presents significant challenges for organizations working with diverse technology stacks. ## Solution Ark UI provides components for building complex, interactive, and accessible user interfaces across multiple JavaScript frameworks. To achieve this, Ark UI is built on top of [Zag.js](https://zagjs.com), a UI component library powered by Finite State Machines. Check out the architecture diagram below for a high-level overview. ## Team Ark UI is built and maintained by the team behind [Chakra UI](https://chakra-ui.com). - [Segun Adebayo](https://github.com/segunadebayo) - Creator of Chakra UI and Zag.js - [Christian Busch](https://github.com/cschroeter) - Core maintainer - [Esther Agbaje](https://github.com/estheragbaje) - Developer Advocate ## Acknowledgments We are committed to open source and the power of collaboration. Our work has been inspired by numerous projects and individuals who continually drive us to innovate and improve. - [Zag.js](https://zagjs.com/) - The foundation of this project - [Park UI](https://park-ui.com) - For providing the styled component demos featured in this project - [Radix Vue](https://www.radix-vue.com/) - For `useForwardPropsEmits`, which we re-export to build closed Vue components ## License This project is licensed under the terms of the [MIT license](https://github.com/chakra-ui/ark/blob/main/LICENSE). --- # About Ark UI (SVELTE) ## Motivation Most popular UI component libraries are designed to work with a specific JavaScript framework. Building UI components that work across different JavaScript frameworks presents significant challenges for organizations working with diverse technology stacks. ## Solution Ark UI provides components for building complex, interactive, and accessible user interfaces across multiple JavaScript frameworks. To achieve this, Ark UI is built on top of [Zag.js](https://zagjs.com), a UI component library powered by Finite State Machines. Check out the architecture diagram below for a high-level overview. ## Team Ark UI is built and maintained by the team behind [Chakra UI](https://chakra-ui.com). - [Segun Adebayo](https://github.com/segunadebayo) - Creator of Chakra UI and Zag.js - [Christian Busch](https://github.com/cschroeter) - Core maintainer - [Esther Agbaje](https://github.com/estheragbaje) - Developer Advocate ## Acknowledgments We are committed to open source and the power of collaboration. Our work has been inspired by numerous projects and individuals who continually drive us to innovate and improve. - [Zag.js](https://zagjs.com/) - The foundation of this project - [Park UI](https://park-ui.com) - For providing the styled component demos featured in this project - [Radix Vue](https://www.radix-vue.com/) - For `useForwardPropsEmits`, which we re-export to build closed Vue components ## License This project is licensed under the terms of the [MIT license](https://github.com/chakra-ui/ark/blob/main/LICENSE). --- # About Ark UI (SOLID) ## Motivation Most popular UI component libraries are designed to work with a specific JavaScript framework. Building UI components that work across different JavaScript frameworks presents significant challenges for organizations working with diverse technology stacks. ## Solution Ark UI provides components for building complex, interactive, and accessible user interfaces across multiple JavaScript frameworks. To achieve this, Ark UI is built on top of [Zag.js](https://zagjs.com), a UI component library powered by Finite State Machines. Check out the architecture diagram below for a high-level overview. ## Team Ark UI is built and maintained by the team behind [Chakra UI](https://chakra-ui.com). - [Segun Adebayo](https://github.com/segunadebayo) - Creator of Chakra UI and Zag.js - [Christian Busch](https://github.com/cschroeter) - Core maintainer - [Esther Agbaje](https://github.com/estheragbaje) - Developer Advocate ## Acknowledgments We are committed to open source and the power of collaboration. Our work has been inspired by numerous projects and individuals who continually drive us to innovate and improve. - [Zag.js](https://zagjs.com/) - The foundation of this project - [Park UI](https://park-ui.com) - For providing the styled component demos featured in this project - [Radix Vue](https://www.radix-vue.com/) - For `useForwardPropsEmits`, which we re-export to build closed Vue components ## License This project is licensed under the terms of the [MIT license](https://github.com/chakra-ui/ark/blob/main/LICENSE). --- # Styling (REACT) ## Overview Ark UI is a headless component library that works with any styling solution. It provides functional styles for elements like popovers for positioning, while leaving presentation styles up to you. Some components also expose CSS variables that can be used for styling or animations. > **Tip:** Looking for a ready-to-use solution? Checkout [Park UI](https://park-ui.com) for a collection of pre-designed > styles based on Ark UI components. ### Data Attributes Ark UI components use `data-scope` and `data-part` attributes to target specific elements within a component. Interactive components often include `data-*` attributes to indicate their state. For example, here's what an open accordion item looks like: ```html
                    ``` For more details on each component's data attributes, refer to their respective documentation. ## Styling with CSS When styling components with CSS, you can target the data attributes assigned to each component part for easy customization. ### Styling a Part To style a specific component part, target its `data-scope` and `data-part` attributes: ```css [data-scope='accordion'][data-part='item'] { border-bottom: 1px solid #e5e5e5; } ``` ### Styling a State To style a component based on its state, use the `data-state` attribute: ```css [data-scope='accordion'][data-part='item'][data-state='open'] { background-color: #f5f5f5; } ``` > **Tip:** If you prefer using classes instead of data attributes, utilize the `class` or `className` prop to add custom > classes to Ark UI components. ### Class Names If you prefer using classes instead of data attributes, utilize `class` or `className` prop to add custom classes to Ark UI components. Pass a class: ```jsx {/* … */} ``` Then use in styles: ```css .AccordionItem { border-bottom: 1px solid #e5e5e5; &[data-state='open'] { background-color: #f5f5f5; } } ``` ## Styling with Panda CSS [Panda CSS](https://panda-css.com) is a best-in-class CSS-in-JS framework that integrates seamlessly with Ark UI, providing an efficient styling solution. ### Styling a part Panda offers various ways to write styles, but in the context of Ark UI, we recommend using the `defineSlotRecipe` function to style a component with its different parts and variants. > **Important:** When importing anatomy objects, we recommend using the `@ark-ui//anatomy` entrypoint (e.g., > `@ark-ui/react/anatomy`) instead of the main package export to avoid potential build and import errors. ```ts import { accordionAnatomy } from '@ark-ui/react/anatomy' import { defineSlotRecipe } from '@pandacss/dev' export const accordionStyles = defineSlotRecipe({ className: 'accordion', slots: accordionAnatomy.keys(), base: { item: { borderBottom: '1px solid #e5e5e5', }, }, defaultVariants: {}, variants: {}, }) ``` ### Styling a state To style a component based on its state, you can use built in [conditions](https://panda-css.com/docs/customization/conditions) in Panda CSS. ```ts import { accordionAnatomy } from '@ark-ui/react/anatomy' import { defineSlotRecipe } from '@pandacss/dev' export const accordionStyles = defineSlotRecipe({ className: 'accordion', slots: accordionAnatomy.keys(), base: { item: { borderBottom: '1px solid {colors.gray.300}', _open: { // [!code highlight] backgroundColor: 'gray.100', }, }, }, defaultVariants: {}, variants: {}, }) ``` ## Styling with Tailwind CSS [Tailwind CSS](https://tailwindcss.com/) is a utility-first CSS framework providing a flexible way to style your components. ### Styling a Part To style a part, apply classes directly to the parts using either `class` or `className`, depending on the JavaScript framework. ```jsx {/* … */} ``` ### Styling a State Leverage Tailwind CSS's variant selector to style a component based on its data-state attribute. ```jsx {/* … */} ``` --- # Styling (VUE) ## Overview Ark UI is a headless component library that works with any styling solution. It provides functional styles for elements like popovers for positioning, while leaving presentation styles up to you. Some components also expose CSS variables that can be used for styling or animations. > **Tip:** Looking for a ready-to-use solution? Checkout [Park UI](https://park-ui.com) for a collection of pre-designed > styles based on Ark UI components. ### Data Attributes Ark UI components use `data-scope` and `data-part` attributes to target specific elements within a component. Interactive components often include `data-*` attributes to indicate their state. For example, here's what an open accordion item looks like: ```html
                    ``` For more details on each component's data attributes, refer to their respective documentation. ## Styling with CSS When styling components with CSS, you can target the data attributes assigned to each component part for easy customization. ### Styling a Part To style a specific component part, target its `data-scope` and `data-part` attributes: ```css [data-scope='accordion'][data-part='item'] { border-bottom: 1px solid #e5e5e5; } ``` ### Styling a State To style a component based on its state, use the `data-state` attribute: ```css [data-scope='accordion'][data-part='item'][data-state='open'] { background-color: #f5f5f5; } ``` > **Tip:** If you prefer using classes instead of data attributes, utilize the `class` or `className` prop to add custom > classes to Ark UI components. ### Class Names If you prefer using classes instead of data attributes, utilize `class` or `className` prop to add custom classes to Ark UI components. Pass a class: ```jsx {/* … */} ``` Then use in styles: ```css .AccordionItem { border-bottom: 1px solid #e5e5e5; &[data-state='open'] { background-color: #f5f5f5; } } ``` ## Styling with Panda CSS [Panda CSS](https://panda-css.com) is a best-in-class CSS-in-JS framework that integrates seamlessly with Ark UI, providing an efficient styling solution. ### Styling a part Panda offers various ways to write styles, but in the context of Ark UI, we recommend using the `defineSlotRecipe` function to style a component with its different parts and variants. > **Important:** When importing anatomy objects, we recommend using the `@ark-ui//anatomy` entrypoint (e.g., > `@ark-ui/react/anatomy`) instead of the main package export to avoid potential build and import errors. ```ts import { accordionAnatomy } from '@ark-ui/react/anatomy' import { defineSlotRecipe } from '@pandacss/dev' export const accordionStyles = defineSlotRecipe({ className: 'accordion', slots: accordionAnatomy.keys(), base: { item: { borderBottom: '1px solid #e5e5e5', }, }, defaultVariants: {}, variants: {}, }) ``` ### Styling a state To style a component based on its state, you can use built in [conditions](https://panda-css.com/docs/customization/conditions) in Panda CSS. ```ts import { accordionAnatomy } from '@ark-ui/react/anatomy' import { defineSlotRecipe } from '@pandacss/dev' export const accordionStyles = defineSlotRecipe({ className: 'accordion', slots: accordionAnatomy.keys(), base: { item: { borderBottom: '1px solid {colors.gray.300}', _open: { // [!code highlight] backgroundColor: 'gray.100', }, }, }, defaultVariants: {}, variants: {}, }) ``` ## Styling with Tailwind CSS [Tailwind CSS](https://tailwindcss.com/) is a utility-first CSS framework providing a flexible way to style your components. ### Styling a Part To style a part, apply classes directly to the parts using either `class` or `className`, depending on the JavaScript framework. ```jsx {/* … */} ``` ### Styling a State Leverage Tailwind CSS's variant selector to style a component based on its data-state attribute. ```jsx {/* … */} ``` --- # Styling (SVELTE) ## Overview Ark UI is a headless component library that works with any styling solution. It provides functional styles for elements like popovers for positioning, while leaving presentation styles up to you. Some components also expose CSS variables that can be used for styling or animations. > **Tip:** Looking for a ready-to-use solution? Checkout [Park UI](https://park-ui.com) for a collection of pre-designed > styles based on Ark UI components. ### Data Attributes Ark UI components use `data-scope` and `data-part` attributes to target specific elements within a component. Interactive components often include `data-*` attributes to indicate their state. For example, here's what an open accordion item looks like: ```html
                    ``` For more details on each component's data attributes, refer to their respective documentation. ## Styling with CSS When styling components with CSS, you can target the data attributes assigned to each component part for easy customization. ### Styling a Part To style a specific component part, target its `data-scope` and `data-part` attributes: ```css [data-scope='accordion'][data-part='item'] { border-bottom: 1px solid #e5e5e5; } ``` ### Styling a State To style a component based on its state, use the `data-state` attribute: ```css [data-scope='accordion'][data-part='item'][data-state='open'] { background-color: #f5f5f5; } ``` > **Tip:** If you prefer using classes instead of data attributes, utilize the `class` or `className` prop to add custom > classes to Ark UI components. ### Class Names If you prefer using classes instead of data attributes, utilize `class` or `className` prop to add custom classes to Ark UI components. Pass a class: ```jsx {/* … */} ``` Then use in styles: ```css .AccordionItem { border-bottom: 1px solid #e5e5e5; &[data-state='open'] { background-color: #f5f5f5; } } ``` ## Styling with Panda CSS [Panda CSS](https://panda-css.com) is a best-in-class CSS-in-JS framework that integrates seamlessly with Ark UI, providing an efficient styling solution. ### Styling a part Panda offers various ways to write styles, but in the context of Ark UI, we recommend using the `defineSlotRecipe` function to style a component with its different parts and variants. > **Important:** When importing anatomy objects, we recommend using the `@ark-ui//anatomy` entrypoint (e.g., > `@ark-ui/react/anatomy`) instead of the main package export to avoid potential build and import errors. ```ts import { accordionAnatomy } from '@ark-ui/react/anatomy' import { defineSlotRecipe } from '@pandacss/dev' export const accordionStyles = defineSlotRecipe({ className: 'accordion', slots: accordionAnatomy.keys(), base: { item: { borderBottom: '1px solid #e5e5e5', }, }, defaultVariants: {}, variants: {}, }) ``` ### Styling a state To style a component based on its state, you can use built in [conditions](https://panda-css.com/docs/customization/conditions) in Panda CSS. ```ts import { accordionAnatomy } from '@ark-ui/react/anatomy' import { defineSlotRecipe } from '@pandacss/dev' export const accordionStyles = defineSlotRecipe({ className: 'accordion', slots: accordionAnatomy.keys(), base: { item: { borderBottom: '1px solid {colors.gray.300}', _open: { // [!code highlight] backgroundColor: 'gray.100', }, }, }, defaultVariants: {}, variants: {}, }) ``` ## Styling with Tailwind CSS [Tailwind CSS](https://tailwindcss.com/) is a utility-first CSS framework providing a flexible way to style your components. ### Styling a Part To style a part, apply classes directly to the parts using either `class` or `className`, depending on the JavaScript framework. ```jsx {/* … */} ``` ### Styling a State Leverage Tailwind CSS's variant selector to style a component based on its data-state attribute. ```jsx {/* … */} ``` --- # Styling (SOLID) ## Overview Ark UI is a headless component library that works with any styling solution. It provides functional styles for elements like popovers for positioning, while leaving presentation styles up to you. Some components also expose CSS variables that can be used for styling or animations. > **Tip:** Looking for a ready-to-use solution? Checkout [Park UI](https://park-ui.com) for a collection of pre-designed > styles based on Ark UI components. ### Data Attributes Ark UI components use `data-scope` and `data-part` attributes to target specific elements within a component. Interactive components often include `data-*` attributes to indicate their state. For example, here's what an open accordion item looks like: ```html
                    ``` For more details on each component's data attributes, refer to their respective documentation. ## Styling with CSS When styling components with CSS, you can target the data attributes assigned to each component part for easy customization. ### Styling a Part To style a specific component part, target its `data-scope` and `data-part` attributes: ```css [data-scope='accordion'][data-part='item'] { border-bottom: 1px solid #e5e5e5; } ``` ### Styling a State To style a component based on its state, use the `data-state` attribute: ```css [data-scope='accordion'][data-part='item'][data-state='open'] { background-color: #f5f5f5; } ``` > **Tip:** If you prefer using classes instead of data attributes, utilize the `class` or `className` prop to add custom > classes to Ark UI components. ### Class Names If you prefer using classes instead of data attributes, utilize `class` or `className` prop to add custom classes to Ark UI components. Pass a class: ```jsx {/* … */} ``` Then use in styles: ```css .AccordionItem { border-bottom: 1px solid #e5e5e5; &[data-state='open'] { background-color: #f5f5f5; } } ``` ## Styling with Panda CSS [Panda CSS](https://panda-css.com) is a best-in-class CSS-in-JS framework that integrates seamlessly with Ark UI, providing an efficient styling solution. ### Styling a part Panda offers various ways to write styles, but in the context of Ark UI, we recommend using the `defineSlotRecipe` function to style a component with its different parts and variants. > **Important:** When importing anatomy objects, we recommend using the `@ark-ui//anatomy` entrypoint (e.g., > `@ark-ui/react/anatomy`) instead of the main package export to avoid potential build and import errors. ```ts import { accordionAnatomy } from '@ark-ui/react/anatomy' import { defineSlotRecipe } from '@pandacss/dev' export const accordionStyles = defineSlotRecipe({ className: 'accordion', slots: accordionAnatomy.keys(), base: { item: { borderBottom: '1px solid #e5e5e5', }, }, defaultVariants: {}, variants: {}, }) ``` ### Styling a state To style a component based on its state, you can use built in [conditions](https://panda-css.com/docs/customization/conditions) in Panda CSS. ```ts import { accordionAnatomy } from '@ark-ui/react/anatomy' import { defineSlotRecipe } from '@pandacss/dev' export const accordionStyles = defineSlotRecipe({ className: 'accordion', slots: accordionAnatomy.keys(), base: { item: { borderBottom: '1px solid {colors.gray.300}', _open: { // [!code highlight] backgroundColor: 'gray.100', }, }, }, defaultVariants: {}, variants: {}, }) ``` ## Styling with Tailwind CSS [Tailwind CSS](https://tailwindcss.com/) is a utility-first CSS framework providing a flexible way to style your components. ### Styling a Part To style a part, apply classes directly to the parts using either `class` or `className`, depending on the JavaScript framework. ```jsx {/* … */} ``` ### Styling a State Leverage Tailwind CSS's variant selector to style a component based on its data-state attribute. ```jsx {/* … */} ``` --- # Composition (REACT) ## The asChild Prop In Ark UI, the `asChild` prop lets you integrate custom components, ensuring consistent styling and behavior while promoting flexibility and reusability. All Ark components that render a DOM element accept the `asChild` prop. Here's an example using `asChild` to integrate a custom `Button` component within a `Popover`: In this example, the `asChild` prop allows the `Button` to be used as the trigger for the `Popover`, inheriting its behaviors from Popover.Trigger. ## The Ark Factory You can use the `ark` factory to create your own elements that work just like Ark UI components. This will produce the following HTML: ```html Ark UI ``` ## ID Composition When composing components that need to work together, share IDs between them using the `ids` prop for proper accessibility and interaction. ```tsx import { Avatar } from '@ark-ui/react/avatar' import { Tooltip } from '@ark-ui/react/tooltip' import { useId } from 'react' export const TooltipWithAvatar = () => { const id = useId() return ( SA Segun Adebayo is online ) } ``` Both components share the same `id` through their `ids` props, creating proper accessibility bindings, `aria-*` attributes and interaction behavior. ## Limitations When using the `asChild` prop, ensure you pass only a single child element. Passing multiple children may cause rendering issues. Certain components, such as `Checkbox.Root` or `RadioGroup.Item`, have specific requirements for their child elements. For instance, they may require a label element as a child. If you change the underlying element type, ensure it remains accessible and functional. --- # Composition (VUE) ## The asChild Prop In Ark UI, the `asChild` prop lets you integrate custom components, ensuring consistent styling and behavior while promoting flexibility and reusability. All Ark components that render a DOM element accept the `asChild` prop. Here's an example using `asChild` to integrate a custom `Button` component within a `Popover`: In this example, the `asChild` prop allows the `Button` to be used as the trigger for the `Popover`, inheriting its behaviors from Popover.Trigger. ## The Ark Factory You can use the `ark` factory to create your own elements that work just like Ark UI components. This will produce the following HTML: ```html Ark UI ``` ## ID Composition When composing components that need to work together, share IDs between them using the `ids` prop for proper accessibility and interaction. ```tsx import { Avatar } from '@ark-ui/react/avatar' import { Tooltip } from '@ark-ui/react/tooltip' import { useId } from 'react' export const TooltipWithAvatar = () => { const id = useId() return ( SA Segun Adebayo is online ) } ``` Both components share the same `id` through their `ids` props, creating proper accessibility bindings, `aria-*` attributes and interaction behavior. ## Limitations When using the `asChild` prop, ensure you pass only a single child element. Passing multiple children may cause rendering issues. Certain components, such as `Checkbox.Root` or `RadioGroup.Item`, have specific requirements for their child elements. For instance, they may require a label element as a child. If you change the underlying element type, ensure it remains accessible and functional. --- # Composition (SVELTE) ## The asChild Prop In Ark UI, the `asChild` prop lets you integrate custom components, ensuring consistent styling and behavior while promoting flexibility and reusability. All Ark components that render a DOM element accept the `asChild` prop. Here's an example using `asChild` to integrate a custom `Button` component within a `Popover`: In this example, the `asChild` prop allows the `Button` to be used as the trigger for the `Popover`, inheriting its behaviors from Popover.Trigger. ## The Ark Factory You can use the `ark` factory to create your own elements that work just like Ark UI components. This will produce the following HTML: ```html Ark UI ``` ## ID Composition When composing components that need to work together, share IDs between them using the `ids` prop for proper accessibility and interaction. ```tsx import { Avatar } from '@ark-ui/react/avatar' import { Tooltip } from '@ark-ui/react/tooltip' import { useId } from 'react' export const TooltipWithAvatar = () => { const id = useId() return ( SA Segun Adebayo is online ) } ``` Both components share the same `id` through their `ids` props, creating proper accessibility bindings, `aria-*` attributes and interaction behavior. ## Limitations When using the `asChild` prop, ensure you pass only a single child element. Passing multiple children may cause rendering issues. Certain components, such as `Checkbox.Root` or `RadioGroup.Item`, have specific requirements for their child elements. For instance, they may require a label element as a child. If you change the underlying element type, ensure it remains accessible and functional. --- # Composition (SOLID) ## The asChild Prop In Ark UI, the `asChild` prop lets you integrate custom components, ensuring consistent styling and behavior while promoting flexibility and reusability. All Ark components that render a DOM element accept the `asChild` prop. Here's an example using `asChild` to integrate a custom `Button` component within a `Popover`: In this example, the `asChild` prop allows the `Button` to be used as the trigger for the `Popover`, inheriting its behaviors from Popover.Trigger. ## The Ark Factory You can use the `ark` factory to create your own elements that work just like Ark UI components. This will produce the following HTML: ```html Ark UI ``` ## ID Composition When composing components that need to work together, share IDs between them using the `ids` prop for proper accessibility and interaction. ```tsx import { Avatar } from '@ark-ui/react/avatar' import { Tooltip } from '@ark-ui/react/tooltip' import { useId } from 'react' export const TooltipWithAvatar = () => { const id = useId() return ( SA Segun Adebayo is online ) } ``` Both components share the same `id` through their `ids` props, creating proper accessibility bindings, `aria-*` attributes and interaction behavior. ## Limitations When using the `asChild` prop, ensure you pass only a single child element. Passing multiple children may cause rendering issues. Certain components, such as `Checkbox.Root` or `RadioGroup.Item`, have specific requirements for their child elements. For instance, they may require a label element as a child. If you change the underlying element type, ensure it remains accessible and functional. --- # Component State (REACT) ## Context Components Context components expose state and functions to child components. In this example, `Avatar.Fallback` renders based on `loaded` state. > **Good to know (RSC)**: Due to the usage of render prop, you might need to add the `'use client'` directive at the top > of your file when using React Server Components. ## Provider Components Provider components can help coordinate state and behavior between multiple components, enabling interactions that aren't possible with `Context` components alone. They are used alongside component hooks. > When using the `RootProvider` component, you don't need to use the `Root` component. --- # Component State (VUE) ## Context Components Context components expose state and functions to child components. In this example, `Avatar.Fallback` renders based on `loaded` state. > **Good to know (RSC)**: Due to the usage of render prop, you might need to add the `'use client'` directive at the top > of your file when using React Server Components. ## Provider Components Provider components can help coordinate state and behavior between multiple components, enabling interactions that aren't possible with `Context` components alone. They are used alongside component hooks. > When using the `RootProvider` component, you don't need to use the `Root` component. --- # Component State (SVELTE) ## Context Components Context components expose state and functions to child components. In this example, `Avatar.Fallback` renders based on `loaded` state. > **Good to know (RSC)**: Due to the usage of render prop, you might need to add the `'use client'` directive at the top > of your file when using React Server Components. ## Provider Components Provider components can help coordinate state and behavior between multiple components, enabling interactions that aren't possible with `Context` components alone. They are used alongside component hooks. > When using the `RootProvider` component, you don't need to use the `Root` component. --- # Component State (SOLID) ## Context Components Context components expose state and functions to child components. In this example, `Avatar.Fallback` renders based on `loaded` state. > **Good to know (RSC)**: Due to the usage of render prop, you might need to add the `'use client'` directive at the top > of your file when using React Server Components. ## Provider Components Provider components can help coordinate state and behavior between multiple components, enabling interactions that aren't possible with `Context` components alone. They are used alongside component hooks. > When using the `RootProvider` component, you don't need to use the `Root` component. --- # Animation (REACT) Adding animation to Ark UI Components is as straightforward as with any other component, but keep in mind some considerations when working with exit animations with JavaScript animation libraries. ## Animating with CSS The most straightforward method to animate your elements is using CSS. You can animate both the mounting and unmounting phases with CSS. The latter is achievable because Ark UI Components postpones the unmounting while your animation runs. Below is a simple example of creating a fade-in and fade-out animation using CSS keyframes: ```css @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } } ``` You can use these keyframes to animate any element during its lifecycle. For instance, to apply the `fadeIn` animation when your `Tooltip` enters the 'open' state, and `fadeOut` when it enters the 'closed' state, you could use the following styles: ```css [data-scope='tooltip'][data-part='content'][data-state='open'] { animation: fadeIn 300ms ease-out; } [data-scope='tooltip'][data-part='content'][data-state='closed'] { animation: fadeOut 300ms ease-in; } ``` ## Animating with JS Libraries There's plenty of versatility when it comes to animating your Ark UI Elements with JavaScript libraries. Various libraries such as GreenSock, anime.js, Framer Motion, and more can add a new level of interaction and feedback to your UI components. One significant advantage of using Ark UI Elements is the control you have over the unmounting phase of your components. This is primarily facilitated through the `present` prop. The `present` prop allows the component to stay mounted even after its enclosing condition has been falsified, allowing for exit animations to complete before the component is removed from the DOM. --- # Animation (VUE) Adding animation to Ark UI Components is as straightforward as with any other component, but keep in mind some considerations when working with exit animations with JavaScript animation libraries. ## Animating with CSS The most straightforward method to animate your elements is using CSS. You can animate both the mounting and unmounting phases with CSS. The latter is achievable because Ark UI Components postpones the unmounting while your animation runs. Below is a simple example of creating a fade-in and fade-out animation using CSS keyframes: ```css @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } } ``` You can use these keyframes to animate any element during its lifecycle. For instance, to apply the `fadeIn` animation when your `Tooltip` enters the 'open' state, and `fadeOut` when it enters the 'closed' state, you could use the following styles: ```css [data-scope='tooltip'][data-part='content'][data-state='open'] { animation: fadeIn 300ms ease-out; } [data-scope='tooltip'][data-part='content'][data-state='closed'] { animation: fadeOut 300ms ease-in; } ``` ## Animating with JS Libraries There's plenty of versatility when it comes to animating your Ark UI Elements with JavaScript libraries. Various libraries such as GreenSock, anime.js, Framer Motion, and more can add a new level of interaction and feedback to your UI components. One significant advantage of using Ark UI Elements is the control you have over the unmounting phase of your components. This is primarily facilitated through the `present` prop. The `present` prop allows the component to stay mounted even after its enclosing condition has been falsified, allowing for exit animations to complete before the component is removed from the DOM. --- # Animation (SVELTE) Adding animation to Ark UI Components is as straightforward as with any other component, but keep in mind some considerations when working with exit animations with JavaScript animation libraries. ## Animating with CSS The most straightforward method to animate your elements is using CSS. You can animate both the mounting and unmounting phases with CSS. The latter is achievable because Ark UI Components postpones the unmounting while your animation runs. Below is a simple example of creating a fade-in and fade-out animation using CSS keyframes: ```css @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } } ``` You can use these keyframes to animate any element during its lifecycle. For instance, to apply the `fadeIn` animation when your `Tooltip` enters the 'open' state, and `fadeOut` when it enters the 'closed' state, you could use the following styles: ```css [data-scope='tooltip'][data-part='content'][data-state='open'] { animation: fadeIn 300ms ease-out; } [data-scope='tooltip'][data-part='content'][data-state='closed'] { animation: fadeOut 300ms ease-in; } ``` ## Animating with JS Libraries There's plenty of versatility when it comes to animating your Ark UI Elements with JavaScript libraries. Various libraries such as GreenSock, anime.js, Framer Motion, and more can add a new level of interaction and feedback to your UI components. One significant advantage of using Ark UI Elements is the control you have over the unmounting phase of your components. This is primarily facilitated through the `present` prop. The `present` prop allows the component to stay mounted even after its enclosing condition has been falsified, allowing for exit animations to complete before the component is removed from the DOM. --- # Animation (SOLID) Adding animation to Ark UI Components is as straightforward as with any other component, but keep in mind some considerations when working with exit animations with JavaScript animation libraries. ## Animating with CSS The most straightforward method to animate your elements is using CSS. You can animate both the mounting and unmounting phases with CSS. The latter is achievable because Ark UI Components postpones the unmounting while your animation runs. Below is a simple example of creating a fade-in and fade-out animation using CSS keyframes: ```css @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } } ``` You can use these keyframes to animate any element during its lifecycle. For instance, to apply the `fadeIn` animation when your `Tooltip` enters the 'open' state, and `fadeOut` when it enters the 'closed' state, you could use the following styles: ```css [data-scope='tooltip'][data-part='content'][data-state='open'] { animation: fadeIn 300ms ease-out; } [data-scope='tooltip'][data-part='content'][data-state='closed'] { animation: fadeOut 300ms ease-in; } ``` ## Animating with JS Libraries There's plenty of versatility when it comes to animating your Ark UI Elements with JavaScript libraries. Various libraries such as GreenSock, anime.js, Framer Motion, and more can add a new level of interaction and feedback to your UI components. One significant advantage of using Ark UI Elements is the control you have over the unmounting phase of your components. This is primarily facilitated through the `present` prop. The `present` prop allows the component to stay mounted even after its enclosing condition has been falsified, allowing for exit animations to complete before the component is removed from the DOM. --- # Forms (REACT) Ark UI provides the `Field` and `Fieldset` components for integrating with native `form` element or popular form libraries like [React Hook Form](https://react-hook-form.com/), [TanStack Form](https://tanstack.com/form/latest), and [Vee Validate](https://vee-validate.logaretm.com). ## Field Context Form components in Ark UI automatically integrate with `Field` through context. When nested inside a `Field.Root`, they inherit `disabled`, `invalid`, `required`, and `readOnly` states automatically. ```tsx import { Field } from '@ark-ui/react/field' import { NumberInput } from '@ark-ui/react/number-input' const Demo = () => ( {/* NumberInput will be disabled */} ) ``` ### Accessible Labels When building accessible forms, you need to ensure that they are properly labeled and described. - `Field.Label`: Used to provide an accessible label the input. - `Field.HelperText`: Used to provide additional instructions about the input. These components are automatically linked to the input element via the `aria-describedby` attribute. > **Best practice**: Make sure that labels are visible (and not just used as placeholders) for screen readers to read > them. ```tsx import { Field } from '@ark-ui/react/field' const Demo = () => (
                    Username This will be your public display name.
                    ) ``` ### Error Handling and Validation When the input is invalid, you can use the `Field.ErrorText` component to provide an error message for the input, and pass the `invalid` prop to the `Field.Root` component. > **Best practice**: Make sure to provide clear, specific error messages that are easy to understand and fix. ```tsx import { Field } from '@ark-ui/react/field' const Demo = () => (
                    Username Username is required.
                    ) ``` ### Required Fields To indicate that a field is required, you can pass the `required` prop to the `Field.Root` component. Optionally, you can use the `Field.RequiredIndicator` component to indicate that the field is required. > **Best practice**: Don't rely solely on color to indicate required status ```tsx import { Field } from '@ark-ui/react/field' export const Demo = () => (
                    Username (required) Username is required.
                    ) ``` To indicate that a field is optional, use the `fallback` prop on the `Field.RequiredIndicator` component. ```tsx (required) ``` ### Native Controls Field supports native HTML form controls including `input`, `textarea`, and `select`: ```tsx import { Field } from '@ark-ui/react/field' const Demo = () => (
                    {/* Input */} Email {/* Textarea */} Bio {/* Select */} Country
                    ) ``` ### Form Reset When the `reset` event is triggered on a form, all Ark UI components automatically sync their internal state with the form's reset values. > **Note**: For this to work correctly, always include the `HiddenInput` component in your form controls. The hidden > input participates in the native form reset mechanism, and Ark UI listens for this to sync the component state. ```tsx import { Checkbox } from '@ark-ui/react/checkbox' const Demo = () => { return (
                    I agree to the terms {/* Clicking reset will restore checkbox to defaultChecked state */}
                    ) } ``` ## Fieldset Context When you have multiple fields in a form or a component that renders multiple `input` elements, you can use the `Fieldset` component to group them together. Common use cases checkbox group, radio group, input + select composition, etc. ### Checkbox Group ```tsx import { Fieldset } from '@ark-ui/react/fieldset' import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ] const Demo = () => ( Frameworks {items.map((item) => ( ))} Choose your preferred frameworks ) ``` ### Radio Group ```tsx import { Fieldset } from '@ark-ui/react/fieldset' import { RadioGroup } from '@ark-ui/react/radio-group' import { RadioIcon } from 'lucide-react' const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ] const Demo = () => ( Frameworks {items.map((item) => ( ))} Choose your preferred framework ) ``` ## React Hook Form Ark UI integrates seamlessly with React Hook Form. Use the `register` function for simple inputs and `Controller` for complex components. ### Native Controls ```tsx import { Field } from '@ark-ui/react/field' import { useForm } from 'react-hook-form' interface FormValues { firstName: string email: string } const Demo = () => { const { register, handleSubmit, formState: { errors }, } = useForm() const onSubmit = (data: FormValues) => console.log(data) return (
                    First Name {errors.firstName?.message} Email {errors.email?.message}
                    ) } ``` ### Custom Components Use the `Controller` hook to integrate custom form components like select or combobox. > **Best practice**: To ensure `react-hook-form` moves focus to invalid field control when performing validation, > forward the field's `ref` to the respective Ark UI component. ```tsx import { Field } from '@ark-ui/react/field' import { Select, createListCollection } from '@ark-ui/react/select' import { Controller, useForm } from 'react-hook-form' const Demo = () => { const { control, handleSubmit } = useForm({ defaultValues: { framework: '' }, }) const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) return (
                    console.log(data))}> ( onChange(e.value[0])} onInteractOutside={() => onBlur()} > Framework {collection.items.map((item) => ( {item} ))} {error?.message} )} /> ) } ``` ## TanStack Form TanStack Form provides powerful form state management that works well with Ark UI. ### Native Controls ```tsx import { useForm } from '@tanstack/react-form' const form = useForm({ defaultValues: { firstName: '' }, }) const Demo = () => (
                    ( First Name field.handleChange(e.target.value)} onBlur={field.handleBlur} /> {field.state.meta.errors.join(',')} )} /> ) ``` ### Custom Components Here's an example of how to integrate custom components like the select or combobox with Tanstack's `form.Field` component. ```tsx import { Field } from '@ark-ui/react/field' import { Select, createListCollection } from '@ark-ui/react/select' import { useForm } from '@tanstack/react-form' const Demo = () => { const form = useForm({ defaultValues: { username: '' }, }) const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) return (
                    { e.preventDefault() e.stopPropagation() form.handleSubmit() }} > (value.length < 3 ? 'Username must be at least 3 characters' : undefined), }} children={(field) => ( 0}> Username field.handleChange(e.value[0])} onInteractOutside={() => field.handleBlur()} > Username {collection.items.map((item) => ( {item} ))} )} /> ) } ``` --- # Forms (VUE) Ark UI provides the `Field` and `Fieldset` components for integrating with native `form` element or popular form libraries like [React Hook Form](https://react-hook-form.com/), [TanStack Form](https://tanstack.com/form/latest), and [Vee Validate](https://vee-validate.logaretm.com). ## Field Context Form components in Ark UI automatically integrate with `Field` through context. When nested inside a `Field.Root`, they inherit `disabled`, `invalid`, `required`, and `readOnly` states automatically. ```tsx import { Field } from '@ark-ui/react/field' import { NumberInput } from '@ark-ui/react/number-input' const Demo = () => ( {/* NumberInput will be disabled */} ) ``` ### Accessible Labels When building accessible forms, you need to ensure that they are properly labeled and described. - `Field.Label`: Used to provide an accessible label the input. - `Field.HelperText`: Used to provide additional instructions about the input. These components are automatically linked to the input element via the `aria-describedby` attribute. > **Best practice**: Make sure that labels are visible (and not just used as placeholders) for screen readers to read > them. ```tsx import { Field } from '@ark-ui/react/field' const Demo = () => (
                    Username This will be your public display name.
                    ) ``` ### Error Handling and Validation When the input is invalid, you can use the `Field.ErrorText` component to provide an error message for the input, and pass the `invalid` prop to the `Field.Root` component. > **Best practice**: Make sure to provide clear, specific error messages that are easy to understand and fix. ```tsx import { Field } from '@ark-ui/react/field' const Demo = () => (
                    Username Username is required.
                    ) ``` ### Required Fields To indicate that a field is required, you can pass the `required` prop to the `Field.Root` component. Optionally, you can use the `Field.RequiredIndicator` component to indicate that the field is required. > **Best practice**: Don't rely solely on color to indicate required status ```tsx import { Field } from '@ark-ui/react/field' export const Demo = () => (
                    Username (required) Username is required.
                    ) ``` To indicate that a field is optional, use the `fallback` prop on the `Field.RequiredIndicator` component. ```tsx (required) ``` ### Native Controls Field supports native HTML form controls including `input`, `textarea`, and `select`: ```tsx import { Field } from '@ark-ui/react/field' const Demo = () => (
                    {/* Input */} Email {/* Textarea */} Bio {/* Select */} Country
                    ) ``` ### Form Reset When the `reset` event is triggered on a form, all Ark UI components automatically sync their internal state with the form's reset values. > **Note**: For this to work correctly, always include the `HiddenInput` component in your form controls. The hidden > input participates in the native form reset mechanism, and Ark UI listens for this to sync the component state. ```tsx import { Checkbox } from '@ark-ui/react/checkbox' const Demo = () => { return (
                    I agree to the terms {/* Clicking reset will restore checkbox to defaultChecked state */}
                    ) } ``` ## Fieldset Context When you have multiple fields in a form or a component that renders multiple `input` elements, you can use the `Fieldset` component to group them together. Common use cases checkbox group, radio group, input + select composition, etc. ### Checkbox Group ```tsx import { Fieldset } from '@ark-ui/react/fieldset' import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ] const Demo = () => ( Frameworks {items.map((item) => ( ))} Choose your preferred frameworks ) ``` ### Radio Group ```tsx import { Fieldset } from '@ark-ui/react/fieldset' import { RadioGroup } from '@ark-ui/react/radio-group' import { RadioIcon } from 'lucide-react' const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ] const Demo = () => ( Frameworks {items.map((item) => ( ))} Choose your preferred framework ) ``` ## React Hook Form Ark UI integrates seamlessly with React Hook Form. Use the `register` function for simple inputs and `Controller` for complex components. ### Native Controls ```tsx import { Field } from '@ark-ui/react/field' import { useForm } from 'react-hook-form' interface FormValues { firstName: string email: string } const Demo = () => { const { register, handleSubmit, formState: { errors }, } = useForm() const onSubmit = (data: FormValues) => console.log(data) return (
                    First Name {errors.firstName?.message} Email {errors.email?.message}
                    ) } ``` ### Custom Components Use the `Controller` hook to integrate custom form components like select or combobox. > **Best practice**: To ensure `react-hook-form` moves focus to invalid field control when performing validation, > forward the field's `ref` to the respective Ark UI component. ```tsx import { Field } from '@ark-ui/react/field' import { Select, createListCollection } from '@ark-ui/react/select' import { Controller, useForm } from 'react-hook-form' const Demo = () => { const { control, handleSubmit } = useForm({ defaultValues: { framework: '' }, }) const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) return (
                    console.log(data))}> ( onChange(e.value[0])} onInteractOutside={() => onBlur()} > Framework {collection.items.map((item) => ( {item} ))} {error?.message} )} /> ) } ``` ## TanStack Form TanStack Form provides powerful form state management that works well with Ark UI. ### Native Controls ```tsx import { useForm } from '@tanstack/react-form' const form = useForm({ defaultValues: { firstName: '' }, }) const Demo = () => (
                    ( First Name field.handleChange(e.target.value)} onBlur={field.handleBlur} /> {field.state.meta.errors.join(',')} )} /> ) ``` ### Custom Components Here's an example of how to integrate custom components like the select or combobox with Tanstack's `form.Field` component. ```tsx import { Field } from '@ark-ui/react/field' import { Select, createListCollection } from '@ark-ui/react/select' import { useForm } from '@tanstack/react-form' const Demo = () => { const form = useForm({ defaultValues: { username: '' }, }) const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) return (
                    { e.preventDefault() e.stopPropagation() form.handleSubmit() }} > (value.length < 3 ? 'Username must be at least 3 characters' : undefined), }} children={(field) => ( 0}> Username field.handleChange(e.value[0])} onInteractOutside={() => field.handleBlur()} > Username {collection.items.map((item) => ( {item} ))} )} /> ) } ``` --- # Forms (SVELTE) Ark UI provides the `Field` and `Fieldset` components for integrating with native `form` element or popular form libraries like [React Hook Form](https://react-hook-form.com/), [TanStack Form](https://tanstack.com/form/latest), and [Vee Validate](https://vee-validate.logaretm.com). ## Field Context Form components in Ark UI automatically integrate with `Field` through context. When nested inside a `Field.Root`, they inherit `disabled`, `invalid`, `required`, and `readOnly` states automatically. ```tsx import { Field } from '@ark-ui/react/field' import { NumberInput } from '@ark-ui/react/number-input' const Demo = () => ( {/* NumberInput will be disabled */} ) ``` ### Accessible Labels When building accessible forms, you need to ensure that they are properly labeled and described. - `Field.Label`: Used to provide an accessible label the input. - `Field.HelperText`: Used to provide additional instructions about the input. These components are automatically linked to the input element via the `aria-describedby` attribute. > **Best practice**: Make sure that labels are visible (and not just used as placeholders) for screen readers to read > them. ```tsx import { Field } from '@ark-ui/react/field' const Demo = () => (
                    Username This will be your public display name.
                    ) ``` ### Error Handling and Validation When the input is invalid, you can use the `Field.ErrorText` component to provide an error message for the input, and pass the `invalid` prop to the `Field.Root` component. > **Best practice**: Make sure to provide clear, specific error messages that are easy to understand and fix. ```tsx import { Field } from '@ark-ui/react/field' const Demo = () => (
                    Username Username is required.
                    ) ``` ### Required Fields To indicate that a field is required, you can pass the `required` prop to the `Field.Root` component. Optionally, you can use the `Field.RequiredIndicator` component to indicate that the field is required. > **Best practice**: Don't rely solely on color to indicate required status ```tsx import { Field } from '@ark-ui/react/field' export const Demo = () => (
                    Username (required) Username is required.
                    ) ``` To indicate that a field is optional, use the `fallback` prop on the `Field.RequiredIndicator` component. ```tsx (required) ``` ### Native Controls Field supports native HTML form controls including `input`, `textarea`, and `select`: ```tsx import { Field } from '@ark-ui/react/field' const Demo = () => (
                    {/* Input */} Email {/* Textarea */} Bio {/* Select */} Country
                    ) ``` ### Form Reset When the `reset` event is triggered on a form, all Ark UI components automatically sync their internal state with the form's reset values. > **Note**: For this to work correctly, always include the `HiddenInput` component in your form controls. The hidden > input participates in the native form reset mechanism, and Ark UI listens for this to sync the component state. ```tsx import { Checkbox } from '@ark-ui/react/checkbox' const Demo = () => { return (
                    I agree to the terms {/* Clicking reset will restore checkbox to defaultChecked state */}
                    ) } ``` ## Fieldset Context When you have multiple fields in a form or a component that renders multiple `input` elements, you can use the `Fieldset` component to group them together. Common use cases checkbox group, radio group, input + select composition, etc. ### Checkbox Group ```tsx import { Fieldset } from '@ark-ui/react/fieldset' import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ] const Demo = () => ( Frameworks {items.map((item) => ( ))} Choose your preferred frameworks ) ``` ### Radio Group ```tsx import { Fieldset } from '@ark-ui/react/fieldset' import { RadioGroup } from '@ark-ui/react/radio-group' import { RadioIcon } from 'lucide-react' const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ] const Demo = () => ( Frameworks {items.map((item) => ( ))} Choose your preferred framework ) ``` ## React Hook Form Ark UI integrates seamlessly with React Hook Form. Use the `register` function for simple inputs and `Controller` for complex components. ### Native Controls ```tsx import { Field } from '@ark-ui/react/field' import { useForm } from 'react-hook-form' interface FormValues { firstName: string email: string } const Demo = () => { const { register, handleSubmit, formState: { errors }, } = useForm() const onSubmit = (data: FormValues) => console.log(data) return (
                    First Name {errors.firstName?.message} Email {errors.email?.message}
                    ) } ``` ### Custom Components Use the `Controller` hook to integrate custom form components like select or combobox. > **Best practice**: To ensure `react-hook-form` moves focus to invalid field control when performing validation, > forward the field's `ref` to the respective Ark UI component. ```tsx import { Field } from '@ark-ui/react/field' import { Select, createListCollection } from '@ark-ui/react/select' import { Controller, useForm } from 'react-hook-form' const Demo = () => { const { control, handleSubmit } = useForm({ defaultValues: { framework: '' }, }) const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) return (
                    console.log(data))}> ( onChange(e.value[0])} onInteractOutside={() => onBlur()} > Framework {collection.items.map((item) => ( {item} ))} {error?.message} )} /> ) } ``` ## TanStack Form TanStack Form provides powerful form state management that works well with Ark UI. ### Native Controls ```tsx import { useForm } from '@tanstack/react-form' const form = useForm({ defaultValues: { firstName: '' }, }) const Demo = () => (
                    ( First Name field.handleChange(e.target.value)} onBlur={field.handleBlur} /> {field.state.meta.errors.join(',')} )} /> ) ``` ### Custom Components Here's an example of how to integrate custom components like the select or combobox with Tanstack's `form.Field` component. ```tsx import { Field } from '@ark-ui/react/field' import { Select, createListCollection } from '@ark-ui/react/select' import { useForm } from '@tanstack/react-form' const Demo = () => { const form = useForm({ defaultValues: { username: '' }, }) const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) return (
                    { e.preventDefault() e.stopPropagation() form.handleSubmit() }} > (value.length < 3 ? 'Username must be at least 3 characters' : undefined), }} children={(field) => ( 0}> Username field.handleChange(e.value[0])} onInteractOutside={() => field.handleBlur()} > Username {collection.items.map((item) => ( {item} ))} )} /> ) } ``` --- # Forms (SOLID) Ark UI provides the `Field` and `Fieldset` components for integrating with native `form` element or popular form libraries like [React Hook Form](https://react-hook-form.com/), [TanStack Form](https://tanstack.com/form/latest), and [Vee Validate](https://vee-validate.logaretm.com). ## Field Context Form components in Ark UI automatically integrate with `Field` through context. When nested inside a `Field.Root`, they inherit `disabled`, `invalid`, `required`, and `readOnly` states automatically. ```tsx import { Field } from '@ark-ui/react/field' import { NumberInput } from '@ark-ui/react/number-input' const Demo = () => ( {/* NumberInput will be disabled */} ) ``` ### Accessible Labels When building accessible forms, you need to ensure that they are properly labeled and described. - `Field.Label`: Used to provide an accessible label the input. - `Field.HelperText`: Used to provide additional instructions about the input. These components are automatically linked to the input element via the `aria-describedby` attribute. > **Best practice**: Make sure that labels are visible (and not just used as placeholders) for screen readers to read > them. ```tsx import { Field } from '@ark-ui/react/field' const Demo = () => (
                    Username This will be your public display name.
                    ) ``` ### Error Handling and Validation When the input is invalid, you can use the `Field.ErrorText` component to provide an error message for the input, and pass the `invalid` prop to the `Field.Root` component. > **Best practice**: Make sure to provide clear, specific error messages that are easy to understand and fix. ```tsx import { Field } from '@ark-ui/react/field' const Demo = () => (
                    Username Username is required.
                    ) ``` ### Required Fields To indicate that a field is required, you can pass the `required` prop to the `Field.Root` component. Optionally, you can use the `Field.RequiredIndicator` component to indicate that the field is required. > **Best practice**: Don't rely solely on color to indicate required status ```tsx import { Field } from '@ark-ui/react/field' export const Demo = () => (
                    Username (required) Username is required.
                    ) ``` To indicate that a field is optional, use the `fallback` prop on the `Field.RequiredIndicator` component. ```tsx (required) ``` ### Native Controls Field supports native HTML form controls including `input`, `textarea`, and `select`: ```tsx import { Field } from '@ark-ui/react/field' const Demo = () => (
                    {/* Input */} Email {/* Textarea */} Bio {/* Select */} Country
                    ) ``` ### Form Reset When the `reset` event is triggered on a form, all Ark UI components automatically sync their internal state with the form's reset values. > **Note**: For this to work correctly, always include the `HiddenInput` component in your form controls. The hidden > input participates in the native form reset mechanism, and Ark UI listens for this to sync the component state. ```tsx import { Checkbox } from '@ark-ui/react/checkbox' const Demo = () => { return (
                    I agree to the terms {/* Clicking reset will restore checkbox to defaultChecked state */}
                    ) } ``` ## Fieldset Context When you have multiple fields in a form or a component that renders multiple `input` elements, you can use the `Fieldset` component to group them together. Common use cases checkbox group, radio group, input + select composition, etc. ### Checkbox Group ```tsx import { Fieldset } from '@ark-ui/react/fieldset' import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ] const Demo = () => ( Frameworks {items.map((item) => ( ))} Choose your preferred frameworks ) ``` ### Radio Group ```tsx import { Fieldset } from '@ark-ui/react/fieldset' import { RadioGroup } from '@ark-ui/react/radio-group' import { RadioIcon } from 'lucide-react' const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ] const Demo = () => ( Frameworks {items.map((item) => ( ))} Choose your preferred framework ) ``` ## React Hook Form Ark UI integrates seamlessly with React Hook Form. Use the `register` function for simple inputs and `Controller` for complex components. ### Native Controls ```tsx import { Field } from '@ark-ui/react/field' import { useForm } from 'react-hook-form' interface FormValues { firstName: string email: string } const Demo = () => { const { register, handleSubmit, formState: { errors }, } = useForm() const onSubmit = (data: FormValues) => console.log(data) return (
                    First Name {errors.firstName?.message} Email {errors.email?.message}
                    ) } ``` ### Custom Components Use the `Controller` hook to integrate custom form components like select or combobox. > **Best practice**: To ensure `react-hook-form` moves focus to invalid field control when performing validation, > forward the field's `ref` to the respective Ark UI component. ```tsx import { Field } from '@ark-ui/react/field' import { Select, createListCollection } from '@ark-ui/react/select' import { Controller, useForm } from 'react-hook-form' const Demo = () => { const { control, handleSubmit } = useForm({ defaultValues: { framework: '' }, }) const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) return (
                    console.log(data))}> ( onChange(e.value[0])} onInteractOutside={() => onBlur()} > Framework {collection.items.map((item) => ( {item} ))} {error?.message} )} /> ) } ``` ## TanStack Form TanStack Form provides powerful form state management that works well with Ark UI. ### Native Controls ```tsx import { useForm } from '@tanstack/react-form' const form = useForm({ defaultValues: { firstName: '' }, }) const Demo = () => (
                    ( First Name field.handleChange(e.target.value)} onBlur={field.handleBlur} /> {field.state.meta.errors.join(',')} )} /> ) ``` ### Custom Components Here's an example of how to integrate custom components like the select or combobox with Tanstack's `form.Field` component. ```tsx import { Field } from '@ark-ui/react/field' import { Select, createListCollection } from '@ark-ui/react/select' import { useForm } from '@tanstack/react-form' const Demo = () => { const form = useForm({ defaultValues: { username: '' }, }) const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) return (
                    { e.preventDefault() e.stopPropagation() form.handleSubmit() }} > (value.length < 3 ? 'Username must be at least 3 characters' : undefined), }} children={(field) => ( 0}> Username field.handleChange(e.value[0])} onInteractOutside={() => field.handleBlur()} > Username {collection.items.map((item) => ( {item} ))} )} /> ) } ``` --- # Refs (REACT) ## React In React, the `ref` prop can be used to access the rendered element. Use the `useRef` hook to create a reference and pass it to the component. ```tsx import { Slider } from '@ark-ui/react/slider' import { useRef } from 'react' export const MySlider = () => { const rootRef = useRef(null) return {/* ... */} } ``` ## Solid In Solid, the `ref` prop can be used to access the rendered element. ```tsx import { Slider } from '@ark-ui/solid/slider' export const MySlider = () => { let rootRef!: HTMLDivElement return (rootRef = el)}>{/* ... */} } ``` Alternatively, you can assign refs to Solid.js signals via the `createSignal` function. ```tsx import { Slider } from '@ark-ui/solid/slider' import { createSignal } from 'solid-js' export const MySlider = () => { const [rootRef, setRootRef] = createSignal(null) return {/* ... */} } ``` ## Vue In Vue, pass the `ref` prop to the component to access the rendered element via the `$el` property. ```vue ``` ## Svelte In Svelte 5, use the `bind:ref` directive to access the rendered element. ```svelte {/* ... */} ``` --- # Refs (VUE) ## React In React, the `ref` prop can be used to access the rendered element. Use the `useRef` hook to create a reference and pass it to the component. ```tsx import { Slider } from '@ark-ui/react/slider' import { useRef } from 'react' export const MySlider = () => { const rootRef = useRef(null) return {/* ... */} } ``` ## Solid In Solid, the `ref` prop can be used to access the rendered element. ```tsx import { Slider } from '@ark-ui/solid/slider' export const MySlider = () => { let rootRef!: HTMLDivElement return (rootRef = el)}>{/* ... */} } ``` Alternatively, you can assign refs to Solid.js signals via the `createSignal` function. ```tsx import { Slider } from '@ark-ui/solid/slider' import { createSignal } from 'solid-js' export const MySlider = () => { const [rootRef, setRootRef] = createSignal(null) return {/* ... */} } ``` ## Vue In Vue, pass the `ref` prop to the component to access the rendered element via the `$el` property. ```vue ``` ## Svelte In Svelte 5, use the `bind:ref` directive to access the rendered element. ```svelte {/* ... */} ``` --- # Refs (SVELTE) ## React In React, the `ref` prop can be used to access the rendered element. Use the `useRef` hook to create a reference and pass it to the component. ```tsx import { Slider } from '@ark-ui/react/slider' import { useRef } from 'react' export const MySlider = () => { const rootRef = useRef(null) return {/* ... */} } ``` ## Solid In Solid, the `ref` prop can be used to access the rendered element. ```tsx import { Slider } from '@ark-ui/solid/slider' export const MySlider = () => { let rootRef!: HTMLDivElement return (rootRef = el)}>{/* ... */} } ``` Alternatively, you can assign refs to Solid.js signals via the `createSignal` function. ```tsx import { Slider } from '@ark-ui/solid/slider' import { createSignal } from 'solid-js' export const MySlider = () => { const [rootRef, setRootRef] = createSignal(null) return {/* ... */} } ``` ## Vue In Vue, pass the `ref` prop to the component to access the rendered element via the `$el` property. ```vue ``` ## Svelte In Svelte 5, use the `bind:ref` directive to access the rendered element. ```svelte {/* ... */} ``` --- # Refs (SOLID) ## React In React, the `ref` prop can be used to access the rendered element. Use the `useRef` hook to create a reference and pass it to the component. ```tsx import { Slider } from '@ark-ui/react/slider' import { useRef } from 'react' export const MySlider = () => { const rootRef = useRef(null) return {/* ... */} } ``` ## Solid In Solid, the `ref` prop can be used to access the rendered element. ```tsx import { Slider } from '@ark-ui/solid/slider' export const MySlider = () => { let rootRef!: HTMLDivElement return (rootRef = el)}>{/* ... */} } ``` Alternatively, you can assign refs to Solid.js signals via the `createSignal` function. ```tsx import { Slider } from '@ark-ui/solid/slider' import { createSignal } from 'solid-js' export const MySlider = () => { const [rootRef, setRootRef] = createSignal(null) return {/* ... */} } ``` ## Vue In Vue, pass the `ref` prop to the component to access the rendered element via the `$el` property. ```vue ``` ## Svelte In Svelte 5, use the `bind:ref` directive to access the rendered element. ```svelte {/* ... */} ``` --- # MCP Server (REACT) The Ark UI MCP Server is a specialized [Model Context Protocol](https://modelcontextprotocol.io/introduction) server that empowers AI agents to build design system components with full knowledge of Ark UI. Ark UI MCP Server It works with tools like Claude Code, Cursor, and Copilot to generate code and apply design system logic consistently across React, Vue, Solid, and Svelte. ## Tools The Ark UI MCP exposes the following tools to AI agents: - **`list_components`**: Returns a full list of all available components - **`list_examples`**: Lists various component examples - **`get_example`**: Retrieves code examples and usage patterns - **`styling_guide`**: Provides styling guidelines for components (data attributes and CSS variables) ## Setup The MCP server currently supports only [stdio transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#stdio) and is published at `@ark-ui/mcp`. ### Visual Studio Code > Make sure you have the [GitHub Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot) and > [GitHub Copilot Chat](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-chat) extensions installed. - In the `.vscode/mcp.json` file at the root of your project, add the MCP server block: ```json title=".vscode/mcp.json" { "servers": { "ark-ui": { "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` - The MCP server is now ready to use. Click the **"Start"** button in the `mcp.json` file. - Start a new chat VSCode Copilot like _"Build me a checkbox with ark ui"_ ### Cursor - In the `.cursor/mcp.json` file at the root of your project, add the following configuration: ```json { "mcpServers": { "ark-ui": { "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` - Go to **Settings** > **Cursor Settings** > **MCP & Integrations** and enable the Ark UI server. - Start a new chat Cursor chat like _"Build me a checkbox with ark ui"_ ### Claude Code > Make sure you have Claude Code installed. Visit [Anthropic docs](https://docs.anthropic.com/en/docs/claude-code/mcp) > for installation instructions. - Run the following command in your terminal to add the Ark UI MCP server: ```bash claude mcp add ark-ui -- npx -y @ark-ui/mcp ``` - Start a Claude Code session by running `claude` - Type a prompt like _"Build me a checkbox with ark ui"_ ### Windsurf - Navigate to **Settings** > **Windsurf Settings** > **Cascade** - Click the **Manage MCPs** button, then click the **"View raw config"** button. - Add the following to the MCP configuration file: ```json title=".codeium/windsurf/mcp_config.json" { "mcpServers": { "ark-ui": { "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` > You might need to click the **Refresh** button to see the MCP server in the list. - Start a new chat Windsurf like _"Build me a checkbox with ark ui"_ ### Zed - Go to **Settings** > **Open Settings** - In the `settings.json` file, add MCP server as a new **context server**: ```json title=".config/zed/settings.json" { "context_servers": { "ark-ui": { "source": "custom", "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` - Start a new chat Zed like _"Build me a checkbox with ark ui"_ ### Custom MCP Client To run the MCP server in a local or development environment using a custom MCP client, you need to add the MCP server to the client's configuration file. ```json { "mcpServers": { "ark-ui": { "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` --- # MCP Server (VUE) The Ark UI MCP Server is a specialized [Model Context Protocol](https://modelcontextprotocol.io/introduction) server that empowers AI agents to build design system components with full knowledge of Ark UI. Ark UI MCP Server It works with tools like Claude Code, Cursor, and Copilot to generate code and apply design system logic consistently across React, Vue, Solid, and Svelte. ## Tools The Ark UI MCP exposes the following tools to AI agents: - **`list_components`**: Returns a full list of all available components - **`list_examples`**: Lists various component examples - **`get_example`**: Retrieves code examples and usage patterns - **`styling_guide`**: Provides styling guidelines for components (data attributes and CSS variables) ## Setup The MCP server currently supports only [stdio transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#stdio) and is published at `@ark-ui/mcp`. ### Visual Studio Code > Make sure you have the [GitHub Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot) and > [GitHub Copilot Chat](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-chat) extensions installed. - In the `.vscode/mcp.json` file at the root of your project, add the MCP server block: ```json title=".vscode/mcp.json" { "servers": { "ark-ui": { "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` - The MCP server is now ready to use. Click the **"Start"** button in the `mcp.json` file. - Start a new chat VSCode Copilot like _"Build me a checkbox with ark ui"_ ### Cursor - In the `.cursor/mcp.json` file at the root of your project, add the following configuration: ```json { "mcpServers": { "ark-ui": { "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` - Go to **Settings** > **Cursor Settings** > **MCP & Integrations** and enable the Ark UI server. - Start a new chat Cursor chat like _"Build me a checkbox with ark ui"_ ### Claude Code > Make sure you have Claude Code installed. Visit [Anthropic docs](https://docs.anthropic.com/en/docs/claude-code/mcp) > for installation instructions. - Run the following command in your terminal to add the Ark UI MCP server: ```bash claude mcp add ark-ui -- npx -y @ark-ui/mcp ``` - Start a Claude Code session by running `claude` - Type a prompt like _"Build me a checkbox with ark ui"_ ### Windsurf - Navigate to **Settings** > **Windsurf Settings** > **Cascade** - Click the **Manage MCPs** button, then click the **"View raw config"** button. - Add the following to the MCP configuration file: ```json title=".codeium/windsurf/mcp_config.json" { "mcpServers": { "ark-ui": { "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` > You might need to click the **Refresh** button to see the MCP server in the list. - Start a new chat Windsurf like _"Build me a checkbox with ark ui"_ ### Zed - Go to **Settings** > **Open Settings** - In the `settings.json` file, add MCP server as a new **context server**: ```json title=".config/zed/settings.json" { "context_servers": { "ark-ui": { "source": "custom", "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` - Start a new chat Zed like _"Build me a checkbox with ark ui"_ ### Custom MCP Client To run the MCP server in a local or development environment using a custom MCP client, you need to add the MCP server to the client's configuration file. ```json { "mcpServers": { "ark-ui": { "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` --- # MCP Server (SVELTE) The Ark UI MCP Server is a specialized [Model Context Protocol](https://modelcontextprotocol.io/introduction) server that empowers AI agents to build design system components with full knowledge of Ark UI. Ark UI MCP Server It works with tools like Claude Code, Cursor, and Copilot to generate code and apply design system logic consistently across React, Vue, Solid, and Svelte. ## Tools The Ark UI MCP exposes the following tools to AI agents: - **`list_components`**: Returns a full list of all available components - **`list_examples`**: Lists various component examples - **`get_example`**: Retrieves code examples and usage patterns - **`styling_guide`**: Provides styling guidelines for components (data attributes and CSS variables) ## Setup The MCP server currently supports only [stdio transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#stdio) and is published at `@ark-ui/mcp`. ### Visual Studio Code > Make sure you have the [GitHub Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot) and > [GitHub Copilot Chat](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-chat) extensions installed. - In the `.vscode/mcp.json` file at the root of your project, add the MCP server block: ```json title=".vscode/mcp.json" { "servers": { "ark-ui": { "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` - The MCP server is now ready to use. Click the **"Start"** button in the `mcp.json` file. - Start a new chat VSCode Copilot like _"Build me a checkbox with ark ui"_ ### Cursor - In the `.cursor/mcp.json` file at the root of your project, add the following configuration: ```json { "mcpServers": { "ark-ui": { "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` - Go to **Settings** > **Cursor Settings** > **MCP & Integrations** and enable the Ark UI server. - Start a new chat Cursor chat like _"Build me a checkbox with ark ui"_ ### Claude Code > Make sure you have Claude Code installed. Visit [Anthropic docs](https://docs.anthropic.com/en/docs/claude-code/mcp) > for installation instructions. - Run the following command in your terminal to add the Ark UI MCP server: ```bash claude mcp add ark-ui -- npx -y @ark-ui/mcp ``` - Start a Claude Code session by running `claude` - Type a prompt like _"Build me a checkbox with ark ui"_ ### Windsurf - Navigate to **Settings** > **Windsurf Settings** > **Cascade** - Click the **Manage MCPs** button, then click the **"View raw config"** button. - Add the following to the MCP configuration file: ```json title=".codeium/windsurf/mcp_config.json" { "mcpServers": { "ark-ui": { "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` > You might need to click the **Refresh** button to see the MCP server in the list. - Start a new chat Windsurf like _"Build me a checkbox with ark ui"_ ### Zed - Go to **Settings** > **Open Settings** - In the `settings.json` file, add MCP server as a new **context server**: ```json title=".config/zed/settings.json" { "context_servers": { "ark-ui": { "source": "custom", "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` - Start a new chat Zed like _"Build me a checkbox with ark ui"_ ### Custom MCP Client To run the MCP server in a local or development environment using a custom MCP client, you need to add the MCP server to the client's configuration file. ```json { "mcpServers": { "ark-ui": { "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` --- # MCP Server (SOLID) The Ark UI MCP Server is a specialized [Model Context Protocol](https://modelcontextprotocol.io/introduction) server that empowers AI agents to build design system components with full knowledge of Ark UI. Ark UI MCP Server It works with tools like Claude Code, Cursor, and Copilot to generate code and apply design system logic consistently across React, Vue, Solid, and Svelte. ## Tools The Ark UI MCP exposes the following tools to AI agents: - **`list_components`**: Returns a full list of all available components - **`list_examples`**: Lists various component examples - **`get_example`**: Retrieves code examples and usage patterns - **`styling_guide`**: Provides styling guidelines for components (data attributes and CSS variables) ## Setup The MCP server currently supports only [stdio transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#stdio) and is published at `@ark-ui/mcp`. ### Visual Studio Code > Make sure you have the [GitHub Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot) and > [GitHub Copilot Chat](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-chat) extensions installed. - In the `.vscode/mcp.json` file at the root of your project, add the MCP server block: ```json title=".vscode/mcp.json" { "servers": { "ark-ui": { "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` - The MCP server is now ready to use. Click the **"Start"** button in the `mcp.json` file. - Start a new chat VSCode Copilot like _"Build me a checkbox with ark ui"_ ### Cursor - In the `.cursor/mcp.json` file at the root of your project, add the following configuration: ```json { "mcpServers": { "ark-ui": { "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` - Go to **Settings** > **Cursor Settings** > **MCP & Integrations** and enable the Ark UI server. - Start a new chat Cursor chat like _"Build me a checkbox with ark ui"_ ### Claude Code > Make sure you have Claude Code installed. Visit [Anthropic docs](https://docs.anthropic.com/en/docs/claude-code/mcp) > for installation instructions. - Run the following command in your terminal to add the Ark UI MCP server: ```bash claude mcp add ark-ui -- npx -y @ark-ui/mcp ``` - Start a Claude Code session by running `claude` - Type a prompt like _"Build me a checkbox with ark ui"_ ### Windsurf - Navigate to **Settings** > **Windsurf Settings** > **Cascade** - Click the **Manage MCPs** button, then click the **"View raw config"** button. - Add the following to the MCP configuration file: ```json title=".codeium/windsurf/mcp_config.json" { "mcpServers": { "ark-ui": { "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` > You might need to click the **Refresh** button to see the MCP server in the list. - Start a new chat Windsurf like _"Build me a checkbox with ark ui"_ ### Zed - Go to **Settings** > **Open Settings** - In the `settings.json` file, add MCP server as a new **context server**: ```json title=".config/zed/settings.json" { "context_servers": { "ark-ui": { "source": "custom", "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` - Start a new chat Zed like _"Build me a checkbox with ark ui"_ ### Custom MCP Client To run the MCP server in a local or development environment using a custom MCP client, you need to add the MCP server to the client's configuration file. ```json { "mcpServers": { "ark-ui": { "command": "npx", "args": ["-y", "@ark-ui/mcp"] } } } ``` --- # LLMs.txt (REACT) ## What is LLMs.txt? We support [LLMs.txt](https://llmstxt.org/) files for making the Ark UI documentation available to large language models (LLMs). This feature helps AI tools better understand our component library, its APIs, and usage patterns. ## Available Routes We provide several LLMs.txt routes to help AI tools access our documentation: - [llms.txt](https://ark-ui.com/llms.txt) - Contains a structured overview of all components and their documentation links - [llms-full.txt](https://ark-ui.com/llms-full.txt) - Provides comprehensive documentation including implementation details and examples - [llms-react.txt](https://ark-ui.com/llms-react.txt) - React-specific documentation and implementation details - [llms-solid.txt](https://ark-ui.com/llms-solid.txt) - SolidJS-specific documentation and implementation details - [llms-vue.txt](https://ark-ui.com/llms-vue.txt) - Vue-specific documentation and implementation details - [llms-svelte.txt](https://ark-ui.com/llms-svelte.txt) - Svelte-specific documentation and implementation details ## Usage with AI Tools ### Cursor Use the `@Docs` feature in Cursor to include the LLMs.txt files in your project. This helps Cursor provide more accurate code suggestions and documentation for Ark UI components. [Read more about @Docs in Cursor](https://docs.cursor.com/context/@-symbols/@-docs) ### Windstatic Reference the LLMs.txt files using `@` or in your `.windsurfrules` files to enhance Windstatic's understanding of Ark UI components. [Read more about Windstatic Memories](https://docs.codeium.com/windsurf/memories#memories-and-rules) ### Other AI Tools Any AI tool that supports LLMs.txt can use these routes to better understand Ark UI. Simply point your tool to any of the routes above based on your framework of choice. --- # LLMs.txt (VUE) ## What is LLMs.txt? We support [LLMs.txt](https://llmstxt.org/) files for making the Ark UI documentation available to large language models (LLMs). This feature helps AI tools better understand our component library, its APIs, and usage patterns. ## Available Routes We provide several LLMs.txt routes to help AI tools access our documentation: - [llms.txt](https://ark-ui.com/llms.txt) - Contains a structured overview of all components and their documentation links - [llms-full.txt](https://ark-ui.com/llms-full.txt) - Provides comprehensive documentation including implementation details and examples - [llms-react.txt](https://ark-ui.com/llms-react.txt) - React-specific documentation and implementation details - [llms-solid.txt](https://ark-ui.com/llms-solid.txt) - SolidJS-specific documentation and implementation details - [llms-vue.txt](https://ark-ui.com/llms-vue.txt) - Vue-specific documentation and implementation details - [llms-svelte.txt](https://ark-ui.com/llms-svelte.txt) - Svelte-specific documentation and implementation details ## Usage with AI Tools ### Cursor Use the `@Docs` feature in Cursor to include the LLMs.txt files in your project. This helps Cursor provide more accurate code suggestions and documentation for Ark UI components. [Read more about @Docs in Cursor](https://docs.cursor.com/context/@-symbols/@-docs) ### Windstatic Reference the LLMs.txt files using `@` or in your `.windsurfrules` files to enhance Windstatic's understanding of Ark UI components. [Read more about Windstatic Memories](https://docs.codeium.com/windsurf/memories#memories-and-rules) ### Other AI Tools Any AI tool that supports LLMs.txt can use these routes to better understand Ark UI. Simply point your tool to any of the routes above based on your framework of choice. --- # LLMs.txt (SVELTE) ## What is LLMs.txt? We support [LLMs.txt](https://llmstxt.org/) files for making the Ark UI documentation available to large language models (LLMs). This feature helps AI tools better understand our component library, its APIs, and usage patterns. ## Available Routes We provide several LLMs.txt routes to help AI tools access our documentation: - [llms.txt](https://ark-ui.com/llms.txt) - Contains a structured overview of all components and their documentation links - [llms-full.txt](https://ark-ui.com/llms-full.txt) - Provides comprehensive documentation including implementation details and examples - [llms-react.txt](https://ark-ui.com/llms-react.txt) - React-specific documentation and implementation details - [llms-solid.txt](https://ark-ui.com/llms-solid.txt) - SolidJS-specific documentation and implementation details - [llms-vue.txt](https://ark-ui.com/llms-vue.txt) - Vue-specific documentation and implementation details - [llms-svelte.txt](https://ark-ui.com/llms-svelte.txt) - Svelte-specific documentation and implementation details ## Usage with AI Tools ### Cursor Use the `@Docs` feature in Cursor to include the LLMs.txt files in your project. This helps Cursor provide more accurate code suggestions and documentation for Ark UI components. [Read more about @Docs in Cursor](https://docs.cursor.com/context/@-symbols/@-docs) ### Windstatic Reference the LLMs.txt files using `@` or in your `.windsurfrules` files to enhance Windstatic's understanding of Ark UI components. [Read more about Windstatic Memories](https://docs.codeium.com/windsurf/memories#memories-and-rules) ### Other AI Tools Any AI tool that supports LLMs.txt can use these routes to better understand Ark UI. Simply point your tool to any of the routes above based on your framework of choice. --- # LLMs.txt (SOLID) ## What is LLMs.txt? We support [LLMs.txt](https://llmstxt.org/) files for making the Ark UI documentation available to large language models (LLMs). This feature helps AI tools better understand our component library, its APIs, and usage patterns. ## Available Routes We provide several LLMs.txt routes to help AI tools access our documentation: - [llms.txt](https://ark-ui.com/llms.txt) - Contains a structured overview of all components and their documentation links - [llms-full.txt](https://ark-ui.com/llms-full.txt) - Provides comprehensive documentation including implementation details and examples - [llms-react.txt](https://ark-ui.com/llms-react.txt) - React-specific documentation and implementation details - [llms-solid.txt](https://ark-ui.com/llms-solid.txt) - SolidJS-specific documentation and implementation details - [llms-vue.txt](https://ark-ui.com/llms-vue.txt) - Vue-specific documentation and implementation details - [llms-svelte.txt](https://ark-ui.com/llms-svelte.txt) - Svelte-specific documentation and implementation details ## Usage with AI Tools ### Cursor Use the `@Docs` feature in Cursor to include the LLMs.txt files in your project. This helps Cursor provide more accurate code suggestions and documentation for Ark UI components. [Read more about @Docs in Cursor](https://docs.cursor.com/context/@-symbols/@-docs) ### Windstatic Reference the LLMs.txt files using `@` or in your `.windsurfrules` files to enhance Windstatic's understanding of Ark UI components. [Read more about Windstatic Memories](https://docs.codeium.com/windsurf/memories#memories-and-rules) ### Other AI Tools Any AI tool that supports LLMs.txt can use these routes to better understand Ark UI. Simply point your tool to any of the routes above based on your framework of choice. --- # List Collection (REACT) A list collection is a collection that is based on an array of items. It is created by passing an array of items to the constructor. ```ts import { createListCollection } from '@ark-ui/react/collection' const collection = createListCollection({ items: [ { label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }, ], }) console.log(collection.items) // [{ label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }] ``` ### Converting value to item Use the `find` or `findMany` method to convert a value to an item. ```ts const item = collection.find('banana') console.log(item) // { label: "Banana", value: "banana" } const items = collection.findMany(['apple', 'banana']) console.log(items) // [{ label: "Apple", value: "apple" }, { label: "Banana", value: "banana" }] ``` ### Value Traversal Use the `getNextValue` or `getPreviousValue` method to get the next or previous item based on a value. ```ts const nextValue = collection.getNextValue('apple') console.log(nextValue) // banana const previousItem = collection.getPreviousValue('banana') console.log(previousItem) // apple ``` Likewise, use the `firstValue` or `lastValue` computed properties to get the first or last item. ```ts console.log(collection.firstValue) // apple console.log(collection.lastValue) // banana ``` ### Check for value existence Use the `has` method to check if a value exists in the collection. ```ts const hasValue = collection.has('apple') console.log(hasValue) // true ``` ### Working with custom objects If you are working with custom objects, you can pass a function to the `itemToString` and `itemToValue` options to specify how to convert an item to a string and a value, respectively. > By default, we look for the `label` and `value` properties in the item. ```ts import { createListCollection } from '@ark-ui/react/collection' const collection = createListCollection({ items: [ { id: 1, name: 'apple' }, { id: 2, name: 'banana' }, { id: 3, name: 'cherry' }, ], itemToString: (item) => item.name, itemToValue: (item) => item.id, }) ``` To mark an item as disabled, pass a function to the `isItemDisabled` option. > By default, we look for the `disabled` property in the item. ```ts import { createListCollection } from '@ark-ui/react/collection' const collection = createListCollection({ items: [ { id: 1, name: 'apple' }, { id: 2, name: 'banana' }, { id: 3, name: 'cherry' }, ], isItemDisabled: (item) => item.id === 2, }) ``` ### Reorder items Use the `reorder` method to reorder items by passing the starting index and the ending index of the item to be moved. ```ts const fromIndex = 1 // Banana const toIndex = 0 // Apple collection.reorder(fromIndex, toIndex) console.log(collection.items) // [{ label: "Banana", value: "banana" }, { label: "Apple", value: "apple" }] ``` --- # List Collection (VUE) A list collection is a collection that is based on an array of items. It is created by passing an array of items to the constructor. ```ts import { createListCollection } from '@ark-ui/react/collection' const collection = createListCollection({ items: [ { label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }, ], }) console.log(collection.items) // [{ label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }] ``` ### Converting value to item Use the `find` or `findMany` method to convert a value to an item. ```ts const item = collection.find('banana') console.log(item) // { label: "Banana", value: "banana" } const items = collection.findMany(['apple', 'banana']) console.log(items) // [{ label: "Apple", value: "apple" }, { label: "Banana", value: "banana" }] ``` ### Value Traversal Use the `getNextValue` or `getPreviousValue` method to get the next or previous item based on a value. ```ts const nextValue = collection.getNextValue('apple') console.log(nextValue) // banana const previousItem = collection.getPreviousValue('banana') console.log(previousItem) // apple ``` Likewise, use the `firstValue` or `lastValue` computed properties to get the first or last item. ```ts console.log(collection.firstValue) // apple console.log(collection.lastValue) // banana ``` ### Check for value existence Use the `has` method to check if a value exists in the collection. ```ts const hasValue = collection.has('apple') console.log(hasValue) // true ``` ### Working with custom objects If you are working with custom objects, you can pass a function to the `itemToString` and `itemToValue` options to specify how to convert an item to a string and a value, respectively. > By default, we look for the `label` and `value` properties in the item. ```ts import { createListCollection } from '@ark-ui/react/collection' const collection = createListCollection({ items: [ { id: 1, name: 'apple' }, { id: 2, name: 'banana' }, { id: 3, name: 'cherry' }, ], itemToString: (item) => item.name, itemToValue: (item) => item.id, }) ``` To mark an item as disabled, pass a function to the `isItemDisabled` option. > By default, we look for the `disabled` property in the item. ```ts import { createListCollection } from '@ark-ui/react/collection' const collection = createListCollection({ items: [ { id: 1, name: 'apple' }, { id: 2, name: 'banana' }, { id: 3, name: 'cherry' }, ], isItemDisabled: (item) => item.id === 2, }) ``` ### Reorder items Use the `reorder` method to reorder items by passing the starting index and the ending index of the item to be moved. ```ts const fromIndex = 1 // Banana const toIndex = 0 // Apple collection.reorder(fromIndex, toIndex) console.log(collection.items) // [{ label: "Banana", value: "banana" }, { label: "Apple", value: "apple" }] ``` --- # List Collection (SVELTE) A list collection is a collection that is based on an array of items. It is created by passing an array of items to the constructor. ```ts import { createListCollection } from '@ark-ui/react/collection' const collection = createListCollection({ items: [ { label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }, ], }) console.log(collection.items) // [{ label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }] ``` ### Converting value to item Use the `find` or `findMany` method to convert a value to an item. ```ts const item = collection.find('banana') console.log(item) // { label: "Banana", value: "banana" } const items = collection.findMany(['apple', 'banana']) console.log(items) // [{ label: "Apple", value: "apple" }, { label: "Banana", value: "banana" }] ``` ### Value Traversal Use the `getNextValue` or `getPreviousValue` method to get the next or previous item based on a value. ```ts const nextValue = collection.getNextValue('apple') console.log(nextValue) // banana const previousItem = collection.getPreviousValue('banana') console.log(previousItem) // apple ``` Likewise, use the `firstValue` or `lastValue` computed properties to get the first or last item. ```ts console.log(collection.firstValue) // apple console.log(collection.lastValue) // banana ``` ### Check for value existence Use the `has` method to check if a value exists in the collection. ```ts const hasValue = collection.has('apple') console.log(hasValue) // true ``` ### Working with custom objects If you are working with custom objects, you can pass a function to the `itemToString` and `itemToValue` options to specify how to convert an item to a string and a value, respectively. > By default, we look for the `label` and `value` properties in the item. ```ts import { createListCollection } from '@ark-ui/react/collection' const collection = createListCollection({ items: [ { id: 1, name: 'apple' }, { id: 2, name: 'banana' }, { id: 3, name: 'cherry' }, ], itemToString: (item) => item.name, itemToValue: (item) => item.id, }) ``` To mark an item as disabled, pass a function to the `isItemDisabled` option. > By default, we look for the `disabled` property in the item. ```ts import { createListCollection } from '@ark-ui/react/collection' const collection = createListCollection({ items: [ { id: 1, name: 'apple' }, { id: 2, name: 'banana' }, { id: 3, name: 'cherry' }, ], isItemDisabled: (item) => item.id === 2, }) ``` ### Reorder items Use the `reorder` method to reorder items by passing the starting index and the ending index of the item to be moved. ```ts const fromIndex = 1 // Banana const toIndex = 0 // Apple collection.reorder(fromIndex, toIndex) console.log(collection.items) // [{ label: "Banana", value: "banana" }, { label: "Apple", value: "apple" }] ``` --- # List Collection (SOLID) A list collection is a collection that is based on an array of items. It is created by passing an array of items to the constructor. ```ts import { createListCollection } from '@ark-ui/react/collection' const collection = createListCollection({ items: [ { label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }, ], }) console.log(collection.items) // [{ label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }] ``` ### Converting value to item Use the `find` or `findMany` method to convert a value to an item. ```ts const item = collection.find('banana') console.log(item) // { label: "Banana", value: "banana" } const items = collection.findMany(['apple', 'banana']) console.log(items) // [{ label: "Apple", value: "apple" }, { label: "Banana", value: "banana" }] ``` ### Value Traversal Use the `getNextValue` or `getPreviousValue` method to get the next or previous item based on a value. ```ts const nextValue = collection.getNextValue('apple') console.log(nextValue) // banana const previousItem = collection.getPreviousValue('banana') console.log(previousItem) // apple ``` Likewise, use the `firstValue` or `lastValue` computed properties to get the first or last item. ```ts console.log(collection.firstValue) // apple console.log(collection.lastValue) // banana ``` ### Check for value existence Use the `has` method to check if a value exists in the collection. ```ts const hasValue = collection.has('apple') console.log(hasValue) // true ``` ### Working with custom objects If you are working with custom objects, you can pass a function to the `itemToString` and `itemToValue` options to specify how to convert an item to a string and a value, respectively. > By default, we look for the `label` and `value` properties in the item. ```ts import { createListCollection } from '@ark-ui/react/collection' const collection = createListCollection({ items: [ { id: 1, name: 'apple' }, { id: 2, name: 'banana' }, { id: 3, name: 'cherry' }, ], itemToString: (item) => item.name, itemToValue: (item) => item.id, }) ``` To mark an item as disabled, pass a function to the `isItemDisabled` option. > By default, we look for the `disabled` property in the item. ```ts import { createListCollection } from '@ark-ui/react/collection' const collection = createListCollection({ items: [ { id: 1, name: 'apple' }, { id: 2, name: 'banana' }, { id: 3, name: 'cherry' }, ], isItemDisabled: (item) => item.id === 2, }) ``` ### Reorder items Use the `reorder` method to reorder items by passing the starting index and the ending index of the item to be moved. ```ts const fromIndex = 1 // Banana const toIndex = 0 // Apple collection.reorder(fromIndex, toIndex) console.log(collection.items) // [{ label: "Banana", value: "banana" }, { label: "Apple", value: "apple" }] ``` --- # Tree Collection (REACT) A tree collection is designed to manage hierarchical data structures like file systems, navigation menus, or organization charts. It provides powerful methods for traversing, manipulating, and querying tree structures. ```ts import { createTreeCollection } from '@ark-ui/react/collection' const treeData = { value: 'root', label: 'Root', children: [ { value: 'folder1', label: 'Folder 1', children: [ { value: 'file1', label: 'File 1.txt' }, { value: 'file2', label: 'File 2.txt' }, ], }, { value: 'folder2', label: 'Folder 2', children: [ { value: 'subfolder1', label: 'Subfolder 1', children: [{ value: 'file3', label: 'File 3.txt' }], }, ], }, ], } const tree = createTreeCollection({ rootNode: treeData }) ``` ### Navigation Methods The tree collection provides various methods to navigate through the hierarchical structure. #### Getting First and Last Nodes ```ts const firstNode = tree.getFirstNode() console.log(firstNode?.value) // "folder1" const lastNode = tree.getLastNode() console.log(lastNode?.value) // "folder2" ``` #### Sequential Navigation Navigate to the next or previous node in the tree traversal order: ```ts const nextNode = tree.getNextNode('file1') console.log(nextNode?.value) // "file2" const previousNode = tree.getPreviousNode('file2') console.log(previousNode?.value) // "file1" ``` ### Hierarchical Relationships #### Parent and Children Get parent and descendant nodes: ```ts // Get parent node const parentNode = tree.getParentNode('file1') console.log(parentNode?.value) // "folder1" // Get all ancestor nodes const ancestors = tree.getParentNodes('file3') console.log(ancestors.map((n) => n.value)) // ["folder2", "subfolder1"] // Get all descendant nodes const descendants = tree.getDescendantNodes('folder1') console.log(descendants.map((n) => n.value)) // ["file1", "file2"] // Get descendant values only const descendantValues = tree.getDescendantValues('folder2') console.log(descendantValues) // ["subfolder1", "file3"] ``` #### Sibling Navigation Navigate between sibling nodes: ```ts // Assuming we have the index path of "file1" const indexPath = tree.getIndexPath('file1') // [0, 0] const nextSibling = tree.getNextSibling(indexPath) console.log(nextSibling?.value) // "file2" const previousSibling = tree.getPreviousSibling(indexPath) console.log(previousSibling) // undefined (no previous sibling) // Get all siblings const siblings = tree.getSiblingNodes(indexPath) console.log(siblings.map((n) => n.value)) // ["file1", "file2"] ``` ### Index Path Operations Work with index paths to identify node positions: ```ts // Get index path for a value const indexPath = tree.getIndexPath('file3') console.log(indexPath) // [1, 0, 0] // Get value from index path const value = tree.getValue([1, 0, 0]) console.log(value) // "file3" // Get full value path (all ancestors + node) const valuePath = tree.getValuePath([1, 0, 0]) console.log(valuePath) // ["folder2", "subfolder1", "file3"] // Get node at specific index path const node = tree.at([1, 0]) console.log(node?.value) // "subfolder1" ``` ### Tree Queries #### Branch and Leaf Detection ```ts // Check if a node is a branch (has children) const folder1Node = tree.findNode('folder1') const isBranch = tree.isBranchNode(folder1Node!) console.log(isBranch) // true // Get all branch values const branchValues = tree.getBranchValues() console.log(branchValues) // ["folder1", "folder2", "subfolder1"] ``` #### Tree Traversal Visit all nodes with custom logic: ```ts tree.visit({ onEnter: (node, indexPath) => { console.log(`Visiting: ${node.value} at depth ${indexPath.length}`) // Skip certain branches if (node.value === 'folder2') { return 'skip' // Skip this branch and its children } }, }) ``` #### Filtering Create a new tree with filtered nodes: ```ts // Keep only nodes that match criteria const filteredTree = tree.filter((node, indexPath) => { return node.value.includes('file') // Only keep files }) console.log(filteredTree.getValues()) // ["file1", "file2", "file3"] ``` ### Tree Manipulation #### Adding Nodes ```ts const newFile = { value: 'newfile', label: 'New File.txt' } // Insert after a specific node const indexPath = tree.getIndexPath('file1') const updatedTree = tree.insertAfter(indexPath!, [newFile]) // Insert before a specific node const updatedTree2 = tree.insertBefore(indexPath!, [newFile]) ``` #### Removing Nodes ```ts const indexPath = tree.getIndexPath('file2') const updatedTree = tree.remove([indexPath!]) console.log(updatedTree.getValues()) // file2 is removed ``` #### Moving Nodes ```ts const fromIndexPaths = [tree.getIndexPath('file1')!] const toIndexPath = tree.getIndexPath('folder2')! const updatedTree = tree.move(fromIndexPaths, toIndexPath) // file1 is now moved under folder2 ``` #### Replacing Nodes ```ts const indexPath = tree.getIndexPath('file1')! const newNode = { value: 'replacedfile', label: 'Replaced File.txt' } const updatedTree = tree.replace(indexPath, newNode) ``` ### Utility Methods #### Flattening Convert the tree to a flat structure: ```ts const flatNodes = tree.flatten() console.log(flatNodes.map((n) => ({ value: n.value, depth: n._indexPath.length }))) // [{ value: "folder1", depth: 1 }, { value: "file1", depth: 2 }, ...] ``` #### Getting All Values ```ts const allValues = tree.getValues() console.log(allValues) // ["folder1", "file1", "file2", "folder2", "subfolder1", "file3"] ``` #### Depth Calculation ```ts const depth = tree.getDepth('file3') console.log(depth) // 3 (root -> folder2 -> subfolder1 -> file3) ``` ### Working with Custom Node Types You can customize how the tree collection interprets your data: ```ts interface CustomNode { id: string name: string items?: CustomNode[] isDisabled?: boolean } const customTree = createTreeCollection({ rootNode: { id: 'root', name: 'Root', items: [ { id: '1', name: 'Item 1', isDisabled: false }, { id: '2', name: 'Item 2', isDisabled: true }, ], }, nodeToValue: (node) => node.id, nodeToString: (node) => node.name, nodeToChildren: (node) => node.items, isNodeDisabled: (node) => node.isDisabled ?? false, }) ``` ### Creating Trees from File Paths Create a tree structure from file paths: ```ts import { createFileTreeCollection } from '@ark-ui/react/collection' const paths = ['src/components/Button.tsx', 'src/components/Input.tsx', 'src/utils/helpers.ts', 'docs/README.md'] const fileTree = createFileTreeCollection(paths) console.log(fileTree.getBranchValues()) // ["src", "components", "utils", "docs"] ``` > **Good to know**: Tree collections are immutable - all modification methods return a new tree instance rather than > modifying the original. --- # Tree Collection (VUE) A tree collection is designed to manage hierarchical data structures like file systems, navigation menus, or organization charts. It provides powerful methods for traversing, manipulating, and querying tree structures. ```ts import { createTreeCollection } from '@ark-ui/react/collection' const treeData = { value: 'root', label: 'Root', children: [ { value: 'folder1', label: 'Folder 1', children: [ { value: 'file1', label: 'File 1.txt' }, { value: 'file2', label: 'File 2.txt' }, ], }, { value: 'folder2', label: 'Folder 2', children: [ { value: 'subfolder1', label: 'Subfolder 1', children: [{ value: 'file3', label: 'File 3.txt' }], }, ], }, ], } const tree = createTreeCollection({ rootNode: treeData }) ``` ### Navigation Methods The tree collection provides various methods to navigate through the hierarchical structure. #### Getting First and Last Nodes ```ts const firstNode = tree.getFirstNode() console.log(firstNode?.value) // "folder1" const lastNode = tree.getLastNode() console.log(lastNode?.value) // "folder2" ``` #### Sequential Navigation Navigate to the next or previous node in the tree traversal order: ```ts const nextNode = tree.getNextNode('file1') console.log(nextNode?.value) // "file2" const previousNode = tree.getPreviousNode('file2') console.log(previousNode?.value) // "file1" ``` ### Hierarchical Relationships #### Parent and Children Get parent and descendant nodes: ```ts // Get parent node const parentNode = tree.getParentNode('file1') console.log(parentNode?.value) // "folder1" // Get all ancestor nodes const ancestors = tree.getParentNodes('file3') console.log(ancestors.map((n) => n.value)) // ["folder2", "subfolder1"] // Get all descendant nodes const descendants = tree.getDescendantNodes('folder1') console.log(descendants.map((n) => n.value)) // ["file1", "file2"] // Get descendant values only const descendantValues = tree.getDescendantValues('folder2') console.log(descendantValues) // ["subfolder1", "file3"] ``` #### Sibling Navigation Navigate between sibling nodes: ```ts // Assuming we have the index path of "file1" const indexPath = tree.getIndexPath('file1') // [0, 0] const nextSibling = tree.getNextSibling(indexPath) console.log(nextSibling?.value) // "file2" const previousSibling = tree.getPreviousSibling(indexPath) console.log(previousSibling) // undefined (no previous sibling) // Get all siblings const siblings = tree.getSiblingNodes(indexPath) console.log(siblings.map((n) => n.value)) // ["file1", "file2"] ``` ### Index Path Operations Work with index paths to identify node positions: ```ts // Get index path for a value const indexPath = tree.getIndexPath('file3') console.log(indexPath) // [1, 0, 0] // Get value from index path const value = tree.getValue([1, 0, 0]) console.log(value) // "file3" // Get full value path (all ancestors + node) const valuePath = tree.getValuePath([1, 0, 0]) console.log(valuePath) // ["folder2", "subfolder1", "file3"] // Get node at specific index path const node = tree.at([1, 0]) console.log(node?.value) // "subfolder1" ``` ### Tree Queries #### Branch and Leaf Detection ```ts // Check if a node is a branch (has children) const folder1Node = tree.findNode('folder1') const isBranch = tree.isBranchNode(folder1Node!) console.log(isBranch) // true // Get all branch values const branchValues = tree.getBranchValues() console.log(branchValues) // ["folder1", "folder2", "subfolder1"] ``` #### Tree Traversal Visit all nodes with custom logic: ```ts tree.visit({ onEnter: (node, indexPath) => { console.log(`Visiting: ${node.value} at depth ${indexPath.length}`) // Skip certain branches if (node.value === 'folder2') { return 'skip' // Skip this branch and its children } }, }) ``` #### Filtering Create a new tree with filtered nodes: ```ts // Keep only nodes that match criteria const filteredTree = tree.filter((node, indexPath) => { return node.value.includes('file') // Only keep files }) console.log(filteredTree.getValues()) // ["file1", "file2", "file3"] ``` ### Tree Manipulation #### Adding Nodes ```ts const newFile = { value: 'newfile', label: 'New File.txt' } // Insert after a specific node const indexPath = tree.getIndexPath('file1') const updatedTree = tree.insertAfter(indexPath!, [newFile]) // Insert before a specific node const updatedTree2 = tree.insertBefore(indexPath!, [newFile]) ``` #### Removing Nodes ```ts const indexPath = tree.getIndexPath('file2') const updatedTree = tree.remove([indexPath!]) console.log(updatedTree.getValues()) // file2 is removed ``` #### Moving Nodes ```ts const fromIndexPaths = [tree.getIndexPath('file1')!] const toIndexPath = tree.getIndexPath('folder2')! const updatedTree = tree.move(fromIndexPaths, toIndexPath) // file1 is now moved under folder2 ``` #### Replacing Nodes ```ts const indexPath = tree.getIndexPath('file1')! const newNode = { value: 'replacedfile', label: 'Replaced File.txt' } const updatedTree = tree.replace(indexPath, newNode) ``` ### Utility Methods #### Flattening Convert the tree to a flat structure: ```ts const flatNodes = tree.flatten() console.log(flatNodes.map((n) => ({ value: n.value, depth: n._indexPath.length }))) // [{ value: "folder1", depth: 1 }, { value: "file1", depth: 2 }, ...] ``` #### Getting All Values ```ts const allValues = tree.getValues() console.log(allValues) // ["folder1", "file1", "file2", "folder2", "subfolder1", "file3"] ``` #### Depth Calculation ```ts const depth = tree.getDepth('file3') console.log(depth) // 3 (root -> folder2 -> subfolder1 -> file3) ``` ### Working with Custom Node Types You can customize how the tree collection interprets your data: ```ts interface CustomNode { id: string name: string items?: CustomNode[] isDisabled?: boolean } const customTree = createTreeCollection({ rootNode: { id: 'root', name: 'Root', items: [ { id: '1', name: 'Item 1', isDisabled: false }, { id: '2', name: 'Item 2', isDisabled: true }, ], }, nodeToValue: (node) => node.id, nodeToString: (node) => node.name, nodeToChildren: (node) => node.items, isNodeDisabled: (node) => node.isDisabled ?? false, }) ``` ### Creating Trees from File Paths Create a tree structure from file paths: ```ts import { createFileTreeCollection } from '@ark-ui/react/collection' const paths = ['src/components/Button.tsx', 'src/components/Input.tsx', 'src/utils/helpers.ts', 'docs/README.md'] const fileTree = createFileTreeCollection(paths) console.log(fileTree.getBranchValues()) // ["src", "components", "utils", "docs"] ``` > **Good to know**: Tree collections are immutable - all modification methods return a new tree instance rather than > modifying the original. --- # Tree Collection (SVELTE) A tree collection is designed to manage hierarchical data structures like file systems, navigation menus, or organization charts. It provides powerful methods for traversing, manipulating, and querying tree structures. ```ts import { createTreeCollection } from '@ark-ui/react/collection' const treeData = { value: 'root', label: 'Root', children: [ { value: 'folder1', label: 'Folder 1', children: [ { value: 'file1', label: 'File 1.txt' }, { value: 'file2', label: 'File 2.txt' }, ], }, { value: 'folder2', label: 'Folder 2', children: [ { value: 'subfolder1', label: 'Subfolder 1', children: [{ value: 'file3', label: 'File 3.txt' }], }, ], }, ], } const tree = createTreeCollection({ rootNode: treeData }) ``` ### Navigation Methods The tree collection provides various methods to navigate through the hierarchical structure. #### Getting First and Last Nodes ```ts const firstNode = tree.getFirstNode() console.log(firstNode?.value) // "folder1" const lastNode = tree.getLastNode() console.log(lastNode?.value) // "folder2" ``` #### Sequential Navigation Navigate to the next or previous node in the tree traversal order: ```ts const nextNode = tree.getNextNode('file1') console.log(nextNode?.value) // "file2" const previousNode = tree.getPreviousNode('file2') console.log(previousNode?.value) // "file1" ``` ### Hierarchical Relationships #### Parent and Children Get parent and descendant nodes: ```ts // Get parent node const parentNode = tree.getParentNode('file1') console.log(parentNode?.value) // "folder1" // Get all ancestor nodes const ancestors = tree.getParentNodes('file3') console.log(ancestors.map((n) => n.value)) // ["folder2", "subfolder1"] // Get all descendant nodes const descendants = tree.getDescendantNodes('folder1') console.log(descendants.map((n) => n.value)) // ["file1", "file2"] // Get descendant values only const descendantValues = tree.getDescendantValues('folder2') console.log(descendantValues) // ["subfolder1", "file3"] ``` #### Sibling Navigation Navigate between sibling nodes: ```ts // Assuming we have the index path of "file1" const indexPath = tree.getIndexPath('file1') // [0, 0] const nextSibling = tree.getNextSibling(indexPath) console.log(nextSibling?.value) // "file2" const previousSibling = tree.getPreviousSibling(indexPath) console.log(previousSibling) // undefined (no previous sibling) // Get all siblings const siblings = tree.getSiblingNodes(indexPath) console.log(siblings.map((n) => n.value)) // ["file1", "file2"] ``` ### Index Path Operations Work with index paths to identify node positions: ```ts // Get index path for a value const indexPath = tree.getIndexPath('file3') console.log(indexPath) // [1, 0, 0] // Get value from index path const value = tree.getValue([1, 0, 0]) console.log(value) // "file3" // Get full value path (all ancestors + node) const valuePath = tree.getValuePath([1, 0, 0]) console.log(valuePath) // ["folder2", "subfolder1", "file3"] // Get node at specific index path const node = tree.at([1, 0]) console.log(node?.value) // "subfolder1" ``` ### Tree Queries #### Branch and Leaf Detection ```ts // Check if a node is a branch (has children) const folder1Node = tree.findNode('folder1') const isBranch = tree.isBranchNode(folder1Node!) console.log(isBranch) // true // Get all branch values const branchValues = tree.getBranchValues() console.log(branchValues) // ["folder1", "folder2", "subfolder1"] ``` #### Tree Traversal Visit all nodes with custom logic: ```ts tree.visit({ onEnter: (node, indexPath) => { console.log(`Visiting: ${node.value} at depth ${indexPath.length}`) // Skip certain branches if (node.value === 'folder2') { return 'skip' // Skip this branch and its children } }, }) ``` #### Filtering Create a new tree with filtered nodes: ```ts // Keep only nodes that match criteria const filteredTree = tree.filter((node, indexPath) => { return node.value.includes('file') // Only keep files }) console.log(filteredTree.getValues()) // ["file1", "file2", "file3"] ``` ### Tree Manipulation #### Adding Nodes ```ts const newFile = { value: 'newfile', label: 'New File.txt' } // Insert after a specific node const indexPath = tree.getIndexPath('file1') const updatedTree = tree.insertAfter(indexPath!, [newFile]) // Insert before a specific node const updatedTree2 = tree.insertBefore(indexPath!, [newFile]) ``` #### Removing Nodes ```ts const indexPath = tree.getIndexPath('file2') const updatedTree = tree.remove([indexPath!]) console.log(updatedTree.getValues()) // file2 is removed ``` #### Moving Nodes ```ts const fromIndexPaths = [tree.getIndexPath('file1')!] const toIndexPath = tree.getIndexPath('folder2')! const updatedTree = tree.move(fromIndexPaths, toIndexPath) // file1 is now moved under folder2 ``` #### Replacing Nodes ```ts const indexPath = tree.getIndexPath('file1')! const newNode = { value: 'replacedfile', label: 'Replaced File.txt' } const updatedTree = tree.replace(indexPath, newNode) ``` ### Utility Methods #### Flattening Convert the tree to a flat structure: ```ts const flatNodes = tree.flatten() console.log(flatNodes.map((n) => ({ value: n.value, depth: n._indexPath.length }))) // [{ value: "folder1", depth: 1 }, { value: "file1", depth: 2 }, ...] ``` #### Getting All Values ```ts const allValues = tree.getValues() console.log(allValues) // ["folder1", "file1", "file2", "folder2", "subfolder1", "file3"] ``` #### Depth Calculation ```ts const depth = tree.getDepth('file3') console.log(depth) // 3 (root -> folder2 -> subfolder1 -> file3) ``` ### Working with Custom Node Types You can customize how the tree collection interprets your data: ```ts interface CustomNode { id: string name: string items?: CustomNode[] isDisabled?: boolean } const customTree = createTreeCollection({ rootNode: { id: 'root', name: 'Root', items: [ { id: '1', name: 'Item 1', isDisabled: false }, { id: '2', name: 'Item 2', isDisabled: true }, ], }, nodeToValue: (node) => node.id, nodeToString: (node) => node.name, nodeToChildren: (node) => node.items, isNodeDisabled: (node) => node.isDisabled ?? false, }) ``` ### Creating Trees from File Paths Create a tree structure from file paths: ```ts import { createFileTreeCollection } from '@ark-ui/react/collection' const paths = ['src/components/Button.tsx', 'src/components/Input.tsx', 'src/utils/helpers.ts', 'docs/README.md'] const fileTree = createFileTreeCollection(paths) console.log(fileTree.getBranchValues()) // ["src", "components", "utils", "docs"] ``` > **Good to know**: Tree collections are immutable - all modification methods return a new tree instance rather than > modifying the original. --- # Tree Collection (SOLID) A tree collection is designed to manage hierarchical data structures like file systems, navigation menus, or organization charts. It provides powerful methods for traversing, manipulating, and querying tree structures. ```ts import { createTreeCollection } from '@ark-ui/react/collection' const treeData = { value: 'root', label: 'Root', children: [ { value: 'folder1', label: 'Folder 1', children: [ { value: 'file1', label: 'File 1.txt' }, { value: 'file2', label: 'File 2.txt' }, ], }, { value: 'folder2', label: 'Folder 2', children: [ { value: 'subfolder1', label: 'Subfolder 1', children: [{ value: 'file3', label: 'File 3.txt' }], }, ], }, ], } const tree = createTreeCollection({ rootNode: treeData }) ``` ### Navigation Methods The tree collection provides various methods to navigate through the hierarchical structure. #### Getting First and Last Nodes ```ts const firstNode = tree.getFirstNode() console.log(firstNode?.value) // "folder1" const lastNode = tree.getLastNode() console.log(lastNode?.value) // "folder2" ``` #### Sequential Navigation Navigate to the next or previous node in the tree traversal order: ```ts const nextNode = tree.getNextNode('file1') console.log(nextNode?.value) // "file2" const previousNode = tree.getPreviousNode('file2') console.log(previousNode?.value) // "file1" ``` ### Hierarchical Relationships #### Parent and Children Get parent and descendant nodes: ```ts // Get parent node const parentNode = tree.getParentNode('file1') console.log(parentNode?.value) // "folder1" // Get all ancestor nodes const ancestors = tree.getParentNodes('file3') console.log(ancestors.map((n) => n.value)) // ["folder2", "subfolder1"] // Get all descendant nodes const descendants = tree.getDescendantNodes('folder1') console.log(descendants.map((n) => n.value)) // ["file1", "file2"] // Get descendant values only const descendantValues = tree.getDescendantValues('folder2') console.log(descendantValues) // ["subfolder1", "file3"] ``` #### Sibling Navigation Navigate between sibling nodes: ```ts // Assuming we have the index path of "file1" const indexPath = tree.getIndexPath('file1') // [0, 0] const nextSibling = tree.getNextSibling(indexPath) console.log(nextSibling?.value) // "file2" const previousSibling = tree.getPreviousSibling(indexPath) console.log(previousSibling) // undefined (no previous sibling) // Get all siblings const siblings = tree.getSiblingNodes(indexPath) console.log(siblings.map((n) => n.value)) // ["file1", "file2"] ``` ### Index Path Operations Work with index paths to identify node positions: ```ts // Get index path for a value const indexPath = tree.getIndexPath('file3') console.log(indexPath) // [1, 0, 0] // Get value from index path const value = tree.getValue([1, 0, 0]) console.log(value) // "file3" // Get full value path (all ancestors + node) const valuePath = tree.getValuePath([1, 0, 0]) console.log(valuePath) // ["folder2", "subfolder1", "file3"] // Get node at specific index path const node = tree.at([1, 0]) console.log(node?.value) // "subfolder1" ``` ### Tree Queries #### Branch and Leaf Detection ```ts // Check if a node is a branch (has children) const folder1Node = tree.findNode('folder1') const isBranch = tree.isBranchNode(folder1Node!) console.log(isBranch) // true // Get all branch values const branchValues = tree.getBranchValues() console.log(branchValues) // ["folder1", "folder2", "subfolder1"] ``` #### Tree Traversal Visit all nodes with custom logic: ```ts tree.visit({ onEnter: (node, indexPath) => { console.log(`Visiting: ${node.value} at depth ${indexPath.length}`) // Skip certain branches if (node.value === 'folder2') { return 'skip' // Skip this branch and its children } }, }) ``` #### Filtering Create a new tree with filtered nodes: ```ts // Keep only nodes that match criteria const filteredTree = tree.filter((node, indexPath) => { return node.value.includes('file') // Only keep files }) console.log(filteredTree.getValues()) // ["file1", "file2", "file3"] ``` ### Tree Manipulation #### Adding Nodes ```ts const newFile = { value: 'newfile', label: 'New File.txt' } // Insert after a specific node const indexPath = tree.getIndexPath('file1') const updatedTree = tree.insertAfter(indexPath!, [newFile]) // Insert before a specific node const updatedTree2 = tree.insertBefore(indexPath!, [newFile]) ``` #### Removing Nodes ```ts const indexPath = tree.getIndexPath('file2') const updatedTree = tree.remove([indexPath!]) console.log(updatedTree.getValues()) // file2 is removed ``` #### Moving Nodes ```ts const fromIndexPaths = [tree.getIndexPath('file1')!] const toIndexPath = tree.getIndexPath('folder2')! const updatedTree = tree.move(fromIndexPaths, toIndexPath) // file1 is now moved under folder2 ``` #### Replacing Nodes ```ts const indexPath = tree.getIndexPath('file1')! const newNode = { value: 'replacedfile', label: 'Replaced File.txt' } const updatedTree = tree.replace(indexPath, newNode) ``` ### Utility Methods #### Flattening Convert the tree to a flat structure: ```ts const flatNodes = tree.flatten() console.log(flatNodes.map((n) => ({ value: n.value, depth: n._indexPath.length }))) // [{ value: "folder1", depth: 1 }, { value: "file1", depth: 2 }, ...] ``` #### Getting All Values ```ts const allValues = tree.getValues() console.log(allValues) // ["folder1", "file1", "file2", "folder2", "subfolder1", "file3"] ``` #### Depth Calculation ```ts const depth = tree.getDepth('file3') console.log(depth) // 3 (root -> folder2 -> subfolder1 -> file3) ``` ### Working with Custom Node Types You can customize how the tree collection interprets your data: ```ts interface CustomNode { id: string name: string items?: CustomNode[] isDisabled?: boolean } const customTree = createTreeCollection({ rootNode: { id: 'root', name: 'Root', items: [ { id: '1', name: 'Item 1', isDisabled: false }, { id: '2', name: 'Item 2', isDisabled: true }, ], }, nodeToValue: (node) => node.id, nodeToString: (node) => node.name, nodeToChildren: (node) => node.items, isNodeDisabled: (node) => node.isDisabled ?? false, }) ``` ### Creating Trees from File Paths Create a tree structure from file paths: ```ts import { createFileTreeCollection } from '@ark-ui/react/collection' const paths = ['src/components/Button.tsx', 'src/components/Input.tsx', 'src/utils/helpers.ts', 'docs/README.md'] const fileTree = createFileTreeCollection(paths) console.log(fileTree.getBranchValues()) // ["src", "components", "utils", "docs"] ``` > **Good to know**: Tree collections are immutable - all modification methods return a new tree instance rather than > modifying the original. --- # Async List (REACT) The `useAsyncList` hook manages asynchronous data operations for list collections. It provides a comprehensive solution for loading, filtering, sorting, and paginating data with built-in loading states, error handling, and request cancellation. ```tsx import { useAsyncList } from '@ark-ui/react/collection' const list = useAsyncList({ async load({ signal }) { const response = await fetch('/api/users', { signal }) const users = await response.json() return { items: users } }, }) console.log(list.items) // User[] console.log(list.loading) // boolean console.log(list.error) // Error | null ``` ## Examples ### Loading Data Load data asynchronously from an API using the `load` function and update the list when the data is ready. **Example: async-list/reload** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { LoaderIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' interface Quote { id: number quote: string author: string } export const Reload = () => { const list = useAsyncList({ autoReload: true, async load() { const response = await fetch(`https://dummyjson.com/quotes?limit=4&skip=${Math.floor(Math.random() * 50)}`) if (!response.ok) { throw new Error('Failed to fetch quotes') } const data = await response.json() return { items: data.quotes } }, }) return (
                    {list.error &&
                    Error: {list.error.message}
                    }
                    {list.items.map((quote) => (
                    "{quote.quote}"
                    — {quote.author}
                    ))}
                    ) } ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' interface Quote { id: number quote: string author: string } export const Reload = () => { const list = useAsyncList({ autoReload: true, async load() { const response = await fetch(`https://dummyjson.com/quotes?limit=4&skip=${Math.floor(Math.random() * 50)}`) if (!response.ok) { throw new Error('Failed to fetch quotes') } const data = await response.json() return { items: data.quotes } }, }) return (
                    {list().error &&
                    Error: {list().error.message}
                    }
                    {(quote) => (
                    "{quote.quote}"
                    — {quote.author}
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    {#each list().items as quote}
                    "{quote.quote}"
                    — {quote.author}
                    {/each}
                    ``` ### Infinite Loading Implement pagination by returning a cursor that indicates more data is available. **Example: async-list/infinite-loading** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { LoaderIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 4 interface Post { userId: number id: number title: string body: string } export const InfiniteLoading = () => { const list = useAsyncList({ autoReload: true, async load({ cursor }) { const page = cursor || 1 const start = (page - 1) * LIMIT const response = await fetch(`https://jsonplaceholder.typicode.com/posts?_start=${start}&_limit=${LIMIT}`) if (!response.ok) { throw new Error('Failed to fetch posts') } const posts: Post[] = await response.json() const hasNextPage = posts.length === LIMIT return { items: posts, cursor: hasNextPage ? page + 1 : undefined, } }, }) return (
                    Loaded {list.items.length} posts {list.cursor && ` (more available)`} {list.cursor && ( )}
                    {list.error &&
                    Error: {list.error.message}
                    }
                    {list.items.map((post, index) => (
                    {index + 1}. {post.title}
                    {post.body}
                    ))}
                    ) } ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 4 interface Post { userId: number id: number title: string body: string } export const InfiniteLoading = () => { const list = useAsyncList({ autoReload: true, async load({ cursor }) { const page = cursor || 1 const start = (page - 1) * LIMIT const response = await fetch(`https://jsonplaceholder.typicode.com/posts?_start=${start}&_limit=${LIMIT}`) if (!response.ok) { throw new Error('Failed to fetch posts') } const posts: Post[] = await response.json() const hasNextPage = posts.length === LIMIT return { items: posts, cursor: hasNextPage ? page + 1 : undefined, } }, }) return (
                    Loaded {list().items.length} posts {list().cursor && ` (more available)`} {list().cursor && ( )}
                    {list().error &&
                    Error: {list().error.message}
                    }
                    {(post, index) => (
                    {index() + 1}. {post.title}
                    {post.body}
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Loaded {list().items.length} posts {#if list().cursor}(more available){/if} {#if list().cursor} {/if}
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    {#each list().items as post, index}
                    {index + 1}. {post.title}
                    {post.body}
                    {/each}
                    ``` ### Filtering Filter data based on user input with automatic debouncing and loading states. **Example: async-list/filter** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { LoaderIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 4 interface User { id: number name: string email: string department: string role: string } export const Filter = () => { const list = useAsyncList({ initialItems: mockUsers.slice(0, LIMIT), async load({ filterText }) { await delay(500) if (!filterText) { return { items: mockUsers.slice(0, LIMIT) } } const filtered = mockUsers.filter( (user) => user.name.toLowerCase().includes(filterText.toLowerCase()) || user.email.toLowerCase().includes(filterText.toLowerCase()), ) return { items: filtered.slice(0, LIMIT) } }, }) return (
                    list.setFilterText(e.target.value)} /> {list.loading && ( Searching )}
                    {list.error &&
                    Error: {list.error.message}
                    }
                    {list.items.map((user) => (
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    ))}
                    {list.items.length === 0 && !list.loading &&
                    No results found
                    }
                    ) } const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) const mockUsers: User[] = [ { id: 1, name: 'Alice Johnson', email: 'alice@example.com', department: 'Engineering', role: 'Senior Developer' }, { id: 2, name: 'Bob Smith', email: 'bob@example.com', department: 'Marketing', role: 'Marketing Manager' }, { id: 3, name: 'Carol Davis', email: 'carol@example.com', department: 'Engineering', role: 'Frontend Developer' }, { id: 4, name: 'David Wilson', email: 'david@example.com', department: 'Sales', role: 'Sales Representative' }, { id: 5, name: 'Eva Brown', email: 'eva@example.com', department: 'Engineering', role: 'DevOps Engineer' }, { id: 6, name: 'Frank Miller', email: 'frank@example.com', department: 'Support', role: 'Customer Success' }, { id: 7, name: 'Grace Lee', email: 'grace@example.com', department: 'Marketing', role: 'Content Creator' }, { id: 8, name: 'Henry Taylor', email: 'henry@example.com', department: 'Engineering', role: 'Backend Developer' }, { id: 9, name: 'Ivy Anderson', email: 'ivy@example.com', department: 'Sales', role: 'Account Manager' }, { id: 10, name: 'Jack Thompson', email: 'jack@example.com', department: 'Support', role: 'Technical Support' }, { id: 11, name: 'Kate Martinez', email: 'kate@example.com', department: 'Marketing', role: 'Brand Manager' }, { id: 12, name: 'Liam Garcia', email: 'liam@example.com', department: 'Engineering', role: 'Full Stack Developer' }, { id: 13, name: 'Mia Rodriguez', email: 'mia@example.com', department: 'Sales', role: 'Sales Director' }, { id: 14, name: 'Noah Lopez', email: 'noah@example.com', department: 'Support', role: 'Support Manager' }, { id: 15, name: 'Olivia White', email: 'olivia@example.com', department: 'Engineering', role: 'UI Designer' }, { id: 16, name: 'Paul Harris', email: 'paul@example.com', department: 'Marketing', role: 'Digital Marketer' }, { id: 17, name: 'Quinn Clark', email: 'quinn@example.com', department: 'Engineering', role: 'Mobile Developer' }, { id: 18, name: 'Ruby Lewis', email: 'ruby@example.com', department: 'Sales', role: 'Business Development' }, { id: 19, name: 'Sam Young', email: 'sam@example.com', department: 'Support', role: 'Documentation Specialist' }, { id: 20, name: 'Tina Walker', email: 'tina@example.com', department: 'Marketing', role: 'Social Media Manager' }, ] ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 4 interface User { id: number name: string email: string department: string role: string } export const Filter = () => { const list = useAsyncList({ initialItems: mockUsers.slice(0, LIMIT), async load({ filterText }: { filterText?: string }) { await delay(500) if (!filterText) { return { items: mockUsers.slice(0, LIMIT) } } const filtered = mockUsers.filter( (user) => user.name.toLowerCase().includes(filterText.toLowerCase()) || user.email.toLowerCase().includes(filterText.toLowerCase()), ) return { items: filtered.slice(0, LIMIT) } }, }) return (
                    list().setFilterText(e.target.value)} /> {list().loading && ( Searching )}
                    {list().error &&
                    Error: {list().error.message}
                    }
                    {(user) => (
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    )}
                    {list().items.length === 0 && !list().loading &&
                    No results found
                    }
                    ) } const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) const mockUsers: User[] = [ { id: 1, name: 'Alice Johnson', email: 'alice@example.com', department: 'Engineering', role: 'Senior Developer' }, { id: 2, name: 'Bob Smith', email: 'bob@example.com', department: 'Marketing', role: 'Marketing Manager' }, { id: 3, name: 'Carol Davis', email: 'carol@example.com', department: 'Engineering', role: 'Frontend Developer' }, { id: 4, name: 'David Wilson', email: 'david@example.com', department: 'Sales', role: 'Sales Representative' }, { id: 5, name: 'Eva Brown', email: 'eva@example.com', department: 'Engineering', role: 'DevOps Engineer' }, { id: 6, name: 'Frank Miller', email: 'frank@example.com', department: 'Support', role: 'Customer Success' }, { id: 7, name: 'Grace Lee', email: 'grace@example.com', department: 'Marketing', role: 'Content Creator' }, { id: 8, name: 'Henry Taylor', email: 'henry@example.com', department: 'Engineering', role: 'Backend Developer' }, { id: 9, name: 'Ivy Anderson', email: 'ivy@example.com', department: 'Sales', role: 'Account Manager' }, { id: 10, name: 'Jack Thompson', email: 'jack@example.com', department: 'Support', role: 'Technical Support' }, { id: 11, name: 'Kate Martinez', email: 'kate@example.com', department: 'Marketing', role: 'Brand Manager' }, { id: 12, name: 'Liam Garcia', email: 'liam@example.com', department: 'Engineering', role: 'Full Stack Developer' }, { id: 13, name: 'Mia Rodriguez', email: 'mia@example.com', department: 'Sales', role: 'Sales Director' }, { id: 14, name: 'Noah Lopez', email: 'noah@example.com', department: 'Support', role: 'Support Manager' }, { id: 15, name: 'Olivia White', email: 'olivia@example.com', department: 'Engineering', role: 'UI Designer' }, { id: 16, name: 'Paul Harris', email: 'paul@example.com', department: 'Marketing', role: 'Digital Marketer' }, { id: 17, name: 'Quinn Clark', email: 'quinn@example.com', department: 'Engineering', role: 'Mobile Developer' }, { id: 18, name: 'Ruby Lewis', email: 'ruby@example.com', department: 'Sales', role: 'Business Development' }, { id: 19, name: 'Sam Young', email: 'sam@example.com', department: 'Support', role: 'Documentation Specialist' }, { id: 20, name: 'Tina Walker', email: 'tina@example.com', department: 'Marketing', role: 'Social Media Manager' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    list().setFilterText(e.currentTarget.value)} /> {#if list().loading} Searching {/if}
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    {#each list().items as user}
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    {/each}
                    {#if list().items.length === 0 && !list().loading}
                    No results found
                    {/if}
                    ``` ### Sorting (Client-side) Sort data on the client side after loading from the server. **Example: async-list/sort-client-side** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { useCollator } from '@ark-ui/react/locale' import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon, LoaderIcon } from 'lucide-react' import styles from 'styles/async-list.module.css' interface User { id: number name: string username: string email: string phone: string website: string } export const SortClientSide = () => { const collator = useCollator() const list = useAsyncList({ autoReload: true, load: async () => { const response = await fetch('https://jsonplaceholder.typicode.com/users?_limit=5') const data = await response.json() return { items: data } }, sort({ items, descriptor }) { return { items: items.sort((a, b) => { const { column, direction } = descriptor let cmp = collator.compare(String(a[column]), String(b[column])) if (direction === 'descending') { cmp *= -1 } return cmp }), } }, }) const handleSort = (column: keyof User) => { const currentSort = list.sortDescriptor let direction: 'ascending' | 'descending' = 'ascending' if (currentSort?.column === column && currentSort.direction === 'ascending') { direction = 'descending' } list.sort({ column, direction }) } const getSortIcon = (column: keyof User) => { const current = list.sortDescriptor if (current?.column !== column) return return current.direction === 'ascending' ? : } const descriptor = list.sortDescriptor return (
                    {list.loading && (
                    Loading
                    )} {list.error &&
                    Error: {list.error.message}
                    }
                    Sorted by: {descriptor ? `${descriptor.column} (${descriptor.direction})` : 'none'}
                    {[ { key: 'name', label: 'Name' }, { key: 'username', label: 'Username' }, { key: 'email', label: 'Email' }, ].map(({ key, label }) => ( ))} {list.items.map((user) => ( ))}
                    handleSort(key as keyof User)}> {label} {getSortIcon(key as keyof User)}
                    {user.name} {user.username} {user.email}
                    ) } ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { useCollator } from '@ark-ui/solid/locale' import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon, LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/async-list.module.css' interface User { id: number name: string username: string email: string phone: string website: string } export const SortClientSide = () => { const collator = useCollator() const list = useAsyncList({ autoReload: true, load: async () => { const response = await fetch('https://jsonplaceholder.typicode.com/users?_limit=5') const data = await response.json() return { items: data } }, sort({ items, descriptor }) { return { items: items.sort((a, b) => { const { column, direction } = descriptor let cmp = collator().compare(String(a[column]), String(b[column])) if (direction === 'descending') { cmp *= -1 } return cmp }), } }, }) const handleSort = (column: keyof User) => { const currentSort = list().sortDescriptor let direction: 'ascending' | 'descending' = 'ascending' if (currentSort?.column === column && currentSort.direction === 'ascending') { direction = 'descending' } list().sort({ column, direction }) } const getSortIcon = (column: keyof User) => { const current = list().sortDescriptor if (current?.column !== column) return return current.direction === 'ascending' ? : } const descriptor = () => list().sortDescriptor return (
                    {list().loading && (
                    Loading
                    )} {list().error &&
                    Error: {list().error.message}
                    }
                    Sorted by: {descriptor() ? `${descriptor()?.column} (${descriptor()?.direction})` : 'none'}
                    {({ key, label }) => ( )} {(user) => ( )}
                    handleSort(key as keyof User)}> {label} {getSortIcon(key as keyof User)}
                    {user.name} {user.username} {user.email}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#if list().loading}
                    Loading
                    {/if} {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    Sorted by: {descriptor ? `${descriptor.column} (${descriptor.direction})` : 'none'}
                    {#each columns as { key, label }} {/each} {#each list().items as user} {/each}
                    handleSort(key as keyof User)}> {label} {#if list().sortDescriptor?.column === key} {#if list().sortDescriptor?.direction === 'ascending'} {:else} {/if} {:else} {/if}
                    {user.name} {user.username} {user.email}
                    ``` ### Sorting (Server-side) Send sort parameters to the server and reload data when sorting changes. **Example: async-list/sort-server-side** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon, LoaderIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' interface Product { id: number title: string price: number description: string category: string image: string rating: { rate: number count: number } } export const SortServerSide = () => { const list = useAsyncList({ autoReload: true, async load({ sortDescriptor }) { const url = new URL('https://fakestoreapi.com/products') url.searchParams.set('limit', '5') if (sortDescriptor) { const { direction } = sortDescriptor url.searchParams.set('sort', direction === 'ascending' ? 'asc' : 'desc') } const response = await fetch(url) const items = await response.json() return { items } }, }) const handleSort = (column: keyof Product) => { const currentSort = list.sortDescriptor let direction: 'ascending' | 'descending' = 'ascending' if (currentSort?.column === column && currentSort.direction === 'ascending') { direction = 'descending' } list.sort({ column, direction }) } const getSortIcon = (column: keyof Product) => { const desc = list.sortDescriptor if (desc?.column !== column) return return desc.direction === 'ascending' ? : } return (
                    {list.loading && ( Loading )}
                    {list.error &&
                    Error: {list.error.message}
                    }
                    {list.items.map((product) => (
                    {product.title}
                    {product.title}
                    ${product.price}
                    {product.category} • {product.rating.rate} ({product.rating.count} reviews)
                    ))}
                    ) } ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon, LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' interface Product { id: number title: string price: number description: string category: string image: string rating: { rate: number count: number } } export const SortServerSide = () => { const list = useAsyncList({ autoReload: true, async load({ sortDescriptor }) { const url = new URL('https://fakestoreapi.com/products') url.searchParams.set('limit', '5') if (sortDescriptor) { const { direction } = sortDescriptor url.searchParams.set('sort', direction === 'ascending' ? 'asc' : 'desc') } const response = await fetch(url) const items = await response.json() return { items } }, }) const handleSort = (column: keyof Product) => { const currentSort = list().sortDescriptor let direction: 'ascending' | 'descending' = 'ascending' if (currentSort?.column === column && currentSort.direction === 'ascending') { direction = 'descending' } list().sort({ column, direction }) } const getSortIcon = (column: keyof Product) => { const desc = list().sortDescriptor if (desc?.column !== column) return return desc.direction === 'ascending' ? : } return (
                    {list().loading && ( Loading )}
                    {list().error &&
                    Error: {list().error.message}
                    }
                    {(product) => (
                    {product.title}
                    {product.title}
                    ${product.price}
                    {product.category} • {product.rating.rate} ({product.rating.count} reviews)
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#if list().loading} Loading {/if}
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    {#each list().items as product}
                    {product.title}
                    {product.title}
                    ${product.price}
                    {product.category} • {product.rating.rate} ({product.rating.count} reviews)
                    {/each}
                    ``` ### Dependencies Automatically reload data when dependencies change, such as filter selections or external state. **Example: async-list/dependencies** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { LoaderIcon } from 'lucide-react' import { useState } from 'react' import field from 'styles/field.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 5 interface User { id: number name: string email: string department: string role: string } export const Dependencies = () => { const [selectedDepartment, setSelectedDepartment] = useState('') const [selectedRole, setSelectedRole] = useState('') const list = useAsyncList({ initialItems: mockUsers.slice(0, LIMIT), dependencies: [selectedDepartment, selectedRole], async load({ filterText }) { await delay(400) let items = mockUsers if (selectedDepartment) { items = items.filter((user) => user.department === selectedDepartment) } if (selectedRole) { items = items.filter((user) => user.role === selectedRole) } if (filterText) { items = items.filter( (user) => user.name.toLowerCase().includes(filterText.toLowerCase()) || user.email.toLowerCase().includes(filterText.toLowerCase()), ) } return { items: items.slice(0, LIMIT) } }, }) return (
                    list.setFilterText(e.target.value)} /> {list.loading && ( Loading )}
                    {list.error &&
                    Error: {list.error.message}
                    }
                    Found {list.items.length} users
                    {list.items.map((user) => (
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    ))}
                    {list.items.length === 0 && !list.loading && (
                    No users found with current filters
                    )}
                    ) } const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) const departments = ['Engineering', 'Marketing', 'Sales', 'Support'] const roles = [ 'Senior Developer', 'Marketing Manager', 'Frontend Developer', 'Sales Representative', 'DevOps Engineer', 'Customer Success', 'Content Creator', 'Backend Developer', 'Account Manager', 'Technical Support', 'Brand Manager', 'Full Stack Developer', 'Sales Director', 'Support Manager', 'UI Designer', 'Digital Marketer', 'Mobile Developer', 'Business Development', 'Documentation Specialist', 'Social Media Manager', ] const mockUsers: User[] = [ { id: 1, name: 'Alice Johnson', email: 'alice@example.com', department: 'Engineering', role: 'Senior Developer' }, { id: 2, name: 'Bob Smith', email: 'bob@example.com', department: 'Marketing', role: 'Marketing Manager' }, { id: 3, name: 'Carol Davis', email: 'carol@example.com', department: 'Engineering', role: 'Frontend Developer' }, { id: 4, name: 'David Wilson', email: 'david@example.com', department: 'Sales', role: 'Sales Representative' }, { id: 5, name: 'Eva Brown', email: 'eva@example.com', department: 'Engineering', role: 'DevOps Engineer' }, { id: 6, name: 'Frank Miller', email: 'frank@example.com', department: 'Support', role: 'Customer Success' }, { id: 7, name: 'Grace Lee', email: 'grace@example.com', department: 'Marketing', role: 'Content Creator' }, { id: 8, name: 'Henry Taylor', email: 'henry@example.com', department: 'Engineering', role: 'Backend Developer' }, { id: 9, name: 'Ivy Anderson', email: 'ivy@example.com', department: 'Sales', role: 'Account Manager' }, { id: 10, name: 'Jack Thompson', email: 'jack@example.com', department: 'Support', role: 'Technical Support' }, { id: 11, name: 'Kate Martinez', email: 'kate@example.com', department: 'Marketing', role: 'Brand Manager' }, { id: 12, name: 'Liam Garcia', email: 'liam@example.com', department: 'Engineering', role: 'Full Stack Developer' }, { id: 13, name: 'Mia Rodriguez', email: 'mia@example.com', department: 'Sales', role: 'Sales Director' }, { id: 14, name: 'Noah Lopez', email: 'noah@example.com', department: 'Support', role: 'Support Manager' }, { id: 15, name: 'Olivia White', email: 'olivia@example.com', department: 'Engineering', role: 'UI Designer' }, { id: 16, name: 'Paul Harris', email: 'paul@example.com', department: 'Marketing', role: 'Digital Marketer' }, { id: 17, name: 'Quinn Clark', email: 'quinn@example.com', department: 'Engineering', role: 'Mobile Developer' }, { id: 18, name: 'Ruby Lewis', email: 'ruby@example.com', department: 'Sales', role: 'Business Development' }, { id: 19, name: 'Sam Young', email: 'sam@example.com', department: 'Support', role: 'Documentation Specialist' }, { id: 20, name: 'Tina Walker', email: 'tina@example.com', department: 'Marketing', role: 'Social Media Manager' }, ] ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { LoaderIcon } from 'lucide-solid' import { createSignal, For } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 5 interface User { id: number name: string email: string department: string role: string } export const Dependencies = () => { const [selectedDepartment, setSelectedDepartment] = createSignal('') const [selectedRole, setSelectedRole] = createSignal('') const list = useAsyncList({ initialItems: mockUsers.slice(0, LIMIT), get dependencies() { return [selectedDepartment(), selectedRole()] }, async load({ filterText }: { filterText?: string }) { await delay(400) let items = mockUsers if (selectedDepartment()) { items = items.filter((user) => user.department === selectedDepartment()) } if (selectedRole()) { items = items.filter((user) => user.role === selectedRole()) } if (filterText) { items = items.filter( (user) => user.name.toLowerCase().includes(filterText.toLowerCase()) || user.email.toLowerCase().includes(filterText.toLowerCase()), ) } return { items: items.slice(0, LIMIT) } }, }) return (
                    list().setFilterText(e.target.value)} /> {list().loading && ( Loading )}
                    {list().error &&
                    Error: {list().error.message}
                    }
                    Found {list().items.length} users
                    {(user) => (
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    )}
                    {list().items.length === 0 && !list().loading && (
                    No users found with current filters
                    )}
                    ) } const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) const departments = ['Engineering', 'Marketing', 'Sales', 'Support'] const roles = [ 'Senior Developer', 'Marketing Manager', 'Frontend Developer', 'Sales Representative', 'DevOps Engineer', 'Customer Success', 'Content Creator', 'Backend Developer', 'Account Manager', 'Technical Support', 'Brand Manager', 'Full Stack Developer', 'Sales Director', 'Support Manager', 'UI Designer', 'Digital Marketer', 'Mobile Developer', 'Business Development', 'Documentation Specialist', 'Social Media Manager', ] const mockUsers: User[] = [ { id: 1, name: 'Alice Johnson', email: 'alice@example.com', department: 'Engineering', role: 'Senior Developer' }, { id: 2, name: 'Bob Smith', email: 'bob@example.com', department: 'Marketing', role: 'Marketing Manager' }, { id: 3, name: 'Carol Davis', email: 'carol@example.com', department: 'Engineering', role: 'Frontend Developer' }, { id: 4, name: 'David Wilson', email: 'david@example.com', department: 'Sales', role: 'Sales Representative' }, { id: 5, name: 'Eva Brown', email: 'eva@example.com', department: 'Engineering', role: 'DevOps Engineer' }, { id: 6, name: 'Frank Miller', email: 'frank@example.com', department: 'Support', role: 'Customer Success' }, { id: 7, name: 'Grace Lee', email: 'grace@example.com', department: 'Marketing', role: 'Content Creator' }, { id: 8, name: 'Henry Taylor', email: 'henry@example.com', department: 'Engineering', role: 'Backend Developer' }, { id: 9, name: 'Ivy Anderson', email: 'ivy@example.com', department: 'Sales', role: 'Account Manager' }, { id: 10, name: 'Jack Thompson', email: 'jack@example.com', department: 'Support', role: 'Technical Support' }, { id: 11, name: 'Kate Martinez', email: 'kate@example.com', department: 'Marketing', role: 'Brand Manager' }, { id: 12, name: 'Liam Garcia', email: 'liam@example.com', department: 'Engineering', role: 'Full Stack Developer' }, { id: 13, name: 'Mia Rodriguez', email: 'mia@example.com', department: 'Sales', role: 'Sales Director' }, { id: 14, name: 'Noah Lopez', email: 'noah@example.com', department: 'Support', role: 'Support Manager' }, { id: 15, name: 'Olivia White', email: 'olivia@example.com', department: 'Engineering', role: 'UI Designer' }, { id: 16, name: 'Paul Harris', email: 'paul@example.com', department: 'Marketing', role: 'Digital Marketer' }, { id: 17, name: 'Quinn Clark', email: 'quinn@example.com', department: 'Engineering', role: 'Mobile Developer' }, { id: 18, name: 'Ruby Lewis', email: 'ruby@example.com', department: 'Sales', role: 'Business Development' }, { id: 19, name: 'Sam Young', email: 'sam@example.com', department: 'Support', role: 'Documentation Specialist' }, { id: 20, name: 'Tina Walker', email: 'tina@example.com', department: 'Marketing', role: 'Social Media Manager' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    list().setFilterText(e.currentTarget.value)} /> {#if list().loading} Loading {/if}
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    Found {list().items.length} users
                    {#each list().items as user}
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    {/each}
                    {#if list().items.length === 0 && !list().loading}
                    No users found with current filters
                    {/if}
                    ``` ## API Reference ### Props - **load** (`(params: LoadParams) => Promise>`) - Function to load data asynchronously - **sort** (`(params: SortParams) => Promise> | SortResult`) - Optional function for client-side sorting - **autoReload** (`boolean`, default: `false`) - Whether to automatically reload data on mount - **initialItems** (`T[]`, default: `[]`) - Initial items to display before first load - **dependencies** (`any[]`, default: `[]`) - Values that trigger a reload when changed - **initialFilterText** (`string`, default: `''`) - Initial filter text value - **initialSortDescriptor** (`SortDescriptor | null`) - Initial sort configuration ### Load Parameters The `load` function receives an object with the following properties: - **cursor** (`C | undefined`) - Current cursor for pagination - **filterText** (`string`) - Current filter text - **sortDescriptor** (`SortDescriptor | null`) - Current sort configuration - **signal** (`AbortSignal`) - AbortController signal for request cancellation ### Load Result The `load` function should return an object with: - **items** (`T[]`) - The loaded items - **cursor** (`C | undefined`) - Optional cursor for next page ### Sort Parameters The `sort` function receives an object with: - **items** (`T[]`) - Current items to sort - **descriptor** (`SortDescriptor`) - Sort configuration with `column` and `direction` ### Return Value The hook returns an object with the following properties and methods: #### State Properties - **items** (`T[]`) - Current list of items - **loading** (`boolean`) - Whether a load operation is in progress - **error** (`Error | null`) - Any error from the last operation - **cursor** (`C | undefined`) - Current cursor for pagination - **filterText** (`string`) - Current filter text - **sortDescriptor** (`SortDescriptor | null`) - Current sort configuration #### Methods - **reload** (`() => void`) - Reload data from the beginning - **loadMore** (`() => void`) - Load more items (when cursor is available) - **setFilterText** (`(text: string) => void`) - Set filter text and reload - **sort** (`(descriptor: SortDescriptor) => void`) - Apply sorting #### Types ```tsx interface SortDescriptor { column: string direction: 'ascending' | 'descending' } interface LoadParams { cursor?: C filterText: string sortDescriptor?: SortDescriptor | null signal: AbortSignal } interface LoadResult { items: T[] cursor?: C } ``` --- # Async List (VUE) The `useAsyncList` hook manages asynchronous data operations for list collections. It provides a comprehensive solution for loading, filtering, sorting, and paginating data with built-in loading states, error handling, and request cancellation. ```tsx import { useAsyncList } from '@ark-ui/react/collection' const list = useAsyncList({ async load({ signal }) { const response = await fetch('/api/users', { signal }) const users = await response.json() return { items: users } }, }) console.log(list.items) // User[] console.log(list.loading) // boolean console.log(list.error) // Error | null ``` ## Examples ### Loading Data Load data asynchronously from an API using the `load` function and update the list when the data is ready. **Example: async-list/reload** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { LoaderIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' interface Quote { id: number quote: string author: string } export const Reload = () => { const list = useAsyncList({ autoReload: true, async load() { const response = await fetch(`https://dummyjson.com/quotes?limit=4&skip=${Math.floor(Math.random() * 50)}`) if (!response.ok) { throw new Error('Failed to fetch quotes') } const data = await response.json() return { items: data.quotes } }, }) return (
                    {list.error &&
                    Error: {list.error.message}
                    }
                    {list.items.map((quote) => (
                    "{quote.quote}"
                    — {quote.author}
                    ))}
                    ) } ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' interface Quote { id: number quote: string author: string } export const Reload = () => { const list = useAsyncList({ autoReload: true, async load() { const response = await fetch(`https://dummyjson.com/quotes?limit=4&skip=${Math.floor(Math.random() * 50)}`) if (!response.ok) { throw new Error('Failed to fetch quotes') } const data = await response.json() return { items: data.quotes } }, }) return (
                    {list().error &&
                    Error: {list().error.message}
                    }
                    {(quote) => (
                    "{quote.quote}"
                    — {quote.author}
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    {#each list().items as quote}
                    "{quote.quote}"
                    — {quote.author}
                    {/each}
                    ``` ### Infinite Loading Implement pagination by returning a cursor that indicates more data is available. **Example: async-list/infinite-loading** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { LoaderIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 4 interface Post { userId: number id: number title: string body: string } export const InfiniteLoading = () => { const list = useAsyncList({ autoReload: true, async load({ cursor }) { const page = cursor || 1 const start = (page - 1) * LIMIT const response = await fetch(`https://jsonplaceholder.typicode.com/posts?_start=${start}&_limit=${LIMIT}`) if (!response.ok) { throw new Error('Failed to fetch posts') } const posts: Post[] = await response.json() const hasNextPage = posts.length === LIMIT return { items: posts, cursor: hasNextPage ? page + 1 : undefined, } }, }) return (
                    Loaded {list.items.length} posts {list.cursor && ` (more available)`} {list.cursor && ( )}
                    {list.error &&
                    Error: {list.error.message}
                    }
                    {list.items.map((post, index) => (
                    {index + 1}. {post.title}
                    {post.body}
                    ))}
                    ) } ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 4 interface Post { userId: number id: number title: string body: string } export const InfiniteLoading = () => { const list = useAsyncList({ autoReload: true, async load({ cursor }) { const page = cursor || 1 const start = (page - 1) * LIMIT const response = await fetch(`https://jsonplaceholder.typicode.com/posts?_start=${start}&_limit=${LIMIT}`) if (!response.ok) { throw new Error('Failed to fetch posts') } const posts: Post[] = await response.json() const hasNextPage = posts.length === LIMIT return { items: posts, cursor: hasNextPage ? page + 1 : undefined, } }, }) return (
                    Loaded {list().items.length} posts {list().cursor && ` (more available)`} {list().cursor && ( )}
                    {list().error &&
                    Error: {list().error.message}
                    }
                    {(post, index) => (
                    {index() + 1}. {post.title}
                    {post.body}
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Loaded {list().items.length} posts {#if list().cursor}(more available){/if} {#if list().cursor} {/if}
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    {#each list().items as post, index}
                    {index + 1}. {post.title}
                    {post.body}
                    {/each}
                    ``` ### Filtering Filter data based on user input with automatic debouncing and loading states. **Example: async-list/filter** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { LoaderIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 4 interface User { id: number name: string email: string department: string role: string } export const Filter = () => { const list = useAsyncList({ initialItems: mockUsers.slice(0, LIMIT), async load({ filterText }) { await delay(500) if (!filterText) { return { items: mockUsers.slice(0, LIMIT) } } const filtered = mockUsers.filter( (user) => user.name.toLowerCase().includes(filterText.toLowerCase()) || user.email.toLowerCase().includes(filterText.toLowerCase()), ) return { items: filtered.slice(0, LIMIT) } }, }) return (
                    list.setFilterText(e.target.value)} /> {list.loading && ( Searching )}
                    {list.error &&
                    Error: {list.error.message}
                    }
                    {list.items.map((user) => (
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    ))}
                    {list.items.length === 0 && !list.loading &&
                    No results found
                    }
                    ) } const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) const mockUsers: User[] = [ { id: 1, name: 'Alice Johnson', email: 'alice@example.com', department: 'Engineering', role: 'Senior Developer' }, { id: 2, name: 'Bob Smith', email: 'bob@example.com', department: 'Marketing', role: 'Marketing Manager' }, { id: 3, name: 'Carol Davis', email: 'carol@example.com', department: 'Engineering', role: 'Frontend Developer' }, { id: 4, name: 'David Wilson', email: 'david@example.com', department: 'Sales', role: 'Sales Representative' }, { id: 5, name: 'Eva Brown', email: 'eva@example.com', department: 'Engineering', role: 'DevOps Engineer' }, { id: 6, name: 'Frank Miller', email: 'frank@example.com', department: 'Support', role: 'Customer Success' }, { id: 7, name: 'Grace Lee', email: 'grace@example.com', department: 'Marketing', role: 'Content Creator' }, { id: 8, name: 'Henry Taylor', email: 'henry@example.com', department: 'Engineering', role: 'Backend Developer' }, { id: 9, name: 'Ivy Anderson', email: 'ivy@example.com', department: 'Sales', role: 'Account Manager' }, { id: 10, name: 'Jack Thompson', email: 'jack@example.com', department: 'Support', role: 'Technical Support' }, { id: 11, name: 'Kate Martinez', email: 'kate@example.com', department: 'Marketing', role: 'Brand Manager' }, { id: 12, name: 'Liam Garcia', email: 'liam@example.com', department: 'Engineering', role: 'Full Stack Developer' }, { id: 13, name: 'Mia Rodriguez', email: 'mia@example.com', department: 'Sales', role: 'Sales Director' }, { id: 14, name: 'Noah Lopez', email: 'noah@example.com', department: 'Support', role: 'Support Manager' }, { id: 15, name: 'Olivia White', email: 'olivia@example.com', department: 'Engineering', role: 'UI Designer' }, { id: 16, name: 'Paul Harris', email: 'paul@example.com', department: 'Marketing', role: 'Digital Marketer' }, { id: 17, name: 'Quinn Clark', email: 'quinn@example.com', department: 'Engineering', role: 'Mobile Developer' }, { id: 18, name: 'Ruby Lewis', email: 'ruby@example.com', department: 'Sales', role: 'Business Development' }, { id: 19, name: 'Sam Young', email: 'sam@example.com', department: 'Support', role: 'Documentation Specialist' }, { id: 20, name: 'Tina Walker', email: 'tina@example.com', department: 'Marketing', role: 'Social Media Manager' }, ] ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 4 interface User { id: number name: string email: string department: string role: string } export const Filter = () => { const list = useAsyncList({ initialItems: mockUsers.slice(0, LIMIT), async load({ filterText }: { filterText?: string }) { await delay(500) if (!filterText) { return { items: mockUsers.slice(0, LIMIT) } } const filtered = mockUsers.filter( (user) => user.name.toLowerCase().includes(filterText.toLowerCase()) || user.email.toLowerCase().includes(filterText.toLowerCase()), ) return { items: filtered.slice(0, LIMIT) } }, }) return (
                    list().setFilterText(e.target.value)} /> {list().loading && ( Searching )}
                    {list().error &&
                    Error: {list().error.message}
                    }
                    {(user) => (
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    )}
                    {list().items.length === 0 && !list().loading &&
                    No results found
                    }
                    ) } const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) const mockUsers: User[] = [ { id: 1, name: 'Alice Johnson', email: 'alice@example.com', department: 'Engineering', role: 'Senior Developer' }, { id: 2, name: 'Bob Smith', email: 'bob@example.com', department: 'Marketing', role: 'Marketing Manager' }, { id: 3, name: 'Carol Davis', email: 'carol@example.com', department: 'Engineering', role: 'Frontend Developer' }, { id: 4, name: 'David Wilson', email: 'david@example.com', department: 'Sales', role: 'Sales Representative' }, { id: 5, name: 'Eva Brown', email: 'eva@example.com', department: 'Engineering', role: 'DevOps Engineer' }, { id: 6, name: 'Frank Miller', email: 'frank@example.com', department: 'Support', role: 'Customer Success' }, { id: 7, name: 'Grace Lee', email: 'grace@example.com', department: 'Marketing', role: 'Content Creator' }, { id: 8, name: 'Henry Taylor', email: 'henry@example.com', department: 'Engineering', role: 'Backend Developer' }, { id: 9, name: 'Ivy Anderson', email: 'ivy@example.com', department: 'Sales', role: 'Account Manager' }, { id: 10, name: 'Jack Thompson', email: 'jack@example.com', department: 'Support', role: 'Technical Support' }, { id: 11, name: 'Kate Martinez', email: 'kate@example.com', department: 'Marketing', role: 'Brand Manager' }, { id: 12, name: 'Liam Garcia', email: 'liam@example.com', department: 'Engineering', role: 'Full Stack Developer' }, { id: 13, name: 'Mia Rodriguez', email: 'mia@example.com', department: 'Sales', role: 'Sales Director' }, { id: 14, name: 'Noah Lopez', email: 'noah@example.com', department: 'Support', role: 'Support Manager' }, { id: 15, name: 'Olivia White', email: 'olivia@example.com', department: 'Engineering', role: 'UI Designer' }, { id: 16, name: 'Paul Harris', email: 'paul@example.com', department: 'Marketing', role: 'Digital Marketer' }, { id: 17, name: 'Quinn Clark', email: 'quinn@example.com', department: 'Engineering', role: 'Mobile Developer' }, { id: 18, name: 'Ruby Lewis', email: 'ruby@example.com', department: 'Sales', role: 'Business Development' }, { id: 19, name: 'Sam Young', email: 'sam@example.com', department: 'Support', role: 'Documentation Specialist' }, { id: 20, name: 'Tina Walker', email: 'tina@example.com', department: 'Marketing', role: 'Social Media Manager' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    list().setFilterText(e.currentTarget.value)} /> {#if list().loading} Searching {/if}
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    {#each list().items as user}
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    {/each}
                    {#if list().items.length === 0 && !list().loading}
                    No results found
                    {/if}
                    ``` ### Sorting (Client-side) Sort data on the client side after loading from the server. **Example: async-list/sort-client-side** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { useCollator } from '@ark-ui/react/locale' import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon, LoaderIcon } from 'lucide-react' import styles from 'styles/async-list.module.css' interface User { id: number name: string username: string email: string phone: string website: string } export const SortClientSide = () => { const collator = useCollator() const list = useAsyncList({ autoReload: true, load: async () => { const response = await fetch('https://jsonplaceholder.typicode.com/users?_limit=5') const data = await response.json() return { items: data } }, sort({ items, descriptor }) { return { items: items.sort((a, b) => { const { column, direction } = descriptor let cmp = collator.compare(String(a[column]), String(b[column])) if (direction === 'descending') { cmp *= -1 } return cmp }), } }, }) const handleSort = (column: keyof User) => { const currentSort = list.sortDescriptor let direction: 'ascending' | 'descending' = 'ascending' if (currentSort?.column === column && currentSort.direction === 'ascending') { direction = 'descending' } list.sort({ column, direction }) } const getSortIcon = (column: keyof User) => { const current = list.sortDescriptor if (current?.column !== column) return return current.direction === 'ascending' ? : } const descriptor = list.sortDescriptor return (
                    {list.loading && (
                    Loading
                    )} {list.error &&
                    Error: {list.error.message}
                    }
                    Sorted by: {descriptor ? `${descriptor.column} (${descriptor.direction})` : 'none'}
                    {[ { key: 'name', label: 'Name' }, { key: 'username', label: 'Username' }, { key: 'email', label: 'Email' }, ].map(({ key, label }) => ( ))} {list.items.map((user) => ( ))}
                    handleSort(key as keyof User)}> {label} {getSortIcon(key as keyof User)}
                    {user.name} {user.username} {user.email}
                    ) } ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { useCollator } from '@ark-ui/solid/locale' import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon, LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/async-list.module.css' interface User { id: number name: string username: string email: string phone: string website: string } export const SortClientSide = () => { const collator = useCollator() const list = useAsyncList({ autoReload: true, load: async () => { const response = await fetch('https://jsonplaceholder.typicode.com/users?_limit=5') const data = await response.json() return { items: data } }, sort({ items, descriptor }) { return { items: items.sort((a, b) => { const { column, direction } = descriptor let cmp = collator().compare(String(a[column]), String(b[column])) if (direction === 'descending') { cmp *= -1 } return cmp }), } }, }) const handleSort = (column: keyof User) => { const currentSort = list().sortDescriptor let direction: 'ascending' | 'descending' = 'ascending' if (currentSort?.column === column && currentSort.direction === 'ascending') { direction = 'descending' } list().sort({ column, direction }) } const getSortIcon = (column: keyof User) => { const current = list().sortDescriptor if (current?.column !== column) return return current.direction === 'ascending' ? : } const descriptor = () => list().sortDescriptor return (
                    {list().loading && (
                    Loading
                    )} {list().error &&
                    Error: {list().error.message}
                    }
                    Sorted by: {descriptor() ? `${descriptor()?.column} (${descriptor()?.direction})` : 'none'}
                    {({ key, label }) => ( )} {(user) => ( )}
                    handleSort(key as keyof User)}> {label} {getSortIcon(key as keyof User)}
                    {user.name} {user.username} {user.email}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#if list().loading}
                    Loading
                    {/if} {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    Sorted by: {descriptor ? `${descriptor.column} (${descriptor.direction})` : 'none'}
                    {#each columns as { key, label }} {/each} {#each list().items as user} {/each}
                    handleSort(key as keyof User)}> {label} {#if list().sortDescriptor?.column === key} {#if list().sortDescriptor?.direction === 'ascending'} {:else} {/if} {:else} {/if}
                    {user.name} {user.username} {user.email}
                    ``` ### Sorting (Server-side) Send sort parameters to the server and reload data when sorting changes. **Example: async-list/sort-server-side** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon, LoaderIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' interface Product { id: number title: string price: number description: string category: string image: string rating: { rate: number count: number } } export const SortServerSide = () => { const list = useAsyncList({ autoReload: true, async load({ sortDescriptor }) { const url = new URL('https://fakestoreapi.com/products') url.searchParams.set('limit', '5') if (sortDescriptor) { const { direction } = sortDescriptor url.searchParams.set('sort', direction === 'ascending' ? 'asc' : 'desc') } const response = await fetch(url) const items = await response.json() return { items } }, }) const handleSort = (column: keyof Product) => { const currentSort = list.sortDescriptor let direction: 'ascending' | 'descending' = 'ascending' if (currentSort?.column === column && currentSort.direction === 'ascending') { direction = 'descending' } list.sort({ column, direction }) } const getSortIcon = (column: keyof Product) => { const desc = list.sortDescriptor if (desc?.column !== column) return return desc.direction === 'ascending' ? : } return (
                    {list.loading && ( Loading )}
                    {list.error &&
                    Error: {list.error.message}
                    }
                    {list.items.map((product) => (
                    {product.title}
                    {product.title}
                    ${product.price}
                    {product.category} • {product.rating.rate} ({product.rating.count} reviews)
                    ))}
                    ) } ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon, LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' interface Product { id: number title: string price: number description: string category: string image: string rating: { rate: number count: number } } export const SortServerSide = () => { const list = useAsyncList({ autoReload: true, async load({ sortDescriptor }) { const url = new URL('https://fakestoreapi.com/products') url.searchParams.set('limit', '5') if (sortDescriptor) { const { direction } = sortDescriptor url.searchParams.set('sort', direction === 'ascending' ? 'asc' : 'desc') } const response = await fetch(url) const items = await response.json() return { items } }, }) const handleSort = (column: keyof Product) => { const currentSort = list().sortDescriptor let direction: 'ascending' | 'descending' = 'ascending' if (currentSort?.column === column && currentSort.direction === 'ascending') { direction = 'descending' } list().sort({ column, direction }) } const getSortIcon = (column: keyof Product) => { const desc = list().sortDescriptor if (desc?.column !== column) return return desc.direction === 'ascending' ? : } return (
                    {list().loading && ( Loading )}
                    {list().error &&
                    Error: {list().error.message}
                    }
                    {(product) => (
                    {product.title}
                    {product.title}
                    ${product.price}
                    {product.category} • {product.rating.rate} ({product.rating.count} reviews)
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#if list().loading} Loading {/if}
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    {#each list().items as product}
                    {product.title}
                    {product.title}
                    ${product.price}
                    {product.category} • {product.rating.rate} ({product.rating.count} reviews)
                    {/each}
                    ``` ### Dependencies Automatically reload data when dependencies change, such as filter selections or external state. **Example: async-list/dependencies** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { LoaderIcon } from 'lucide-react' import { useState } from 'react' import field from 'styles/field.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 5 interface User { id: number name: string email: string department: string role: string } export const Dependencies = () => { const [selectedDepartment, setSelectedDepartment] = useState('') const [selectedRole, setSelectedRole] = useState('') const list = useAsyncList({ initialItems: mockUsers.slice(0, LIMIT), dependencies: [selectedDepartment, selectedRole], async load({ filterText }) { await delay(400) let items = mockUsers if (selectedDepartment) { items = items.filter((user) => user.department === selectedDepartment) } if (selectedRole) { items = items.filter((user) => user.role === selectedRole) } if (filterText) { items = items.filter( (user) => user.name.toLowerCase().includes(filterText.toLowerCase()) || user.email.toLowerCase().includes(filterText.toLowerCase()), ) } return { items: items.slice(0, LIMIT) } }, }) return (
                    list.setFilterText(e.target.value)} /> {list.loading && ( Loading )}
                    {list.error &&
                    Error: {list.error.message}
                    }
                    Found {list.items.length} users
                    {list.items.map((user) => (
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    ))}
                    {list.items.length === 0 && !list.loading && (
                    No users found with current filters
                    )}
                    ) } const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) const departments = ['Engineering', 'Marketing', 'Sales', 'Support'] const roles = [ 'Senior Developer', 'Marketing Manager', 'Frontend Developer', 'Sales Representative', 'DevOps Engineer', 'Customer Success', 'Content Creator', 'Backend Developer', 'Account Manager', 'Technical Support', 'Brand Manager', 'Full Stack Developer', 'Sales Director', 'Support Manager', 'UI Designer', 'Digital Marketer', 'Mobile Developer', 'Business Development', 'Documentation Specialist', 'Social Media Manager', ] const mockUsers: User[] = [ { id: 1, name: 'Alice Johnson', email: 'alice@example.com', department: 'Engineering', role: 'Senior Developer' }, { id: 2, name: 'Bob Smith', email: 'bob@example.com', department: 'Marketing', role: 'Marketing Manager' }, { id: 3, name: 'Carol Davis', email: 'carol@example.com', department: 'Engineering', role: 'Frontend Developer' }, { id: 4, name: 'David Wilson', email: 'david@example.com', department: 'Sales', role: 'Sales Representative' }, { id: 5, name: 'Eva Brown', email: 'eva@example.com', department: 'Engineering', role: 'DevOps Engineer' }, { id: 6, name: 'Frank Miller', email: 'frank@example.com', department: 'Support', role: 'Customer Success' }, { id: 7, name: 'Grace Lee', email: 'grace@example.com', department: 'Marketing', role: 'Content Creator' }, { id: 8, name: 'Henry Taylor', email: 'henry@example.com', department: 'Engineering', role: 'Backend Developer' }, { id: 9, name: 'Ivy Anderson', email: 'ivy@example.com', department: 'Sales', role: 'Account Manager' }, { id: 10, name: 'Jack Thompson', email: 'jack@example.com', department: 'Support', role: 'Technical Support' }, { id: 11, name: 'Kate Martinez', email: 'kate@example.com', department: 'Marketing', role: 'Brand Manager' }, { id: 12, name: 'Liam Garcia', email: 'liam@example.com', department: 'Engineering', role: 'Full Stack Developer' }, { id: 13, name: 'Mia Rodriguez', email: 'mia@example.com', department: 'Sales', role: 'Sales Director' }, { id: 14, name: 'Noah Lopez', email: 'noah@example.com', department: 'Support', role: 'Support Manager' }, { id: 15, name: 'Olivia White', email: 'olivia@example.com', department: 'Engineering', role: 'UI Designer' }, { id: 16, name: 'Paul Harris', email: 'paul@example.com', department: 'Marketing', role: 'Digital Marketer' }, { id: 17, name: 'Quinn Clark', email: 'quinn@example.com', department: 'Engineering', role: 'Mobile Developer' }, { id: 18, name: 'Ruby Lewis', email: 'ruby@example.com', department: 'Sales', role: 'Business Development' }, { id: 19, name: 'Sam Young', email: 'sam@example.com', department: 'Support', role: 'Documentation Specialist' }, { id: 20, name: 'Tina Walker', email: 'tina@example.com', department: 'Marketing', role: 'Social Media Manager' }, ] ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { LoaderIcon } from 'lucide-solid' import { createSignal, For } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 5 interface User { id: number name: string email: string department: string role: string } export const Dependencies = () => { const [selectedDepartment, setSelectedDepartment] = createSignal('') const [selectedRole, setSelectedRole] = createSignal('') const list = useAsyncList({ initialItems: mockUsers.slice(0, LIMIT), get dependencies() { return [selectedDepartment(), selectedRole()] }, async load({ filterText }: { filterText?: string }) { await delay(400) let items = mockUsers if (selectedDepartment()) { items = items.filter((user) => user.department === selectedDepartment()) } if (selectedRole()) { items = items.filter((user) => user.role === selectedRole()) } if (filterText) { items = items.filter( (user) => user.name.toLowerCase().includes(filterText.toLowerCase()) || user.email.toLowerCase().includes(filterText.toLowerCase()), ) } return { items: items.slice(0, LIMIT) } }, }) return (
                    list().setFilterText(e.target.value)} /> {list().loading && ( Loading )}
                    {list().error &&
                    Error: {list().error.message}
                    }
                    Found {list().items.length} users
                    {(user) => (
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    )}
                    {list().items.length === 0 && !list().loading && (
                    No users found with current filters
                    )}
                    ) } const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) const departments = ['Engineering', 'Marketing', 'Sales', 'Support'] const roles = [ 'Senior Developer', 'Marketing Manager', 'Frontend Developer', 'Sales Representative', 'DevOps Engineer', 'Customer Success', 'Content Creator', 'Backend Developer', 'Account Manager', 'Technical Support', 'Brand Manager', 'Full Stack Developer', 'Sales Director', 'Support Manager', 'UI Designer', 'Digital Marketer', 'Mobile Developer', 'Business Development', 'Documentation Specialist', 'Social Media Manager', ] const mockUsers: User[] = [ { id: 1, name: 'Alice Johnson', email: 'alice@example.com', department: 'Engineering', role: 'Senior Developer' }, { id: 2, name: 'Bob Smith', email: 'bob@example.com', department: 'Marketing', role: 'Marketing Manager' }, { id: 3, name: 'Carol Davis', email: 'carol@example.com', department: 'Engineering', role: 'Frontend Developer' }, { id: 4, name: 'David Wilson', email: 'david@example.com', department: 'Sales', role: 'Sales Representative' }, { id: 5, name: 'Eva Brown', email: 'eva@example.com', department: 'Engineering', role: 'DevOps Engineer' }, { id: 6, name: 'Frank Miller', email: 'frank@example.com', department: 'Support', role: 'Customer Success' }, { id: 7, name: 'Grace Lee', email: 'grace@example.com', department: 'Marketing', role: 'Content Creator' }, { id: 8, name: 'Henry Taylor', email: 'henry@example.com', department: 'Engineering', role: 'Backend Developer' }, { id: 9, name: 'Ivy Anderson', email: 'ivy@example.com', department: 'Sales', role: 'Account Manager' }, { id: 10, name: 'Jack Thompson', email: 'jack@example.com', department: 'Support', role: 'Technical Support' }, { id: 11, name: 'Kate Martinez', email: 'kate@example.com', department: 'Marketing', role: 'Brand Manager' }, { id: 12, name: 'Liam Garcia', email: 'liam@example.com', department: 'Engineering', role: 'Full Stack Developer' }, { id: 13, name: 'Mia Rodriguez', email: 'mia@example.com', department: 'Sales', role: 'Sales Director' }, { id: 14, name: 'Noah Lopez', email: 'noah@example.com', department: 'Support', role: 'Support Manager' }, { id: 15, name: 'Olivia White', email: 'olivia@example.com', department: 'Engineering', role: 'UI Designer' }, { id: 16, name: 'Paul Harris', email: 'paul@example.com', department: 'Marketing', role: 'Digital Marketer' }, { id: 17, name: 'Quinn Clark', email: 'quinn@example.com', department: 'Engineering', role: 'Mobile Developer' }, { id: 18, name: 'Ruby Lewis', email: 'ruby@example.com', department: 'Sales', role: 'Business Development' }, { id: 19, name: 'Sam Young', email: 'sam@example.com', department: 'Support', role: 'Documentation Specialist' }, { id: 20, name: 'Tina Walker', email: 'tina@example.com', department: 'Marketing', role: 'Social Media Manager' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    list().setFilterText(e.currentTarget.value)} /> {#if list().loading} Loading {/if}
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    Found {list().items.length} users
                    {#each list().items as user}
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    {/each}
                    {#if list().items.length === 0 && !list().loading}
                    No users found with current filters
                    {/if}
                    ``` ## API Reference ### Props - **load** (`(params: LoadParams) => Promise>`) - Function to load data asynchronously - **sort** (`(params: SortParams) => Promise> | SortResult`) - Optional function for client-side sorting - **autoReload** (`boolean`, default: `false`) - Whether to automatically reload data on mount - **initialItems** (`T[]`, default: `[]`) - Initial items to display before first load - **dependencies** (`any[]`, default: `[]`) - Values that trigger a reload when changed - **initialFilterText** (`string`, default: `''`) - Initial filter text value - **initialSortDescriptor** (`SortDescriptor | null`) - Initial sort configuration ### Load Parameters The `load` function receives an object with the following properties: - **cursor** (`C | undefined`) - Current cursor for pagination - **filterText** (`string`) - Current filter text - **sortDescriptor** (`SortDescriptor | null`) - Current sort configuration - **signal** (`AbortSignal`) - AbortController signal for request cancellation ### Load Result The `load` function should return an object with: - **items** (`T[]`) - The loaded items - **cursor** (`C | undefined`) - Optional cursor for next page ### Sort Parameters The `sort` function receives an object with: - **items** (`T[]`) - Current items to sort - **descriptor** (`SortDescriptor`) - Sort configuration with `column` and `direction` ### Return Value The hook returns an object with the following properties and methods: #### State Properties - **items** (`T[]`) - Current list of items - **loading** (`boolean`) - Whether a load operation is in progress - **error** (`Error | null`) - Any error from the last operation - **cursor** (`C | undefined`) - Current cursor for pagination - **filterText** (`string`) - Current filter text - **sortDescriptor** (`SortDescriptor | null`) - Current sort configuration #### Methods - **reload** (`() => void`) - Reload data from the beginning - **loadMore** (`() => void`) - Load more items (when cursor is available) - **setFilterText** (`(text: string) => void`) - Set filter text and reload - **sort** (`(descriptor: SortDescriptor) => void`) - Apply sorting #### Types ```tsx interface SortDescriptor { column: string direction: 'ascending' | 'descending' } interface LoadParams { cursor?: C filterText: string sortDescriptor?: SortDescriptor | null signal: AbortSignal } interface LoadResult { items: T[] cursor?: C } ``` --- # Async List (SVELTE) The `useAsyncList` hook manages asynchronous data operations for list collections. It provides a comprehensive solution for loading, filtering, sorting, and paginating data with built-in loading states, error handling, and request cancellation. ```tsx import { useAsyncList } from '@ark-ui/react/collection' const list = useAsyncList({ async load({ signal }) { const response = await fetch('/api/users', { signal }) const users = await response.json() return { items: users } }, }) console.log(list.items) // User[] console.log(list.loading) // boolean console.log(list.error) // Error | null ``` ## Examples ### Loading Data Load data asynchronously from an API using the `load` function and update the list when the data is ready. **Example: async-list/reload** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { LoaderIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' interface Quote { id: number quote: string author: string } export const Reload = () => { const list = useAsyncList({ autoReload: true, async load() { const response = await fetch(`https://dummyjson.com/quotes?limit=4&skip=${Math.floor(Math.random() * 50)}`) if (!response.ok) { throw new Error('Failed to fetch quotes') } const data = await response.json() return { items: data.quotes } }, }) return (
                    {list.error &&
                    Error: {list.error.message}
                    }
                    {list.items.map((quote) => (
                    "{quote.quote}"
                    — {quote.author}
                    ))}
                    ) } ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' interface Quote { id: number quote: string author: string } export const Reload = () => { const list = useAsyncList({ autoReload: true, async load() { const response = await fetch(`https://dummyjson.com/quotes?limit=4&skip=${Math.floor(Math.random() * 50)}`) if (!response.ok) { throw new Error('Failed to fetch quotes') } const data = await response.json() return { items: data.quotes } }, }) return (
                    {list().error &&
                    Error: {list().error.message}
                    }
                    {(quote) => (
                    "{quote.quote}"
                    — {quote.author}
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    {#each list().items as quote}
                    "{quote.quote}"
                    — {quote.author}
                    {/each}
                    ``` ### Infinite Loading Implement pagination by returning a cursor that indicates more data is available. **Example: async-list/infinite-loading** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { LoaderIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 4 interface Post { userId: number id: number title: string body: string } export const InfiniteLoading = () => { const list = useAsyncList({ autoReload: true, async load({ cursor }) { const page = cursor || 1 const start = (page - 1) * LIMIT const response = await fetch(`https://jsonplaceholder.typicode.com/posts?_start=${start}&_limit=${LIMIT}`) if (!response.ok) { throw new Error('Failed to fetch posts') } const posts: Post[] = await response.json() const hasNextPage = posts.length === LIMIT return { items: posts, cursor: hasNextPage ? page + 1 : undefined, } }, }) return (
                    Loaded {list.items.length} posts {list.cursor && ` (more available)`} {list.cursor && ( )}
                    {list.error &&
                    Error: {list.error.message}
                    }
                    {list.items.map((post, index) => (
                    {index + 1}. {post.title}
                    {post.body}
                    ))}
                    ) } ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 4 interface Post { userId: number id: number title: string body: string } export const InfiniteLoading = () => { const list = useAsyncList({ autoReload: true, async load({ cursor }) { const page = cursor || 1 const start = (page - 1) * LIMIT const response = await fetch(`https://jsonplaceholder.typicode.com/posts?_start=${start}&_limit=${LIMIT}`) if (!response.ok) { throw new Error('Failed to fetch posts') } const posts: Post[] = await response.json() const hasNextPage = posts.length === LIMIT return { items: posts, cursor: hasNextPage ? page + 1 : undefined, } }, }) return (
                    Loaded {list().items.length} posts {list().cursor && ` (more available)`} {list().cursor && ( )}
                    {list().error &&
                    Error: {list().error.message}
                    }
                    {(post, index) => (
                    {index() + 1}. {post.title}
                    {post.body}
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Loaded {list().items.length} posts {#if list().cursor}(more available){/if} {#if list().cursor} {/if}
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    {#each list().items as post, index}
                    {index + 1}. {post.title}
                    {post.body}
                    {/each}
                    ``` ### Filtering Filter data based on user input with automatic debouncing and loading states. **Example: async-list/filter** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { LoaderIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 4 interface User { id: number name: string email: string department: string role: string } export const Filter = () => { const list = useAsyncList({ initialItems: mockUsers.slice(0, LIMIT), async load({ filterText }) { await delay(500) if (!filterText) { return { items: mockUsers.slice(0, LIMIT) } } const filtered = mockUsers.filter( (user) => user.name.toLowerCase().includes(filterText.toLowerCase()) || user.email.toLowerCase().includes(filterText.toLowerCase()), ) return { items: filtered.slice(0, LIMIT) } }, }) return (
                    list.setFilterText(e.target.value)} /> {list.loading && ( Searching )}
                    {list.error &&
                    Error: {list.error.message}
                    }
                    {list.items.map((user) => (
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    ))}
                    {list.items.length === 0 && !list.loading &&
                    No results found
                    }
                    ) } const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) const mockUsers: User[] = [ { id: 1, name: 'Alice Johnson', email: 'alice@example.com', department: 'Engineering', role: 'Senior Developer' }, { id: 2, name: 'Bob Smith', email: 'bob@example.com', department: 'Marketing', role: 'Marketing Manager' }, { id: 3, name: 'Carol Davis', email: 'carol@example.com', department: 'Engineering', role: 'Frontend Developer' }, { id: 4, name: 'David Wilson', email: 'david@example.com', department: 'Sales', role: 'Sales Representative' }, { id: 5, name: 'Eva Brown', email: 'eva@example.com', department: 'Engineering', role: 'DevOps Engineer' }, { id: 6, name: 'Frank Miller', email: 'frank@example.com', department: 'Support', role: 'Customer Success' }, { id: 7, name: 'Grace Lee', email: 'grace@example.com', department: 'Marketing', role: 'Content Creator' }, { id: 8, name: 'Henry Taylor', email: 'henry@example.com', department: 'Engineering', role: 'Backend Developer' }, { id: 9, name: 'Ivy Anderson', email: 'ivy@example.com', department: 'Sales', role: 'Account Manager' }, { id: 10, name: 'Jack Thompson', email: 'jack@example.com', department: 'Support', role: 'Technical Support' }, { id: 11, name: 'Kate Martinez', email: 'kate@example.com', department: 'Marketing', role: 'Brand Manager' }, { id: 12, name: 'Liam Garcia', email: 'liam@example.com', department: 'Engineering', role: 'Full Stack Developer' }, { id: 13, name: 'Mia Rodriguez', email: 'mia@example.com', department: 'Sales', role: 'Sales Director' }, { id: 14, name: 'Noah Lopez', email: 'noah@example.com', department: 'Support', role: 'Support Manager' }, { id: 15, name: 'Olivia White', email: 'olivia@example.com', department: 'Engineering', role: 'UI Designer' }, { id: 16, name: 'Paul Harris', email: 'paul@example.com', department: 'Marketing', role: 'Digital Marketer' }, { id: 17, name: 'Quinn Clark', email: 'quinn@example.com', department: 'Engineering', role: 'Mobile Developer' }, { id: 18, name: 'Ruby Lewis', email: 'ruby@example.com', department: 'Sales', role: 'Business Development' }, { id: 19, name: 'Sam Young', email: 'sam@example.com', department: 'Support', role: 'Documentation Specialist' }, { id: 20, name: 'Tina Walker', email: 'tina@example.com', department: 'Marketing', role: 'Social Media Manager' }, ] ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 4 interface User { id: number name: string email: string department: string role: string } export const Filter = () => { const list = useAsyncList({ initialItems: mockUsers.slice(0, LIMIT), async load({ filterText }: { filterText?: string }) { await delay(500) if (!filterText) { return { items: mockUsers.slice(0, LIMIT) } } const filtered = mockUsers.filter( (user) => user.name.toLowerCase().includes(filterText.toLowerCase()) || user.email.toLowerCase().includes(filterText.toLowerCase()), ) return { items: filtered.slice(0, LIMIT) } }, }) return (
                    list().setFilterText(e.target.value)} /> {list().loading && ( Searching )}
                    {list().error &&
                    Error: {list().error.message}
                    }
                    {(user) => (
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    )}
                    {list().items.length === 0 && !list().loading &&
                    No results found
                    }
                    ) } const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) const mockUsers: User[] = [ { id: 1, name: 'Alice Johnson', email: 'alice@example.com', department: 'Engineering', role: 'Senior Developer' }, { id: 2, name: 'Bob Smith', email: 'bob@example.com', department: 'Marketing', role: 'Marketing Manager' }, { id: 3, name: 'Carol Davis', email: 'carol@example.com', department: 'Engineering', role: 'Frontend Developer' }, { id: 4, name: 'David Wilson', email: 'david@example.com', department: 'Sales', role: 'Sales Representative' }, { id: 5, name: 'Eva Brown', email: 'eva@example.com', department: 'Engineering', role: 'DevOps Engineer' }, { id: 6, name: 'Frank Miller', email: 'frank@example.com', department: 'Support', role: 'Customer Success' }, { id: 7, name: 'Grace Lee', email: 'grace@example.com', department: 'Marketing', role: 'Content Creator' }, { id: 8, name: 'Henry Taylor', email: 'henry@example.com', department: 'Engineering', role: 'Backend Developer' }, { id: 9, name: 'Ivy Anderson', email: 'ivy@example.com', department: 'Sales', role: 'Account Manager' }, { id: 10, name: 'Jack Thompson', email: 'jack@example.com', department: 'Support', role: 'Technical Support' }, { id: 11, name: 'Kate Martinez', email: 'kate@example.com', department: 'Marketing', role: 'Brand Manager' }, { id: 12, name: 'Liam Garcia', email: 'liam@example.com', department: 'Engineering', role: 'Full Stack Developer' }, { id: 13, name: 'Mia Rodriguez', email: 'mia@example.com', department: 'Sales', role: 'Sales Director' }, { id: 14, name: 'Noah Lopez', email: 'noah@example.com', department: 'Support', role: 'Support Manager' }, { id: 15, name: 'Olivia White', email: 'olivia@example.com', department: 'Engineering', role: 'UI Designer' }, { id: 16, name: 'Paul Harris', email: 'paul@example.com', department: 'Marketing', role: 'Digital Marketer' }, { id: 17, name: 'Quinn Clark', email: 'quinn@example.com', department: 'Engineering', role: 'Mobile Developer' }, { id: 18, name: 'Ruby Lewis', email: 'ruby@example.com', department: 'Sales', role: 'Business Development' }, { id: 19, name: 'Sam Young', email: 'sam@example.com', department: 'Support', role: 'Documentation Specialist' }, { id: 20, name: 'Tina Walker', email: 'tina@example.com', department: 'Marketing', role: 'Social Media Manager' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    list().setFilterText(e.currentTarget.value)} /> {#if list().loading} Searching {/if}
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    {#each list().items as user}
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    {/each}
                    {#if list().items.length === 0 && !list().loading}
                    No results found
                    {/if}
                    ``` ### Sorting (Client-side) Sort data on the client side after loading from the server. **Example: async-list/sort-client-side** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { useCollator } from '@ark-ui/react/locale' import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon, LoaderIcon } from 'lucide-react' import styles from 'styles/async-list.module.css' interface User { id: number name: string username: string email: string phone: string website: string } export const SortClientSide = () => { const collator = useCollator() const list = useAsyncList({ autoReload: true, load: async () => { const response = await fetch('https://jsonplaceholder.typicode.com/users?_limit=5') const data = await response.json() return { items: data } }, sort({ items, descriptor }) { return { items: items.sort((a, b) => { const { column, direction } = descriptor let cmp = collator.compare(String(a[column]), String(b[column])) if (direction === 'descending') { cmp *= -1 } return cmp }), } }, }) const handleSort = (column: keyof User) => { const currentSort = list.sortDescriptor let direction: 'ascending' | 'descending' = 'ascending' if (currentSort?.column === column && currentSort.direction === 'ascending') { direction = 'descending' } list.sort({ column, direction }) } const getSortIcon = (column: keyof User) => { const current = list.sortDescriptor if (current?.column !== column) return return current.direction === 'ascending' ? : } const descriptor = list.sortDescriptor return (
                    {list.loading && (
                    Loading
                    )} {list.error &&
                    Error: {list.error.message}
                    }
                    Sorted by: {descriptor ? `${descriptor.column} (${descriptor.direction})` : 'none'}
                    {[ { key: 'name', label: 'Name' }, { key: 'username', label: 'Username' }, { key: 'email', label: 'Email' }, ].map(({ key, label }) => ( ))} {list.items.map((user) => ( ))}
                    handleSort(key as keyof User)}> {label} {getSortIcon(key as keyof User)}
                    {user.name} {user.username} {user.email}
                    ) } ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { useCollator } from '@ark-ui/solid/locale' import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon, LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/async-list.module.css' interface User { id: number name: string username: string email: string phone: string website: string } export const SortClientSide = () => { const collator = useCollator() const list = useAsyncList({ autoReload: true, load: async () => { const response = await fetch('https://jsonplaceholder.typicode.com/users?_limit=5') const data = await response.json() return { items: data } }, sort({ items, descriptor }) { return { items: items.sort((a, b) => { const { column, direction } = descriptor let cmp = collator().compare(String(a[column]), String(b[column])) if (direction === 'descending') { cmp *= -1 } return cmp }), } }, }) const handleSort = (column: keyof User) => { const currentSort = list().sortDescriptor let direction: 'ascending' | 'descending' = 'ascending' if (currentSort?.column === column && currentSort.direction === 'ascending') { direction = 'descending' } list().sort({ column, direction }) } const getSortIcon = (column: keyof User) => { const current = list().sortDescriptor if (current?.column !== column) return return current.direction === 'ascending' ? : } const descriptor = () => list().sortDescriptor return (
                    {list().loading && (
                    Loading
                    )} {list().error &&
                    Error: {list().error.message}
                    }
                    Sorted by: {descriptor() ? `${descriptor()?.column} (${descriptor()?.direction})` : 'none'}
                    {({ key, label }) => ( )} {(user) => ( )}
                    handleSort(key as keyof User)}> {label} {getSortIcon(key as keyof User)}
                    {user.name} {user.username} {user.email}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#if list().loading}
                    Loading
                    {/if} {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    Sorted by: {descriptor ? `${descriptor.column} (${descriptor.direction})` : 'none'}
                    {#each columns as { key, label }} {/each} {#each list().items as user} {/each}
                    handleSort(key as keyof User)}> {label} {#if list().sortDescriptor?.column === key} {#if list().sortDescriptor?.direction === 'ascending'} {:else} {/if} {:else} {/if}
                    {user.name} {user.username} {user.email}
                    ``` ### Sorting (Server-side) Send sort parameters to the server and reload data when sorting changes. **Example: async-list/sort-server-side** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon, LoaderIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' interface Product { id: number title: string price: number description: string category: string image: string rating: { rate: number count: number } } export const SortServerSide = () => { const list = useAsyncList({ autoReload: true, async load({ sortDescriptor }) { const url = new URL('https://fakestoreapi.com/products') url.searchParams.set('limit', '5') if (sortDescriptor) { const { direction } = sortDescriptor url.searchParams.set('sort', direction === 'ascending' ? 'asc' : 'desc') } const response = await fetch(url) const items = await response.json() return { items } }, }) const handleSort = (column: keyof Product) => { const currentSort = list.sortDescriptor let direction: 'ascending' | 'descending' = 'ascending' if (currentSort?.column === column && currentSort.direction === 'ascending') { direction = 'descending' } list.sort({ column, direction }) } const getSortIcon = (column: keyof Product) => { const desc = list.sortDescriptor if (desc?.column !== column) return return desc.direction === 'ascending' ? : } return (
                    {list.loading && ( Loading )}
                    {list.error &&
                    Error: {list.error.message}
                    }
                    {list.items.map((product) => (
                    {product.title}
                    {product.title}
                    ${product.price}
                    {product.category} • {product.rating.rate} ({product.rating.count} reviews)
                    ))}
                    ) } ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon, LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' interface Product { id: number title: string price: number description: string category: string image: string rating: { rate: number count: number } } export const SortServerSide = () => { const list = useAsyncList({ autoReload: true, async load({ sortDescriptor }) { const url = new URL('https://fakestoreapi.com/products') url.searchParams.set('limit', '5') if (sortDescriptor) { const { direction } = sortDescriptor url.searchParams.set('sort', direction === 'ascending' ? 'asc' : 'desc') } const response = await fetch(url) const items = await response.json() return { items } }, }) const handleSort = (column: keyof Product) => { const currentSort = list().sortDescriptor let direction: 'ascending' | 'descending' = 'ascending' if (currentSort?.column === column && currentSort.direction === 'ascending') { direction = 'descending' } list().sort({ column, direction }) } const getSortIcon = (column: keyof Product) => { const desc = list().sortDescriptor if (desc?.column !== column) return return desc.direction === 'ascending' ? : } return (
                    {list().loading && ( Loading )}
                    {list().error &&
                    Error: {list().error.message}
                    }
                    {(product) => (
                    {product.title}
                    {product.title}
                    ${product.price}
                    {product.category} • {product.rating.rate} ({product.rating.count} reviews)
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#if list().loading} Loading {/if}
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    {#each list().items as product}
                    {product.title}
                    {product.title}
                    ${product.price}
                    {product.category} • {product.rating.rate} ({product.rating.count} reviews)
                    {/each}
                    ``` ### Dependencies Automatically reload data when dependencies change, such as filter selections or external state. **Example: async-list/dependencies** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { LoaderIcon } from 'lucide-react' import { useState } from 'react' import field from 'styles/field.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 5 interface User { id: number name: string email: string department: string role: string } export const Dependencies = () => { const [selectedDepartment, setSelectedDepartment] = useState('') const [selectedRole, setSelectedRole] = useState('') const list = useAsyncList({ initialItems: mockUsers.slice(0, LIMIT), dependencies: [selectedDepartment, selectedRole], async load({ filterText }) { await delay(400) let items = mockUsers if (selectedDepartment) { items = items.filter((user) => user.department === selectedDepartment) } if (selectedRole) { items = items.filter((user) => user.role === selectedRole) } if (filterText) { items = items.filter( (user) => user.name.toLowerCase().includes(filterText.toLowerCase()) || user.email.toLowerCase().includes(filterText.toLowerCase()), ) } return { items: items.slice(0, LIMIT) } }, }) return (
                    list.setFilterText(e.target.value)} /> {list.loading && ( Loading )}
                    {list.error &&
                    Error: {list.error.message}
                    }
                    Found {list.items.length} users
                    {list.items.map((user) => (
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    ))}
                    {list.items.length === 0 && !list.loading && (
                    No users found with current filters
                    )}
                    ) } const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) const departments = ['Engineering', 'Marketing', 'Sales', 'Support'] const roles = [ 'Senior Developer', 'Marketing Manager', 'Frontend Developer', 'Sales Representative', 'DevOps Engineer', 'Customer Success', 'Content Creator', 'Backend Developer', 'Account Manager', 'Technical Support', 'Brand Manager', 'Full Stack Developer', 'Sales Director', 'Support Manager', 'UI Designer', 'Digital Marketer', 'Mobile Developer', 'Business Development', 'Documentation Specialist', 'Social Media Manager', ] const mockUsers: User[] = [ { id: 1, name: 'Alice Johnson', email: 'alice@example.com', department: 'Engineering', role: 'Senior Developer' }, { id: 2, name: 'Bob Smith', email: 'bob@example.com', department: 'Marketing', role: 'Marketing Manager' }, { id: 3, name: 'Carol Davis', email: 'carol@example.com', department: 'Engineering', role: 'Frontend Developer' }, { id: 4, name: 'David Wilson', email: 'david@example.com', department: 'Sales', role: 'Sales Representative' }, { id: 5, name: 'Eva Brown', email: 'eva@example.com', department: 'Engineering', role: 'DevOps Engineer' }, { id: 6, name: 'Frank Miller', email: 'frank@example.com', department: 'Support', role: 'Customer Success' }, { id: 7, name: 'Grace Lee', email: 'grace@example.com', department: 'Marketing', role: 'Content Creator' }, { id: 8, name: 'Henry Taylor', email: 'henry@example.com', department: 'Engineering', role: 'Backend Developer' }, { id: 9, name: 'Ivy Anderson', email: 'ivy@example.com', department: 'Sales', role: 'Account Manager' }, { id: 10, name: 'Jack Thompson', email: 'jack@example.com', department: 'Support', role: 'Technical Support' }, { id: 11, name: 'Kate Martinez', email: 'kate@example.com', department: 'Marketing', role: 'Brand Manager' }, { id: 12, name: 'Liam Garcia', email: 'liam@example.com', department: 'Engineering', role: 'Full Stack Developer' }, { id: 13, name: 'Mia Rodriguez', email: 'mia@example.com', department: 'Sales', role: 'Sales Director' }, { id: 14, name: 'Noah Lopez', email: 'noah@example.com', department: 'Support', role: 'Support Manager' }, { id: 15, name: 'Olivia White', email: 'olivia@example.com', department: 'Engineering', role: 'UI Designer' }, { id: 16, name: 'Paul Harris', email: 'paul@example.com', department: 'Marketing', role: 'Digital Marketer' }, { id: 17, name: 'Quinn Clark', email: 'quinn@example.com', department: 'Engineering', role: 'Mobile Developer' }, { id: 18, name: 'Ruby Lewis', email: 'ruby@example.com', department: 'Sales', role: 'Business Development' }, { id: 19, name: 'Sam Young', email: 'sam@example.com', department: 'Support', role: 'Documentation Specialist' }, { id: 20, name: 'Tina Walker', email: 'tina@example.com', department: 'Marketing', role: 'Social Media Manager' }, ] ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { LoaderIcon } from 'lucide-solid' import { createSignal, For } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 5 interface User { id: number name: string email: string department: string role: string } export const Dependencies = () => { const [selectedDepartment, setSelectedDepartment] = createSignal('') const [selectedRole, setSelectedRole] = createSignal('') const list = useAsyncList({ initialItems: mockUsers.slice(0, LIMIT), get dependencies() { return [selectedDepartment(), selectedRole()] }, async load({ filterText }: { filterText?: string }) { await delay(400) let items = mockUsers if (selectedDepartment()) { items = items.filter((user) => user.department === selectedDepartment()) } if (selectedRole()) { items = items.filter((user) => user.role === selectedRole()) } if (filterText) { items = items.filter( (user) => user.name.toLowerCase().includes(filterText.toLowerCase()) || user.email.toLowerCase().includes(filterText.toLowerCase()), ) } return { items: items.slice(0, LIMIT) } }, }) return (
                    list().setFilterText(e.target.value)} /> {list().loading && ( Loading )}
                    {list().error &&
                    Error: {list().error.message}
                    }
                    Found {list().items.length} users
                    {(user) => (
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    )}
                    {list().items.length === 0 && !list().loading && (
                    No users found with current filters
                    )}
                    ) } const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) const departments = ['Engineering', 'Marketing', 'Sales', 'Support'] const roles = [ 'Senior Developer', 'Marketing Manager', 'Frontend Developer', 'Sales Representative', 'DevOps Engineer', 'Customer Success', 'Content Creator', 'Backend Developer', 'Account Manager', 'Technical Support', 'Brand Manager', 'Full Stack Developer', 'Sales Director', 'Support Manager', 'UI Designer', 'Digital Marketer', 'Mobile Developer', 'Business Development', 'Documentation Specialist', 'Social Media Manager', ] const mockUsers: User[] = [ { id: 1, name: 'Alice Johnson', email: 'alice@example.com', department: 'Engineering', role: 'Senior Developer' }, { id: 2, name: 'Bob Smith', email: 'bob@example.com', department: 'Marketing', role: 'Marketing Manager' }, { id: 3, name: 'Carol Davis', email: 'carol@example.com', department: 'Engineering', role: 'Frontend Developer' }, { id: 4, name: 'David Wilson', email: 'david@example.com', department: 'Sales', role: 'Sales Representative' }, { id: 5, name: 'Eva Brown', email: 'eva@example.com', department: 'Engineering', role: 'DevOps Engineer' }, { id: 6, name: 'Frank Miller', email: 'frank@example.com', department: 'Support', role: 'Customer Success' }, { id: 7, name: 'Grace Lee', email: 'grace@example.com', department: 'Marketing', role: 'Content Creator' }, { id: 8, name: 'Henry Taylor', email: 'henry@example.com', department: 'Engineering', role: 'Backend Developer' }, { id: 9, name: 'Ivy Anderson', email: 'ivy@example.com', department: 'Sales', role: 'Account Manager' }, { id: 10, name: 'Jack Thompson', email: 'jack@example.com', department: 'Support', role: 'Technical Support' }, { id: 11, name: 'Kate Martinez', email: 'kate@example.com', department: 'Marketing', role: 'Brand Manager' }, { id: 12, name: 'Liam Garcia', email: 'liam@example.com', department: 'Engineering', role: 'Full Stack Developer' }, { id: 13, name: 'Mia Rodriguez', email: 'mia@example.com', department: 'Sales', role: 'Sales Director' }, { id: 14, name: 'Noah Lopez', email: 'noah@example.com', department: 'Support', role: 'Support Manager' }, { id: 15, name: 'Olivia White', email: 'olivia@example.com', department: 'Engineering', role: 'UI Designer' }, { id: 16, name: 'Paul Harris', email: 'paul@example.com', department: 'Marketing', role: 'Digital Marketer' }, { id: 17, name: 'Quinn Clark', email: 'quinn@example.com', department: 'Engineering', role: 'Mobile Developer' }, { id: 18, name: 'Ruby Lewis', email: 'ruby@example.com', department: 'Sales', role: 'Business Development' }, { id: 19, name: 'Sam Young', email: 'sam@example.com', department: 'Support', role: 'Documentation Specialist' }, { id: 20, name: 'Tina Walker', email: 'tina@example.com', department: 'Marketing', role: 'Social Media Manager' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    list().setFilterText(e.currentTarget.value)} /> {#if list().loading} Loading {/if}
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    Found {list().items.length} users
                    {#each list().items as user}
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    {/each}
                    {#if list().items.length === 0 && !list().loading}
                    No users found with current filters
                    {/if}
                    ``` ## API Reference ### Props - **load** (`(params: LoadParams) => Promise>`) - Function to load data asynchronously - **sort** (`(params: SortParams) => Promise> | SortResult`) - Optional function for client-side sorting - **autoReload** (`boolean`, default: `false`) - Whether to automatically reload data on mount - **initialItems** (`T[]`, default: `[]`) - Initial items to display before first load - **dependencies** (`any[]`, default: `[]`) - Values that trigger a reload when changed - **initialFilterText** (`string`, default: `''`) - Initial filter text value - **initialSortDescriptor** (`SortDescriptor | null`) - Initial sort configuration ### Load Parameters The `load` function receives an object with the following properties: - **cursor** (`C | undefined`) - Current cursor for pagination - **filterText** (`string`) - Current filter text - **sortDescriptor** (`SortDescriptor | null`) - Current sort configuration - **signal** (`AbortSignal`) - AbortController signal for request cancellation ### Load Result The `load` function should return an object with: - **items** (`T[]`) - The loaded items - **cursor** (`C | undefined`) - Optional cursor for next page ### Sort Parameters The `sort` function receives an object with: - **items** (`T[]`) - Current items to sort - **descriptor** (`SortDescriptor`) - Sort configuration with `column` and `direction` ### Return Value The hook returns an object with the following properties and methods: #### State Properties - **items** (`T[]`) - Current list of items - **loading** (`boolean`) - Whether a load operation is in progress - **error** (`Error | null`) - Any error from the last operation - **cursor** (`C | undefined`) - Current cursor for pagination - **filterText** (`string`) - Current filter text - **sortDescriptor** (`SortDescriptor | null`) - Current sort configuration #### Methods - **reload** (`() => void`) - Reload data from the beginning - **loadMore** (`() => void`) - Load more items (when cursor is available) - **setFilterText** (`(text: string) => void`) - Set filter text and reload - **sort** (`(descriptor: SortDescriptor) => void`) - Apply sorting #### Types ```tsx interface SortDescriptor { column: string direction: 'ascending' | 'descending' } interface LoadParams { cursor?: C filterText: string sortDescriptor?: SortDescriptor | null signal: AbortSignal } interface LoadResult { items: T[] cursor?: C } ``` --- # Async List (SOLID) The `useAsyncList` hook manages asynchronous data operations for list collections. It provides a comprehensive solution for loading, filtering, sorting, and paginating data with built-in loading states, error handling, and request cancellation. ```tsx import { useAsyncList } from '@ark-ui/react/collection' const list = useAsyncList({ async load({ signal }) { const response = await fetch('/api/users', { signal }) const users = await response.json() return { items: users } }, }) console.log(list.items) // User[] console.log(list.loading) // boolean console.log(list.error) // Error | null ``` ## Examples ### Loading Data Load data asynchronously from an API using the `load` function and update the list when the data is ready. **Example: async-list/reload** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { LoaderIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' interface Quote { id: number quote: string author: string } export const Reload = () => { const list = useAsyncList({ autoReload: true, async load() { const response = await fetch(`https://dummyjson.com/quotes?limit=4&skip=${Math.floor(Math.random() * 50)}`) if (!response.ok) { throw new Error('Failed to fetch quotes') } const data = await response.json() return { items: data.quotes } }, }) return (
                    {list.error &&
                    Error: {list.error.message}
                    }
                    {list.items.map((quote) => (
                    "{quote.quote}"
                    — {quote.author}
                    ))}
                    ) } ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' interface Quote { id: number quote: string author: string } export const Reload = () => { const list = useAsyncList({ autoReload: true, async load() { const response = await fetch(`https://dummyjson.com/quotes?limit=4&skip=${Math.floor(Math.random() * 50)}`) if (!response.ok) { throw new Error('Failed to fetch quotes') } const data = await response.json() return { items: data.quotes } }, }) return (
                    {list().error &&
                    Error: {list().error.message}
                    }
                    {(quote) => (
                    "{quote.quote}"
                    — {quote.author}
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    {#each list().items as quote}
                    "{quote.quote}"
                    — {quote.author}
                    {/each}
                    ``` ### Infinite Loading Implement pagination by returning a cursor that indicates more data is available. **Example: async-list/infinite-loading** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { LoaderIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 4 interface Post { userId: number id: number title: string body: string } export const InfiniteLoading = () => { const list = useAsyncList({ autoReload: true, async load({ cursor }) { const page = cursor || 1 const start = (page - 1) * LIMIT const response = await fetch(`https://jsonplaceholder.typicode.com/posts?_start=${start}&_limit=${LIMIT}`) if (!response.ok) { throw new Error('Failed to fetch posts') } const posts: Post[] = await response.json() const hasNextPage = posts.length === LIMIT return { items: posts, cursor: hasNextPage ? page + 1 : undefined, } }, }) return (
                    Loaded {list.items.length} posts {list.cursor && ` (more available)`} {list.cursor && ( )}
                    {list.error &&
                    Error: {list.error.message}
                    }
                    {list.items.map((post, index) => (
                    {index + 1}. {post.title}
                    {post.body}
                    ))}
                    ) } ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 4 interface Post { userId: number id: number title: string body: string } export const InfiniteLoading = () => { const list = useAsyncList({ autoReload: true, async load({ cursor }) { const page = cursor || 1 const start = (page - 1) * LIMIT const response = await fetch(`https://jsonplaceholder.typicode.com/posts?_start=${start}&_limit=${LIMIT}`) if (!response.ok) { throw new Error('Failed to fetch posts') } const posts: Post[] = await response.json() const hasNextPage = posts.length === LIMIT return { items: posts, cursor: hasNextPage ? page + 1 : undefined, } }, }) return (
                    Loaded {list().items.length} posts {list().cursor && ` (more available)`} {list().cursor && ( )}
                    {list().error &&
                    Error: {list().error.message}
                    }
                    {(post, index) => (
                    {index() + 1}. {post.title}
                    {post.body}
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Loaded {list().items.length} posts {#if list().cursor}(more available){/if} {#if list().cursor} {/if}
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    {#each list().items as post, index}
                    {index + 1}. {post.title}
                    {post.body}
                    {/each}
                    ``` ### Filtering Filter data based on user input with automatic debouncing and loading states. **Example: async-list/filter** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { LoaderIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 4 interface User { id: number name: string email: string department: string role: string } export const Filter = () => { const list = useAsyncList({ initialItems: mockUsers.slice(0, LIMIT), async load({ filterText }) { await delay(500) if (!filterText) { return { items: mockUsers.slice(0, LIMIT) } } const filtered = mockUsers.filter( (user) => user.name.toLowerCase().includes(filterText.toLowerCase()) || user.email.toLowerCase().includes(filterText.toLowerCase()), ) return { items: filtered.slice(0, LIMIT) } }, }) return (
                    list.setFilterText(e.target.value)} /> {list.loading && ( Searching )}
                    {list.error &&
                    Error: {list.error.message}
                    }
                    {list.items.map((user) => (
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    ))}
                    {list.items.length === 0 && !list.loading &&
                    No results found
                    }
                    ) } const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) const mockUsers: User[] = [ { id: 1, name: 'Alice Johnson', email: 'alice@example.com', department: 'Engineering', role: 'Senior Developer' }, { id: 2, name: 'Bob Smith', email: 'bob@example.com', department: 'Marketing', role: 'Marketing Manager' }, { id: 3, name: 'Carol Davis', email: 'carol@example.com', department: 'Engineering', role: 'Frontend Developer' }, { id: 4, name: 'David Wilson', email: 'david@example.com', department: 'Sales', role: 'Sales Representative' }, { id: 5, name: 'Eva Brown', email: 'eva@example.com', department: 'Engineering', role: 'DevOps Engineer' }, { id: 6, name: 'Frank Miller', email: 'frank@example.com', department: 'Support', role: 'Customer Success' }, { id: 7, name: 'Grace Lee', email: 'grace@example.com', department: 'Marketing', role: 'Content Creator' }, { id: 8, name: 'Henry Taylor', email: 'henry@example.com', department: 'Engineering', role: 'Backend Developer' }, { id: 9, name: 'Ivy Anderson', email: 'ivy@example.com', department: 'Sales', role: 'Account Manager' }, { id: 10, name: 'Jack Thompson', email: 'jack@example.com', department: 'Support', role: 'Technical Support' }, { id: 11, name: 'Kate Martinez', email: 'kate@example.com', department: 'Marketing', role: 'Brand Manager' }, { id: 12, name: 'Liam Garcia', email: 'liam@example.com', department: 'Engineering', role: 'Full Stack Developer' }, { id: 13, name: 'Mia Rodriguez', email: 'mia@example.com', department: 'Sales', role: 'Sales Director' }, { id: 14, name: 'Noah Lopez', email: 'noah@example.com', department: 'Support', role: 'Support Manager' }, { id: 15, name: 'Olivia White', email: 'olivia@example.com', department: 'Engineering', role: 'UI Designer' }, { id: 16, name: 'Paul Harris', email: 'paul@example.com', department: 'Marketing', role: 'Digital Marketer' }, { id: 17, name: 'Quinn Clark', email: 'quinn@example.com', department: 'Engineering', role: 'Mobile Developer' }, { id: 18, name: 'Ruby Lewis', email: 'ruby@example.com', department: 'Sales', role: 'Business Development' }, { id: 19, name: 'Sam Young', email: 'sam@example.com', department: 'Support', role: 'Documentation Specialist' }, { id: 20, name: 'Tina Walker', email: 'tina@example.com', department: 'Marketing', role: 'Social Media Manager' }, ] ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 4 interface User { id: number name: string email: string department: string role: string } export const Filter = () => { const list = useAsyncList({ initialItems: mockUsers.slice(0, LIMIT), async load({ filterText }: { filterText?: string }) { await delay(500) if (!filterText) { return { items: mockUsers.slice(0, LIMIT) } } const filtered = mockUsers.filter( (user) => user.name.toLowerCase().includes(filterText.toLowerCase()) || user.email.toLowerCase().includes(filterText.toLowerCase()), ) return { items: filtered.slice(0, LIMIT) } }, }) return (
                    list().setFilterText(e.target.value)} /> {list().loading && ( Searching )}
                    {list().error &&
                    Error: {list().error.message}
                    }
                    {(user) => (
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    )}
                    {list().items.length === 0 && !list().loading &&
                    No results found
                    }
                    ) } const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) const mockUsers: User[] = [ { id: 1, name: 'Alice Johnson', email: 'alice@example.com', department: 'Engineering', role: 'Senior Developer' }, { id: 2, name: 'Bob Smith', email: 'bob@example.com', department: 'Marketing', role: 'Marketing Manager' }, { id: 3, name: 'Carol Davis', email: 'carol@example.com', department: 'Engineering', role: 'Frontend Developer' }, { id: 4, name: 'David Wilson', email: 'david@example.com', department: 'Sales', role: 'Sales Representative' }, { id: 5, name: 'Eva Brown', email: 'eva@example.com', department: 'Engineering', role: 'DevOps Engineer' }, { id: 6, name: 'Frank Miller', email: 'frank@example.com', department: 'Support', role: 'Customer Success' }, { id: 7, name: 'Grace Lee', email: 'grace@example.com', department: 'Marketing', role: 'Content Creator' }, { id: 8, name: 'Henry Taylor', email: 'henry@example.com', department: 'Engineering', role: 'Backend Developer' }, { id: 9, name: 'Ivy Anderson', email: 'ivy@example.com', department: 'Sales', role: 'Account Manager' }, { id: 10, name: 'Jack Thompson', email: 'jack@example.com', department: 'Support', role: 'Technical Support' }, { id: 11, name: 'Kate Martinez', email: 'kate@example.com', department: 'Marketing', role: 'Brand Manager' }, { id: 12, name: 'Liam Garcia', email: 'liam@example.com', department: 'Engineering', role: 'Full Stack Developer' }, { id: 13, name: 'Mia Rodriguez', email: 'mia@example.com', department: 'Sales', role: 'Sales Director' }, { id: 14, name: 'Noah Lopez', email: 'noah@example.com', department: 'Support', role: 'Support Manager' }, { id: 15, name: 'Olivia White', email: 'olivia@example.com', department: 'Engineering', role: 'UI Designer' }, { id: 16, name: 'Paul Harris', email: 'paul@example.com', department: 'Marketing', role: 'Digital Marketer' }, { id: 17, name: 'Quinn Clark', email: 'quinn@example.com', department: 'Engineering', role: 'Mobile Developer' }, { id: 18, name: 'Ruby Lewis', email: 'ruby@example.com', department: 'Sales', role: 'Business Development' }, { id: 19, name: 'Sam Young', email: 'sam@example.com', department: 'Support', role: 'Documentation Specialist' }, { id: 20, name: 'Tina Walker', email: 'tina@example.com', department: 'Marketing', role: 'Social Media Manager' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    list().setFilterText(e.currentTarget.value)} /> {#if list().loading} Searching {/if}
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    {#each list().items as user}
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    {/each}
                    {#if list().items.length === 0 && !list().loading}
                    No results found
                    {/if}
                    ``` ### Sorting (Client-side) Sort data on the client side after loading from the server. **Example: async-list/sort-client-side** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { useCollator } from '@ark-ui/react/locale' import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon, LoaderIcon } from 'lucide-react' import styles from 'styles/async-list.module.css' interface User { id: number name: string username: string email: string phone: string website: string } export const SortClientSide = () => { const collator = useCollator() const list = useAsyncList({ autoReload: true, load: async () => { const response = await fetch('https://jsonplaceholder.typicode.com/users?_limit=5') const data = await response.json() return { items: data } }, sort({ items, descriptor }) { return { items: items.sort((a, b) => { const { column, direction } = descriptor let cmp = collator.compare(String(a[column]), String(b[column])) if (direction === 'descending') { cmp *= -1 } return cmp }), } }, }) const handleSort = (column: keyof User) => { const currentSort = list.sortDescriptor let direction: 'ascending' | 'descending' = 'ascending' if (currentSort?.column === column && currentSort.direction === 'ascending') { direction = 'descending' } list.sort({ column, direction }) } const getSortIcon = (column: keyof User) => { const current = list.sortDescriptor if (current?.column !== column) return return current.direction === 'ascending' ? : } const descriptor = list.sortDescriptor return (
                    {list.loading && (
                    Loading
                    )} {list.error &&
                    Error: {list.error.message}
                    }
                    Sorted by: {descriptor ? `${descriptor.column} (${descriptor.direction})` : 'none'}
                    {[ { key: 'name', label: 'Name' }, { key: 'username', label: 'Username' }, { key: 'email', label: 'Email' }, ].map(({ key, label }) => ( ))} {list.items.map((user) => ( ))}
                    handleSort(key as keyof User)}> {label} {getSortIcon(key as keyof User)}
                    {user.name} {user.username} {user.email}
                    ) } ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { useCollator } from '@ark-ui/solid/locale' import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon, LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/async-list.module.css' interface User { id: number name: string username: string email: string phone: string website: string } export const SortClientSide = () => { const collator = useCollator() const list = useAsyncList({ autoReload: true, load: async () => { const response = await fetch('https://jsonplaceholder.typicode.com/users?_limit=5') const data = await response.json() return { items: data } }, sort({ items, descriptor }) { return { items: items.sort((a, b) => { const { column, direction } = descriptor let cmp = collator().compare(String(a[column]), String(b[column])) if (direction === 'descending') { cmp *= -1 } return cmp }), } }, }) const handleSort = (column: keyof User) => { const currentSort = list().sortDescriptor let direction: 'ascending' | 'descending' = 'ascending' if (currentSort?.column === column && currentSort.direction === 'ascending') { direction = 'descending' } list().sort({ column, direction }) } const getSortIcon = (column: keyof User) => { const current = list().sortDescriptor if (current?.column !== column) return return current.direction === 'ascending' ? : } const descriptor = () => list().sortDescriptor return (
                    {list().loading && (
                    Loading
                    )} {list().error &&
                    Error: {list().error.message}
                    }
                    Sorted by: {descriptor() ? `${descriptor()?.column} (${descriptor()?.direction})` : 'none'}
                    {({ key, label }) => ( )} {(user) => ( )}
                    handleSort(key as keyof User)}> {label} {getSortIcon(key as keyof User)}
                    {user.name} {user.username} {user.email}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#if list().loading}
                    Loading
                    {/if} {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    Sorted by: {descriptor ? `${descriptor.column} (${descriptor.direction})` : 'none'}
                    {#each columns as { key, label }} {/each} {#each list().items as user} {/each}
                    handleSort(key as keyof User)}> {label} {#if list().sortDescriptor?.column === key} {#if list().sortDescriptor?.direction === 'ascending'} {:else} {/if} {:else} {/if}
                    {user.name} {user.username} {user.email}
                    ``` ### Sorting (Server-side) Send sort parameters to the server and reload data when sorting changes. **Example: async-list/sort-server-side** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon, LoaderIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' interface Product { id: number title: string price: number description: string category: string image: string rating: { rate: number count: number } } export const SortServerSide = () => { const list = useAsyncList({ autoReload: true, async load({ sortDescriptor }) { const url = new URL('https://fakestoreapi.com/products') url.searchParams.set('limit', '5') if (sortDescriptor) { const { direction } = sortDescriptor url.searchParams.set('sort', direction === 'ascending' ? 'asc' : 'desc') } const response = await fetch(url) const items = await response.json() return { items } }, }) const handleSort = (column: keyof Product) => { const currentSort = list.sortDescriptor let direction: 'ascending' | 'descending' = 'ascending' if (currentSort?.column === column && currentSort.direction === 'ascending') { direction = 'descending' } list.sort({ column, direction }) } const getSortIcon = (column: keyof Product) => { const desc = list.sortDescriptor if (desc?.column !== column) return return desc.direction === 'ascending' ? : } return (
                    {list.loading && ( Loading )}
                    {list.error &&
                    Error: {list.error.message}
                    }
                    {list.items.map((product) => (
                    {product.title}
                    {product.title}
                    ${product.price}
                    {product.category} • {product.rating.rate} ({product.rating.count} reviews)
                    ))}
                    ) } ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon, LoaderIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/async-list.module.css' interface Product { id: number title: string price: number description: string category: string image: string rating: { rate: number count: number } } export const SortServerSide = () => { const list = useAsyncList({ autoReload: true, async load({ sortDescriptor }) { const url = new URL('https://fakestoreapi.com/products') url.searchParams.set('limit', '5') if (sortDescriptor) { const { direction } = sortDescriptor url.searchParams.set('sort', direction === 'ascending' ? 'asc' : 'desc') } const response = await fetch(url) const items = await response.json() return { items } }, }) const handleSort = (column: keyof Product) => { const currentSort = list().sortDescriptor let direction: 'ascending' | 'descending' = 'ascending' if (currentSort?.column === column && currentSort.direction === 'ascending') { direction = 'descending' } list().sort({ column, direction }) } const getSortIcon = (column: keyof Product) => { const desc = list().sortDescriptor if (desc?.column !== column) return return desc.direction === 'ascending' ? : } return (
                    {list().loading && ( Loading )}
                    {list().error &&
                    Error: {list().error.message}
                    }
                    {(product) => (
                    {product.title}
                    {product.title}
                    ${product.price}
                    {product.category} • {product.rating.rate} ({product.rating.count} reviews)
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#if list().loading} Loading {/if}
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    {#each list().items as product}
                    {product.title}
                    {product.title}
                    ${product.price}
                    {product.category} • {product.rating.rate} ({product.rating.count} reviews)
                    {/each}
                    ``` ### Dependencies Automatically reload data when dependencies change, such as filter selections or external state. **Example: async-list/dependencies** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { LoaderIcon } from 'lucide-react' import { useState } from 'react' import field from 'styles/field.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 5 interface User { id: number name: string email: string department: string role: string } export const Dependencies = () => { const [selectedDepartment, setSelectedDepartment] = useState('') const [selectedRole, setSelectedRole] = useState('') const list = useAsyncList({ initialItems: mockUsers.slice(0, LIMIT), dependencies: [selectedDepartment, selectedRole], async load({ filterText }) { await delay(400) let items = mockUsers if (selectedDepartment) { items = items.filter((user) => user.department === selectedDepartment) } if (selectedRole) { items = items.filter((user) => user.role === selectedRole) } if (filterText) { items = items.filter( (user) => user.name.toLowerCase().includes(filterText.toLowerCase()) || user.email.toLowerCase().includes(filterText.toLowerCase()), ) } return { items: items.slice(0, LIMIT) } }, }) return (
                    list.setFilterText(e.target.value)} /> {list.loading && ( Loading )}
                    {list.error &&
                    Error: {list.error.message}
                    }
                    Found {list.items.length} users
                    {list.items.map((user) => (
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    ))}
                    {list.items.length === 0 && !list.loading && (
                    No users found with current filters
                    )}
                    ) } const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) const departments = ['Engineering', 'Marketing', 'Sales', 'Support'] const roles = [ 'Senior Developer', 'Marketing Manager', 'Frontend Developer', 'Sales Representative', 'DevOps Engineer', 'Customer Success', 'Content Creator', 'Backend Developer', 'Account Manager', 'Technical Support', 'Brand Manager', 'Full Stack Developer', 'Sales Director', 'Support Manager', 'UI Designer', 'Digital Marketer', 'Mobile Developer', 'Business Development', 'Documentation Specialist', 'Social Media Manager', ] const mockUsers: User[] = [ { id: 1, name: 'Alice Johnson', email: 'alice@example.com', department: 'Engineering', role: 'Senior Developer' }, { id: 2, name: 'Bob Smith', email: 'bob@example.com', department: 'Marketing', role: 'Marketing Manager' }, { id: 3, name: 'Carol Davis', email: 'carol@example.com', department: 'Engineering', role: 'Frontend Developer' }, { id: 4, name: 'David Wilson', email: 'david@example.com', department: 'Sales', role: 'Sales Representative' }, { id: 5, name: 'Eva Brown', email: 'eva@example.com', department: 'Engineering', role: 'DevOps Engineer' }, { id: 6, name: 'Frank Miller', email: 'frank@example.com', department: 'Support', role: 'Customer Success' }, { id: 7, name: 'Grace Lee', email: 'grace@example.com', department: 'Marketing', role: 'Content Creator' }, { id: 8, name: 'Henry Taylor', email: 'henry@example.com', department: 'Engineering', role: 'Backend Developer' }, { id: 9, name: 'Ivy Anderson', email: 'ivy@example.com', department: 'Sales', role: 'Account Manager' }, { id: 10, name: 'Jack Thompson', email: 'jack@example.com', department: 'Support', role: 'Technical Support' }, { id: 11, name: 'Kate Martinez', email: 'kate@example.com', department: 'Marketing', role: 'Brand Manager' }, { id: 12, name: 'Liam Garcia', email: 'liam@example.com', department: 'Engineering', role: 'Full Stack Developer' }, { id: 13, name: 'Mia Rodriguez', email: 'mia@example.com', department: 'Sales', role: 'Sales Director' }, { id: 14, name: 'Noah Lopez', email: 'noah@example.com', department: 'Support', role: 'Support Manager' }, { id: 15, name: 'Olivia White', email: 'olivia@example.com', department: 'Engineering', role: 'UI Designer' }, { id: 16, name: 'Paul Harris', email: 'paul@example.com', department: 'Marketing', role: 'Digital Marketer' }, { id: 17, name: 'Quinn Clark', email: 'quinn@example.com', department: 'Engineering', role: 'Mobile Developer' }, { id: 18, name: 'Ruby Lewis', email: 'ruby@example.com', department: 'Sales', role: 'Business Development' }, { id: 19, name: 'Sam Young', email: 'sam@example.com', department: 'Support', role: 'Documentation Specialist' }, { id: 20, name: 'Tina Walker', email: 'tina@example.com', department: 'Marketing', role: 'Social Media Manager' }, ] ``` #### Solid ```tsx import { useAsyncList } from '@ark-ui/solid/collection' import { LoaderIcon } from 'lucide-solid' import { createSignal, For } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/async-list.module.css' const LIMIT = 5 interface User { id: number name: string email: string department: string role: string } export const Dependencies = () => { const [selectedDepartment, setSelectedDepartment] = createSignal('') const [selectedRole, setSelectedRole] = createSignal('') const list = useAsyncList({ initialItems: mockUsers.slice(0, LIMIT), get dependencies() { return [selectedDepartment(), selectedRole()] }, async load({ filterText }: { filterText?: string }) { await delay(400) let items = mockUsers if (selectedDepartment()) { items = items.filter((user) => user.department === selectedDepartment()) } if (selectedRole()) { items = items.filter((user) => user.role === selectedRole()) } if (filterText) { items = items.filter( (user) => user.name.toLowerCase().includes(filterText.toLowerCase()) || user.email.toLowerCase().includes(filterText.toLowerCase()), ) } return { items: items.slice(0, LIMIT) } }, }) return (
                    list().setFilterText(e.target.value)} /> {list().loading && ( Loading )}
                    {list().error &&
                    Error: {list().error.message}
                    }
                    Found {list().items.length} users
                    {(user) => (
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    )}
                    {list().items.length === 0 && !list().loading && (
                    No users found with current filters
                    )}
                    ) } const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) const departments = ['Engineering', 'Marketing', 'Sales', 'Support'] const roles = [ 'Senior Developer', 'Marketing Manager', 'Frontend Developer', 'Sales Representative', 'DevOps Engineer', 'Customer Success', 'Content Creator', 'Backend Developer', 'Account Manager', 'Technical Support', 'Brand Manager', 'Full Stack Developer', 'Sales Director', 'Support Manager', 'UI Designer', 'Digital Marketer', 'Mobile Developer', 'Business Development', 'Documentation Specialist', 'Social Media Manager', ] const mockUsers: User[] = [ { id: 1, name: 'Alice Johnson', email: 'alice@example.com', department: 'Engineering', role: 'Senior Developer' }, { id: 2, name: 'Bob Smith', email: 'bob@example.com', department: 'Marketing', role: 'Marketing Manager' }, { id: 3, name: 'Carol Davis', email: 'carol@example.com', department: 'Engineering', role: 'Frontend Developer' }, { id: 4, name: 'David Wilson', email: 'david@example.com', department: 'Sales', role: 'Sales Representative' }, { id: 5, name: 'Eva Brown', email: 'eva@example.com', department: 'Engineering', role: 'DevOps Engineer' }, { id: 6, name: 'Frank Miller', email: 'frank@example.com', department: 'Support', role: 'Customer Success' }, { id: 7, name: 'Grace Lee', email: 'grace@example.com', department: 'Marketing', role: 'Content Creator' }, { id: 8, name: 'Henry Taylor', email: 'henry@example.com', department: 'Engineering', role: 'Backend Developer' }, { id: 9, name: 'Ivy Anderson', email: 'ivy@example.com', department: 'Sales', role: 'Account Manager' }, { id: 10, name: 'Jack Thompson', email: 'jack@example.com', department: 'Support', role: 'Technical Support' }, { id: 11, name: 'Kate Martinez', email: 'kate@example.com', department: 'Marketing', role: 'Brand Manager' }, { id: 12, name: 'Liam Garcia', email: 'liam@example.com', department: 'Engineering', role: 'Full Stack Developer' }, { id: 13, name: 'Mia Rodriguez', email: 'mia@example.com', department: 'Sales', role: 'Sales Director' }, { id: 14, name: 'Noah Lopez', email: 'noah@example.com', department: 'Support', role: 'Support Manager' }, { id: 15, name: 'Olivia White', email: 'olivia@example.com', department: 'Engineering', role: 'UI Designer' }, { id: 16, name: 'Paul Harris', email: 'paul@example.com', department: 'Marketing', role: 'Digital Marketer' }, { id: 17, name: 'Quinn Clark', email: 'quinn@example.com', department: 'Engineering', role: 'Mobile Developer' }, { id: 18, name: 'Ruby Lewis', email: 'ruby@example.com', department: 'Sales', role: 'Business Development' }, { id: 19, name: 'Sam Young', email: 'sam@example.com', department: 'Support', role: 'Documentation Specialist' }, { id: 20, name: 'Tina Walker', email: 'tina@example.com', department: 'Marketing', role: 'Social Media Manager' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    list().setFilterText(e.currentTarget.value)} /> {#if list().loading} Loading {/if}
                    {#if list().error}
                    Error: {list().error.message}
                    {/if}
                    Found {list().items.length} users
                    {#each list().items as user}
                    {user.name}
                    {user.email}
                    {user.department} • {user.role}
                    {/each}
                    {#if list().items.length === 0 && !list().loading}
                    No users found with current filters
                    {/if}
                    ``` ## API Reference ### Props - **load** (`(params: LoadParams) => Promise>`) - Function to load data asynchronously - **sort** (`(params: SortParams) => Promise> | SortResult`) - Optional function for client-side sorting - **autoReload** (`boolean`, default: `false`) - Whether to automatically reload data on mount - **initialItems** (`T[]`, default: `[]`) - Initial items to display before first load - **dependencies** (`any[]`, default: `[]`) - Values that trigger a reload when changed - **initialFilterText** (`string`, default: `''`) - Initial filter text value - **initialSortDescriptor** (`SortDescriptor | null`) - Initial sort configuration ### Load Parameters The `load` function receives an object with the following properties: - **cursor** (`C | undefined`) - Current cursor for pagination - **filterText** (`string`) - Current filter text - **sortDescriptor** (`SortDescriptor | null`) - Current sort configuration - **signal** (`AbortSignal`) - AbortController signal for request cancellation ### Load Result The `load` function should return an object with: - **items** (`T[]`) - The loaded items - **cursor** (`C | undefined`) - Optional cursor for next page ### Sort Parameters The `sort` function receives an object with: - **items** (`T[]`) - Current items to sort - **descriptor** (`SortDescriptor`) - Sort configuration with `column` and `direction` ### Return Value The hook returns an object with the following properties and methods: #### State Properties - **items** (`T[]`) - Current list of items - **loading** (`boolean`) - Whether a load operation is in progress - **error** (`Error | null`) - Any error from the last operation - **cursor** (`C | undefined`) - Current cursor for pagination - **filterText** (`string`) - Current filter text - **sortDescriptor** (`SortDescriptor | null`) - Current sort configuration #### Methods - **reload** (`() => void`) - Reload data from the beginning - **loadMore** (`() => void`) - Load more items (when cursor is available) - **setFilterText** (`(text: string) => void`) - Set filter text and reload - **sort** (`(descriptor: SortDescriptor) => void`) - Apply sorting #### Types ```tsx interface SortDescriptor { column: string direction: 'ascending' | 'descending' } interface LoadParams { cursor?: C filterText: string sortDescriptor?: SortDescriptor | null signal: AbortSignal } interface LoadResult { items: T[] cursor?: C } ``` --- # List Selection (REACT) The `useListSelection` hook manages selection state in lists and collections. It supports single and multiple selection modes with operations like select, deselect, toggle, and clear. ```tsx import { createListCollection, useListSelection } from '@ark-ui/react/collection' const collection = createListCollection({ items: [ { label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }, { label: 'Cherry', value: 'cherry' }, ], }) const selection = useListSelection({ collection, selectionMode: 'single', deselectable: true, }) console.log(selection.selectedValues) // ['apple', 'banana', 'cherry'] ``` ## Examples ### Basic By default, the hook supports single selection mode that can be deselected. > Set `deselectable` to `false` to prevent deselecting the current selection. **Example: list-selection/basic** #### React ```tsx import { createListCollection, useListSelection } from '@ark-ui/react/collection' import styles from 'styles/list-selection.module.css' export const Basic = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, ], }) const selection = useListSelection({ collection }) return (
                    Selected: {selection.selectedValues.join(', ') || 'None'} {collection.items.map((item) => ( ))}
                    ) } ``` #### Solid ```tsx import { createListCollection, useListSelection } from '@ark-ui/solid/collection' import { For } from 'solid-js' import styles from 'styles/list-selection.module.css' export const Basic = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, ], }) const selection = useListSelection({ collection }) return (
                    Selected: {selection.selectedValues().join(', ') || 'None'} {(item) => ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Selected: {selection.selectedValues().join(', ') || 'None'} {#each collection.items as item (item.value)} {/each}
                    ``` ### Multiple Selection Set `selectionMode` to `multiple` to allow multiple items to be selected. **Example: list-selection/multiple** #### React ```tsx import { createListCollection, useListSelection } from '@ark-ui/react/collection' import styles from 'styles/list-selection.module.css' export const Multiple = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, ], }) const selection = useListSelection({ collection, selectionMode: 'multiple', }) const handleSelectAll = () => { if (selection.isAllSelected()) { selection.clear() } else { selection.setSelectedValues(collection.getValues()) } } return (
                    {selection.selectedValues.length} of {collection.items.length} selected
                    {collection.items.map((item) => ( ))}
                    ) } ``` #### Solid ```tsx import { createListCollection, useListSelection } from '@ark-ui/solid/collection' import { For } from 'solid-js' import styles from 'styles/list-selection.module.css' export const Multiple = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, ], }) const selection = useListSelection({ collection, selectionMode: 'multiple', }) const handleSelectAll = () => { if (selection.isAllSelected()) { selection.clear() } else { selection.setSelectedValues(collection.getValues()) } } return (
                    {selection.selectedValues().length} of {collection.items.length} selected
                    {(item) => ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {selection.selectedValues().length} of {collection.items.length} selected
                    {#each collection.items as item (item.value)} {/each}
                    ``` ### Range Selection Here's an example of how to implement range selection that extends the selection from the first selected item to the clicked item. **Example: list-selection/range** #### React ```tsx import { createListCollection, useListSelection } from '@ark-ui/react/collection' import styles from 'styles/list-selection.module.css' export const Range = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, ], }) const selection = useListSelection({ collection, selectionMode: 'multiple', }) const handleItemClick = (value: string, event: React.MouseEvent) => { if (event.shiftKey && selection.firstSelectedValue) { selection.extend(selection.firstSelectedValue, value) } else if (event.ctrlKey || event.metaKey) { selection.toggle(value) } else { selection.replace(value) } } return (
                    Selected: {selection.selectedValues.join(', ') || 'None'} {collection.items.map((item) => ( ))}

                    Click to select • Shift+Click for range • Cmd/Ctrl+Click to toggle

                    ) } ``` #### Solid ```tsx import { createListCollection, useListSelection } from '@ark-ui/solid/collection' import { For } from 'solid-js' import styles from 'styles/list-selection.module.css' export const Range = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, ], }) const selection = useListSelection({ collection, selectionMode: 'multiple', }) const handleItemClick = (value: string, event: MouseEvent) => { const firstSelectedValue = selection.firstSelectedValue() if (event.shiftKey && firstSelectedValue) { selection.extend(firstSelectedValue, value) } else if (event.ctrlKey || event.metaKey) { selection.toggle(value) } else { selection.replace(value) } } return (
                    Selected: {selection.selectedValues().join(', ') || 'None'} {(item) => ( )}

                    Click to select • Shift+Click for range • Cmd/Ctrl+Click to toggle

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Selected: {selection.selectedValues().join(', ') || 'None'} {#each collection.items as item (item.value)} {/each}

                    Click to select • Shift+Click for range • Cmd/Ctrl+Click to toggle

                    ``` ## API Reference ### Props - **collection** (`ListCollection`) - The collection to manage selection for - **selectionMode** (`'single' | 'multiple' | 'none'`, default: `'single'`) - The selection mode - **deselectable** (`boolean`, default: `true`) - Whether selected items can be deselected - **initialSelectedValues** (`string[]`, default: `[]`) - Initial selected values - **resetOnCollectionChange** (`boolean`, default: `false`) - Whether to reset selection when collection changes ### Return Value The hook returns an object with the following properties and methods: #### State Properties - **selectedValues** (`string[]`) - Array of currently selected values - **isEmpty** (`boolean`) - Whether no items are selected - **firstSelectedValue** (`string | null`) - The first selected value in collection order - **lastSelectedValue** (`string | null`) - The last selected value in collection order #### Query Methods - **isSelected** (`(value: string | null) => boolean`) - Check if a value is selected - **canSelect** (`(value: string) => boolean`) - Check if a value can be selected - **isAllSelected** (`() => boolean`) - Check if all items are selected - **isSomeSelected** (`() => boolean`) - Check if some items are selected #### Selection Methods - **select** (`(value: string, forceToggle?: boolean) => void`) - Select a value - **deselect** (`(value: string) => void`) - Deselect a value - **toggle** (`(value: string) => void`) - Toggle selection of a value - **replace** (`(value: string | null) => void`) - Replace selection with a single value - **extend** (`(anchorValue: string, targetValue: string) => void`) - Extend selection from anchor to target - **setSelectedValues** (`(values: string[]) => void`) - Set the selected values - **setSelection** (`(values: string[]) => void`) - Set the selection (alias for setSelectedValues) - **clear** (`() => void`) - Clear all selections - **resetSelection** (`() => void`) - Reset selection to initial state --- # List Selection (VUE) The `useListSelection` hook manages selection state in lists and collections. It supports single and multiple selection modes with operations like select, deselect, toggle, and clear. ```tsx import { createListCollection, useListSelection } from '@ark-ui/react/collection' const collection = createListCollection({ items: [ { label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }, { label: 'Cherry', value: 'cherry' }, ], }) const selection = useListSelection({ collection, selectionMode: 'single', deselectable: true, }) console.log(selection.selectedValues) // ['apple', 'banana', 'cherry'] ``` ## Examples ### Basic By default, the hook supports single selection mode that can be deselected. > Set `deselectable` to `false` to prevent deselecting the current selection. **Example: list-selection/basic** #### React ```tsx import { createListCollection, useListSelection } from '@ark-ui/react/collection' import styles from 'styles/list-selection.module.css' export const Basic = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, ], }) const selection = useListSelection({ collection }) return (
                    Selected: {selection.selectedValues.join(', ') || 'None'} {collection.items.map((item) => ( ))}
                    ) } ``` #### Solid ```tsx import { createListCollection, useListSelection } from '@ark-ui/solid/collection' import { For } from 'solid-js' import styles from 'styles/list-selection.module.css' export const Basic = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, ], }) const selection = useListSelection({ collection }) return (
                    Selected: {selection.selectedValues().join(', ') || 'None'} {(item) => ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Selected: {selection.selectedValues().join(', ') || 'None'} {#each collection.items as item (item.value)} {/each}
                    ``` ### Multiple Selection Set `selectionMode` to `multiple` to allow multiple items to be selected. **Example: list-selection/multiple** #### React ```tsx import { createListCollection, useListSelection } from '@ark-ui/react/collection' import styles from 'styles/list-selection.module.css' export const Multiple = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, ], }) const selection = useListSelection({ collection, selectionMode: 'multiple', }) const handleSelectAll = () => { if (selection.isAllSelected()) { selection.clear() } else { selection.setSelectedValues(collection.getValues()) } } return (
                    {selection.selectedValues.length} of {collection.items.length} selected
                    {collection.items.map((item) => ( ))}
                    ) } ``` #### Solid ```tsx import { createListCollection, useListSelection } from '@ark-ui/solid/collection' import { For } from 'solid-js' import styles from 'styles/list-selection.module.css' export const Multiple = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, ], }) const selection = useListSelection({ collection, selectionMode: 'multiple', }) const handleSelectAll = () => { if (selection.isAllSelected()) { selection.clear() } else { selection.setSelectedValues(collection.getValues()) } } return (
                    {selection.selectedValues().length} of {collection.items.length} selected
                    {(item) => ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {selection.selectedValues().length} of {collection.items.length} selected
                    {#each collection.items as item (item.value)} {/each}
                    ``` ### Range Selection Here's an example of how to implement range selection that extends the selection from the first selected item to the clicked item. **Example: list-selection/range** #### React ```tsx import { createListCollection, useListSelection } from '@ark-ui/react/collection' import styles from 'styles/list-selection.module.css' export const Range = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, ], }) const selection = useListSelection({ collection, selectionMode: 'multiple', }) const handleItemClick = (value: string, event: React.MouseEvent) => { if (event.shiftKey && selection.firstSelectedValue) { selection.extend(selection.firstSelectedValue, value) } else if (event.ctrlKey || event.metaKey) { selection.toggle(value) } else { selection.replace(value) } } return (
                    Selected: {selection.selectedValues.join(', ') || 'None'} {collection.items.map((item) => ( ))}

                    Click to select • Shift+Click for range • Cmd/Ctrl+Click to toggle

                    ) } ``` #### Solid ```tsx import { createListCollection, useListSelection } from '@ark-ui/solid/collection' import { For } from 'solid-js' import styles from 'styles/list-selection.module.css' export const Range = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, ], }) const selection = useListSelection({ collection, selectionMode: 'multiple', }) const handleItemClick = (value: string, event: MouseEvent) => { const firstSelectedValue = selection.firstSelectedValue() if (event.shiftKey && firstSelectedValue) { selection.extend(firstSelectedValue, value) } else if (event.ctrlKey || event.metaKey) { selection.toggle(value) } else { selection.replace(value) } } return (
                    Selected: {selection.selectedValues().join(', ') || 'None'} {(item) => ( )}

                    Click to select • Shift+Click for range • Cmd/Ctrl+Click to toggle

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Selected: {selection.selectedValues().join(', ') || 'None'} {#each collection.items as item (item.value)} {/each}

                    Click to select • Shift+Click for range • Cmd/Ctrl+Click to toggle

                    ``` ## API Reference ### Props - **collection** (`ListCollection`) - The collection to manage selection for - **selectionMode** (`'single' | 'multiple' | 'none'`, default: `'single'`) - The selection mode - **deselectable** (`boolean`, default: `true`) - Whether selected items can be deselected - **initialSelectedValues** (`string[]`, default: `[]`) - Initial selected values - **resetOnCollectionChange** (`boolean`, default: `false`) - Whether to reset selection when collection changes ### Return Value The hook returns an object with the following properties and methods: #### State Properties - **selectedValues** (`string[]`) - Array of currently selected values - **isEmpty** (`boolean`) - Whether no items are selected - **firstSelectedValue** (`string | null`) - The first selected value in collection order - **lastSelectedValue** (`string | null`) - The last selected value in collection order #### Query Methods - **isSelected** (`(value: string | null) => boolean`) - Check if a value is selected - **canSelect** (`(value: string) => boolean`) - Check if a value can be selected - **isAllSelected** (`() => boolean`) - Check if all items are selected - **isSomeSelected** (`() => boolean`) - Check if some items are selected #### Selection Methods - **select** (`(value: string, forceToggle?: boolean) => void`) - Select a value - **deselect** (`(value: string) => void`) - Deselect a value - **toggle** (`(value: string) => void`) - Toggle selection of a value - **replace** (`(value: string | null) => void`) - Replace selection with a single value - **extend** (`(anchorValue: string, targetValue: string) => void`) - Extend selection from anchor to target - **setSelectedValues** (`(values: string[]) => void`) - Set the selected values - **setSelection** (`(values: string[]) => void`) - Set the selection (alias for setSelectedValues) - **clear** (`() => void`) - Clear all selections - **resetSelection** (`() => void`) - Reset selection to initial state --- # List Selection (SVELTE) The `useListSelection` hook manages selection state in lists and collections. It supports single and multiple selection modes with operations like select, deselect, toggle, and clear. ```tsx import { createListCollection, useListSelection } from '@ark-ui/react/collection' const collection = createListCollection({ items: [ { label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }, { label: 'Cherry', value: 'cherry' }, ], }) const selection = useListSelection({ collection, selectionMode: 'single', deselectable: true, }) console.log(selection.selectedValues) // ['apple', 'banana', 'cherry'] ``` ## Examples ### Basic By default, the hook supports single selection mode that can be deselected. > Set `deselectable` to `false` to prevent deselecting the current selection. **Example: list-selection/basic** #### React ```tsx import { createListCollection, useListSelection } from '@ark-ui/react/collection' import styles from 'styles/list-selection.module.css' export const Basic = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, ], }) const selection = useListSelection({ collection }) return (
                    Selected: {selection.selectedValues.join(', ') || 'None'} {collection.items.map((item) => ( ))}
                    ) } ``` #### Solid ```tsx import { createListCollection, useListSelection } from '@ark-ui/solid/collection' import { For } from 'solid-js' import styles from 'styles/list-selection.module.css' export const Basic = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, ], }) const selection = useListSelection({ collection }) return (
                    Selected: {selection.selectedValues().join(', ') || 'None'} {(item) => ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Selected: {selection.selectedValues().join(', ') || 'None'} {#each collection.items as item (item.value)} {/each}
                    ``` ### Multiple Selection Set `selectionMode` to `multiple` to allow multiple items to be selected. **Example: list-selection/multiple** #### React ```tsx import { createListCollection, useListSelection } from '@ark-ui/react/collection' import styles from 'styles/list-selection.module.css' export const Multiple = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, ], }) const selection = useListSelection({ collection, selectionMode: 'multiple', }) const handleSelectAll = () => { if (selection.isAllSelected()) { selection.clear() } else { selection.setSelectedValues(collection.getValues()) } } return (
                    {selection.selectedValues.length} of {collection.items.length} selected
                    {collection.items.map((item) => ( ))}
                    ) } ``` #### Solid ```tsx import { createListCollection, useListSelection } from '@ark-ui/solid/collection' import { For } from 'solid-js' import styles from 'styles/list-selection.module.css' export const Multiple = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, ], }) const selection = useListSelection({ collection, selectionMode: 'multiple', }) const handleSelectAll = () => { if (selection.isAllSelected()) { selection.clear() } else { selection.setSelectedValues(collection.getValues()) } } return (
                    {selection.selectedValues().length} of {collection.items.length} selected
                    {(item) => ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {selection.selectedValues().length} of {collection.items.length} selected
                    {#each collection.items as item (item.value)} {/each}
                    ``` ### Range Selection Here's an example of how to implement range selection that extends the selection from the first selected item to the clicked item. **Example: list-selection/range** #### React ```tsx import { createListCollection, useListSelection } from '@ark-ui/react/collection' import styles from 'styles/list-selection.module.css' export const Range = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, ], }) const selection = useListSelection({ collection, selectionMode: 'multiple', }) const handleItemClick = (value: string, event: React.MouseEvent) => { if (event.shiftKey && selection.firstSelectedValue) { selection.extend(selection.firstSelectedValue, value) } else if (event.ctrlKey || event.metaKey) { selection.toggle(value) } else { selection.replace(value) } } return (
                    Selected: {selection.selectedValues.join(', ') || 'None'} {collection.items.map((item) => ( ))}

                    Click to select • Shift+Click for range • Cmd/Ctrl+Click to toggle

                    ) } ``` #### Solid ```tsx import { createListCollection, useListSelection } from '@ark-ui/solid/collection' import { For } from 'solid-js' import styles from 'styles/list-selection.module.css' export const Range = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, ], }) const selection = useListSelection({ collection, selectionMode: 'multiple', }) const handleItemClick = (value: string, event: MouseEvent) => { const firstSelectedValue = selection.firstSelectedValue() if (event.shiftKey && firstSelectedValue) { selection.extend(firstSelectedValue, value) } else if (event.ctrlKey || event.metaKey) { selection.toggle(value) } else { selection.replace(value) } } return (
                    Selected: {selection.selectedValues().join(', ') || 'None'} {(item) => ( )}

                    Click to select • Shift+Click for range • Cmd/Ctrl+Click to toggle

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Selected: {selection.selectedValues().join(', ') || 'None'} {#each collection.items as item (item.value)} {/each}

                    Click to select • Shift+Click for range • Cmd/Ctrl+Click to toggle

                    ``` ## API Reference ### Props - **collection** (`ListCollection`) - The collection to manage selection for - **selectionMode** (`'single' | 'multiple' | 'none'`, default: `'single'`) - The selection mode - **deselectable** (`boolean`, default: `true`) - Whether selected items can be deselected - **initialSelectedValues** (`string[]`, default: `[]`) - Initial selected values - **resetOnCollectionChange** (`boolean`, default: `false`) - Whether to reset selection when collection changes ### Return Value The hook returns an object with the following properties and methods: #### State Properties - **selectedValues** (`string[]`) - Array of currently selected values - **isEmpty** (`boolean`) - Whether no items are selected - **firstSelectedValue** (`string | null`) - The first selected value in collection order - **lastSelectedValue** (`string | null`) - The last selected value in collection order #### Query Methods - **isSelected** (`(value: string | null) => boolean`) - Check if a value is selected - **canSelect** (`(value: string) => boolean`) - Check if a value can be selected - **isAllSelected** (`() => boolean`) - Check if all items are selected - **isSomeSelected** (`() => boolean`) - Check if some items are selected #### Selection Methods - **select** (`(value: string, forceToggle?: boolean) => void`) - Select a value - **deselect** (`(value: string) => void`) - Deselect a value - **toggle** (`(value: string) => void`) - Toggle selection of a value - **replace** (`(value: string | null) => void`) - Replace selection with a single value - **extend** (`(anchorValue: string, targetValue: string) => void`) - Extend selection from anchor to target - **setSelectedValues** (`(values: string[]) => void`) - Set the selected values - **setSelection** (`(values: string[]) => void`) - Set the selection (alias for setSelectedValues) - **clear** (`() => void`) - Clear all selections - **resetSelection** (`() => void`) - Reset selection to initial state --- # List Selection (SOLID) The `useListSelection` hook manages selection state in lists and collections. It supports single and multiple selection modes with operations like select, deselect, toggle, and clear. ```tsx import { createListCollection, useListSelection } from '@ark-ui/react/collection' const collection = createListCollection({ items: [ { label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }, { label: 'Cherry', value: 'cherry' }, ], }) const selection = useListSelection({ collection, selectionMode: 'single', deselectable: true, }) console.log(selection.selectedValues) // ['apple', 'banana', 'cherry'] ``` ## Examples ### Basic By default, the hook supports single selection mode that can be deselected. > Set `deselectable` to `false` to prevent deselecting the current selection. **Example: list-selection/basic** #### React ```tsx import { createListCollection, useListSelection } from '@ark-ui/react/collection' import styles from 'styles/list-selection.module.css' export const Basic = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, ], }) const selection = useListSelection({ collection }) return (
                    Selected: {selection.selectedValues.join(', ') || 'None'} {collection.items.map((item) => ( ))}
                    ) } ``` #### Solid ```tsx import { createListCollection, useListSelection } from '@ark-ui/solid/collection' import { For } from 'solid-js' import styles from 'styles/list-selection.module.css' export const Basic = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, ], }) const selection = useListSelection({ collection }) return (
                    Selected: {selection.selectedValues().join(', ') || 'None'} {(item) => ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Selected: {selection.selectedValues().join(', ') || 'None'} {#each collection.items as item (item.value)} {/each}
                    ``` ### Multiple Selection Set `selectionMode` to `multiple` to allow multiple items to be selected. **Example: list-selection/multiple** #### React ```tsx import { createListCollection, useListSelection } from '@ark-ui/react/collection' import styles from 'styles/list-selection.module.css' export const Multiple = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, ], }) const selection = useListSelection({ collection, selectionMode: 'multiple', }) const handleSelectAll = () => { if (selection.isAllSelected()) { selection.clear() } else { selection.setSelectedValues(collection.getValues()) } } return (
                    {selection.selectedValues.length} of {collection.items.length} selected
                    {collection.items.map((item) => ( ))}
                    ) } ``` #### Solid ```tsx import { createListCollection, useListSelection } from '@ark-ui/solid/collection' import { For } from 'solid-js' import styles from 'styles/list-selection.module.css' export const Multiple = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, ], }) const selection = useListSelection({ collection, selectionMode: 'multiple', }) const handleSelectAll = () => { if (selection.isAllSelected()) { selection.clear() } else { selection.setSelectedValues(collection.getValues()) } } return (
                    {selection.selectedValues().length} of {collection.items.length} selected
                    {(item) => ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {selection.selectedValues().length} of {collection.items.length} selected
                    {#each collection.items as item (item.value)} {/each}
                    ``` ### Range Selection Here's an example of how to implement range selection that extends the selection from the first selected item to the clicked item. **Example: list-selection/range** #### React ```tsx import { createListCollection, useListSelection } from '@ark-ui/react/collection' import styles from 'styles/list-selection.module.css' export const Range = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, ], }) const selection = useListSelection({ collection, selectionMode: 'multiple', }) const handleItemClick = (value: string, event: React.MouseEvent) => { if (event.shiftKey && selection.firstSelectedValue) { selection.extend(selection.firstSelectedValue, value) } else if (event.ctrlKey || event.metaKey) { selection.toggle(value) } else { selection.replace(value) } } return (
                    Selected: {selection.selectedValues.join(', ') || 'None'} {collection.items.map((item) => ( ))}

                    Click to select • Shift+Click for range • Cmd/Ctrl+Click to toggle

                    ) } ``` #### Solid ```tsx import { createListCollection, useListSelection } from '@ark-ui/solid/collection' import { For } from 'solid-js' import styles from 'styles/list-selection.module.css' export const Range = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, ], }) const selection = useListSelection({ collection, selectionMode: 'multiple', }) const handleItemClick = (value: string, event: MouseEvent) => { const firstSelectedValue = selection.firstSelectedValue() if (event.shiftKey && firstSelectedValue) { selection.extend(firstSelectedValue, value) } else if (event.ctrlKey || event.metaKey) { selection.toggle(value) } else { selection.replace(value) } } return (
                    Selected: {selection.selectedValues().join(', ') || 'None'} {(item) => ( )}

                    Click to select • Shift+Click for range • Cmd/Ctrl+Click to toggle

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Selected: {selection.selectedValues().join(', ') || 'None'} {#each collection.items as item (item.value)} {/each}

                    Click to select • Shift+Click for range • Cmd/Ctrl+Click to toggle

                    ``` ## API Reference ### Props - **collection** (`ListCollection`) - The collection to manage selection for - **selectionMode** (`'single' | 'multiple' | 'none'`, default: `'single'`) - The selection mode - **deselectable** (`boolean`, default: `true`) - Whether selected items can be deselected - **initialSelectedValues** (`string[]`, default: `[]`) - Initial selected values - **resetOnCollectionChange** (`boolean`, default: `false`) - Whether to reset selection when collection changes ### Return Value The hook returns an object with the following properties and methods: #### State Properties - **selectedValues** (`string[]`) - Array of currently selected values - **isEmpty** (`boolean`) - Whether no items are selected - **firstSelectedValue** (`string | null`) - The first selected value in collection order - **lastSelectedValue** (`string | null`) - The last selected value in collection order #### Query Methods - **isSelected** (`(value: string | null) => boolean`) - Check if a value is selected - **canSelect** (`(value: string) => boolean`) - Check if a value can be selected - **isAllSelected** (`() => boolean`) - Check if all items are selected - **isSomeSelected** (`() => boolean`) - Check if some items are selected #### Selection Methods - **select** (`(value: string, forceToggle?: boolean) => void`) - Select a value - **deselect** (`(value: string) => void`) - Deselect a value - **toggle** (`(value: string) => void`) - Toggle selection of a value - **replace** (`(value: string | null) => void`) - Replace selection with a single value - **extend** (`(anchorValue: string, targetValue: string) => void`) - Extend selection from anchor to target - **setSelectedValues** (`(values: string[]) => void`) - Set the selected values - **setSelection** (`(values: string[]) => void`) - Set the selection (alias for setSelectedValues) - **clear** (`() => void`) - Clear all selections - **resetSelection** (`() => void`) - Reset selection to initial state --- # Accordion (REACT) ## Anatomy ```tsx ``` ## Examples ### Default Value Set the `defaultValue` prop to specify which item should be expanded by default. **Example: basic** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const Basic = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Basic = () => { return ( {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Controlled Use the `value` and `onValueChange` props to control the expanded items. **Example: controlled** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/accordion.module.css' export const Controlled = () => { const [value, setValue] = useState([]) return ( setValue(details.value)}> {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/accordion.module.css' export const Controlled = () => { const [value, setValue] = createSignal([]) return ( setValue(details.value)}> {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Accordion, useAccordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const RootProvider = () => { const accordion = useAccordion({ multiple: true, defaultValue: ['ark-ui'], }) return (
                    Value: {JSON.stringify(accordion.value)} {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion, useAccordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const RootProvider = () => { const accordion = useAccordion({ multiple: true, defaultValue: ['ark-ui'], }) return (
                    Value: {JSON.stringify(accordion().value)} {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Value: {JSON.stringify(accordion().value)} {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Collapsible Use the `collapsible` prop to allow the user to collapse all panels. **Example: collapsible** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const Collapsible = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Collapsible = () => { return ( {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Multiple Use the `multiple` prop to allow multiple panels to be expanded simultaneously. **Example: multiple** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const Multiple = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Multiple = () => { return ( {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Horizontal By default, the Accordion is oriented vertically. Use the `orientation` prop to switch to a horizontal layout. **Example: horizontal** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import styles from 'styles/accordion.module.css' export const Horizontal = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Horizontal = () => { return ( {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### 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. **Example: lazy-mount** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const LazyMount = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Context Use `Accordion.Context` or `useAccordionContext` to access the accordion state. **Example: context** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const Context = () => { return ( {(context) => (
                    context.value: {JSON.stringify(context.value)}
                    context.focusedValue: {context.focusedValue || 'null'}
                    )}
                    {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Context = () => { return ( {(context) => (
                    context.value: {JSON.stringify(context().value)}
                    context.focusedValue: {context().focusedValue || 'null'}
                    )}
                    {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(context)}
                    context.value: {JSON.stringify(context().value)}
                    context.focusedValue: {context().focusedValue || 'null'}
                    {/snippet}
                    {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Item State Use `Accordion.ItemContext` or `useAccordionItemContext` to access the state of an accordion item. **Example: item-context** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import styles from 'styles/accordion.module.css' export const ItemContext = () => { return ( {items.map((item) => ( {item.title} {(context) => ( {context.expanded && Expanded} {context.focused && Focused} )}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const ItemContext = () => { return ( {(item) => ( {item().title} {(context) => (
                    Expanded: {String(context().expanded)} Focused: {String(context().focused)} Disabled: {String(context().disabled)}
                    )}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title} {#snippet render(context)}
                    Expanded: {context().expanded} Focused: {context().focused} Disabled: {context().disabled}
                    {/snippet}
                    {item.content}
                    {/each}
                    ``` ## Guides ### Content Animation Use the `--height` and/or `--width` CSS variables to animate the size of the content when it expands or closes: ```css @keyframes slideDown { from { opacity: 0.01; height: 0; } to { opacity: 1; height: var(--height); } } @keyframes slideUp { from { opacity: 1; height: var(--height); } to { opacity: 0.01; height: 0; } } [data-scope='accordion'][data-part='item-content'][data-state='open'] { animation: slideDown 250ms ease-in-out; } [data-scope='accordion'][data-part='item-content'][data-state='closed'] { animation: slideUp 200ms ease-in-out; } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsible` | `boolean` | No | Whether an accordion item can be closed after it has been expanded. | | `defaultValue` | `string[]` | No | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | `disabled` | `boolean` | No | Whether the accordion items are disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item: (value: string) => string itemContent: (value: string) => string itemTrigger: (value: string) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `multiple` | `boolean` | No | Whether multiple accordion items can be expanded at the same time. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | The callback fired when the focused accordion item changes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the state of expanded/collapsed accordion items changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the accordion items. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the expanded accordion items. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | root | | `[data-orientation]` | The orientation of the accordion | **ItemContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-content | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the accordion item. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the accordion item is disabled. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | **ItemTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-trigger | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "open" | "closed" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAccordionReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsible` | `boolean` | No | Whether an accordion item can be closed after it has been expanded. | | `defaultValue` | `string[]` | No | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | `disabled` | `boolean` | No | Whether the accordion items are disabled | | `ids` | `Partial<{ root: string item: (value: string) => string itemContent: (value: string) => string itemTrigger: (value: string) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `multiple` | `boolean` | No | Whether multiple accordion items can be expanded at the same time. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | The callback fired when the focused accordion item changes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the state of expanded/collapsed accordion items changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the accordion items. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the expanded accordion items. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | root | | `[data-orientation]` | The orientation of the accordion | **ItemContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-content | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the accordion item. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the accordion item is disabled. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | **ItemTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-trigger | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "open" | "closed" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAccordionReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsible` | `boolean` | No | Whether an accordion item can be closed after it has been expanded. | | `defaultValue` | `string[]` | No | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | `disabled` | `boolean` | No | Whether the accordion items are disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item(value: string): string itemContent(value: string): string itemTrigger(value: string): string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modelValue` | `string[]` | No | The v-model value of the accordion | | `multiple` | `boolean` | No | Whether multiple accordion items can be expanded at the same time. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the accordion items. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | root | | `[data-orientation]` | The orientation of the accordion | **ItemContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-content | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the accordion item. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the accordion item is disabled. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | **ItemTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-trigger | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "open" | "closed" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `AccordionApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsible` | `boolean` | No | Whether an accordion item can be closed after it has been expanded. | | `defaultValue` | `string[]` | No | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | `disabled` | `boolean` | No | Whether the accordion items are disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item: (value: string) => string itemContent: (value: string) => string itemTrigger: (value: string) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `multiple` | `boolean` | No | Whether multiple accordion items can be expanded at the same time. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | The callback fired when the focused accordion item changes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the state of expanded/collapsed accordion items changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the accordion items. | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the expanded accordion items. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | root | | `[data-orientation]` | The orientation of the accordion | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseAccordionContext]>` | Yes | | **ItemContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-content | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseAccordionItemContext]>` | Yes | | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the accordion item. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the accordion item is disabled. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | **ItemTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-trigger | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "open" | "closed" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAccordionReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focusedValue` | `string` | The value of the focused accordion item. | | `value` | `string[]` | The value of the accordion | | `setValue` | `(value: string[]) => void` | Sets the value of the accordion | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of an accordion item. | ## Accessibility This component complies with the [Accordion WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/accordion/). ### Keyboard Support **`Space`** Description: When focus is on an trigger of a collapsed item, the item is expanded **`Enter`** Description: When focus is on an trigger of a collapsed section, expands the section. **`Tab`** Description: Moves focus to the next focusable element **`Shift + Tab`** Description: Moves focus to the previous focusable element **`ArrowDown`** Description: Moves focus to the next trigger **`ArrowUp`** Description: Moves focus to the previous trigger. **`Home`** Description: When focus is on an trigger, moves focus to the first trigger. **`End`** Description: When focus is on an trigger, moves focus to the last trigger. --- # Accordion (VUE) ## Anatomy ```tsx ``` ## Examples ### Default Value Set the `defaultValue` prop to specify which item should be expanded by default. **Example: basic** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const Basic = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Basic = () => { return ( {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Controlled Use the `value` and `onValueChange` props to control the expanded items. **Example: controlled** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/accordion.module.css' export const Controlled = () => { const [value, setValue] = useState([]) return ( setValue(details.value)}> {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/accordion.module.css' export const Controlled = () => { const [value, setValue] = createSignal([]) return ( setValue(details.value)}> {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Accordion, useAccordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const RootProvider = () => { const accordion = useAccordion({ multiple: true, defaultValue: ['ark-ui'], }) return (
                    Value: {JSON.stringify(accordion.value)} {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion, useAccordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const RootProvider = () => { const accordion = useAccordion({ multiple: true, defaultValue: ['ark-ui'], }) return (
                    Value: {JSON.stringify(accordion().value)} {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Value: {JSON.stringify(accordion().value)} {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Collapsible Use the `collapsible` prop to allow the user to collapse all panels. **Example: collapsible** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const Collapsible = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Collapsible = () => { return ( {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Multiple Use the `multiple` prop to allow multiple panels to be expanded simultaneously. **Example: multiple** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const Multiple = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Multiple = () => { return ( {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Horizontal By default, the Accordion is oriented vertically. Use the `orientation` prop to switch to a horizontal layout. **Example: horizontal** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import styles from 'styles/accordion.module.css' export const Horizontal = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Horizontal = () => { return ( {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### 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. **Example: lazy-mount** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const LazyMount = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Context Use `Accordion.Context` or `useAccordionContext` to access the accordion state. **Example: context** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const Context = () => { return ( {(context) => (
                    context.value: {JSON.stringify(context.value)}
                    context.focusedValue: {context.focusedValue || 'null'}
                    )}
                    {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Context = () => { return ( {(context) => (
                    context.value: {JSON.stringify(context().value)}
                    context.focusedValue: {context().focusedValue || 'null'}
                    )}
                    {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(context)}
                    context.value: {JSON.stringify(context().value)}
                    context.focusedValue: {context().focusedValue || 'null'}
                    {/snippet}
                    {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Item State Use `Accordion.ItemContext` or `useAccordionItemContext` to access the state of an accordion item. **Example: item-context** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import styles from 'styles/accordion.module.css' export const ItemContext = () => { return ( {items.map((item) => ( {item.title} {(context) => ( {context.expanded && Expanded} {context.focused && Focused} )}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const ItemContext = () => { return ( {(item) => ( {item().title} {(context) => (
                    Expanded: {String(context().expanded)} Focused: {String(context().focused)} Disabled: {String(context().disabled)}
                    )}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title} {#snippet render(context)}
                    Expanded: {context().expanded} Focused: {context().focused} Disabled: {context().disabled}
                    {/snippet}
                    {item.content}
                    {/each}
                    ``` ## Guides ### Content Animation Use the `--height` and/or `--width` CSS variables to animate the size of the content when it expands or closes: ```css @keyframes slideDown { from { opacity: 0.01; height: 0; } to { opacity: 1; height: var(--height); } } @keyframes slideUp { from { opacity: 1; height: var(--height); } to { opacity: 0.01; height: 0; } } [data-scope='accordion'][data-part='item-content'][data-state='open'] { animation: slideDown 250ms ease-in-out; } [data-scope='accordion'][data-part='item-content'][data-state='closed'] { animation: slideUp 200ms ease-in-out; } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsible` | `boolean` | No | Whether an accordion item can be closed after it has been expanded. | | `defaultValue` | `string[]` | No | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | `disabled` | `boolean` | No | Whether the accordion items are disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item: (value: string) => string itemContent: (value: string) => string itemTrigger: (value: string) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `multiple` | `boolean` | No | Whether multiple accordion items can be expanded at the same time. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | The callback fired when the focused accordion item changes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the state of expanded/collapsed accordion items changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the accordion items. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the expanded accordion items. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | root | | `[data-orientation]` | The orientation of the accordion | **ItemContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-content | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the accordion item. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the accordion item is disabled. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | **ItemTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-trigger | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "open" | "closed" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAccordionReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsible` | `boolean` | No | Whether an accordion item can be closed after it has been expanded. | | `defaultValue` | `string[]` | No | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | `disabled` | `boolean` | No | Whether the accordion items are disabled | | `ids` | `Partial<{ root: string item: (value: string) => string itemContent: (value: string) => string itemTrigger: (value: string) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `multiple` | `boolean` | No | Whether multiple accordion items can be expanded at the same time. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | The callback fired when the focused accordion item changes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the state of expanded/collapsed accordion items changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the accordion items. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the expanded accordion items. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | root | | `[data-orientation]` | The orientation of the accordion | **ItemContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-content | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the accordion item. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the accordion item is disabled. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | **ItemTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-trigger | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "open" | "closed" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAccordionReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsible` | `boolean` | No | Whether an accordion item can be closed after it has been expanded. | | `defaultValue` | `string[]` | No | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | `disabled` | `boolean` | No | Whether the accordion items are disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item(value: string): string itemContent(value: string): string itemTrigger(value: string): string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modelValue` | `string[]` | No | The v-model value of the accordion | | `multiple` | `boolean` | No | Whether multiple accordion items can be expanded at the same time. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the accordion items. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | root | | `[data-orientation]` | The orientation of the accordion | **ItemContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-content | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the accordion item. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the accordion item is disabled. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | **ItemTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-trigger | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "open" | "closed" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `AccordionApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsible` | `boolean` | No | Whether an accordion item can be closed after it has been expanded. | | `defaultValue` | `string[]` | No | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | `disabled` | `boolean` | No | Whether the accordion items are disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item: (value: string) => string itemContent: (value: string) => string itemTrigger: (value: string) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `multiple` | `boolean` | No | Whether multiple accordion items can be expanded at the same time. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | The callback fired when the focused accordion item changes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the state of expanded/collapsed accordion items changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the accordion items. | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the expanded accordion items. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | root | | `[data-orientation]` | The orientation of the accordion | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseAccordionContext]>` | Yes | | **ItemContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-content | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseAccordionItemContext]>` | Yes | | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the accordion item. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the accordion item is disabled. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | **ItemTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-trigger | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "open" | "closed" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAccordionReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focusedValue` | `string` | The value of the focused accordion item. | | `value` | `string[]` | The value of the accordion | | `setValue` | `(value: string[]) => void` | Sets the value of the accordion | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of an accordion item. | ## Accessibility This component complies with the [Accordion WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/accordion/). ### Keyboard Support **`Space`** Description: When focus is on an trigger of a collapsed item, the item is expanded **`Enter`** Description: When focus is on an trigger of a collapsed section, expands the section. **`Tab`** Description: Moves focus to the next focusable element **`Shift + Tab`** Description: Moves focus to the previous focusable element **`ArrowDown`** Description: Moves focus to the next trigger **`ArrowUp`** Description: Moves focus to the previous trigger. **`Home`** Description: When focus is on an trigger, moves focus to the first trigger. **`End`** Description: When focus is on an trigger, moves focus to the last trigger. --- # Accordion (SVELTE) ## Anatomy ```tsx ``` ## Examples ### Default Value Set the `defaultValue` prop to specify which item should be expanded by default. **Example: basic** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const Basic = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Basic = () => { return ( {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Controlled Use the `value` and `onValueChange` props to control the expanded items. **Example: controlled** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/accordion.module.css' export const Controlled = () => { const [value, setValue] = useState([]) return ( setValue(details.value)}> {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/accordion.module.css' export const Controlled = () => { const [value, setValue] = createSignal([]) return ( setValue(details.value)}> {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Accordion, useAccordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const RootProvider = () => { const accordion = useAccordion({ multiple: true, defaultValue: ['ark-ui'], }) return (
                    Value: {JSON.stringify(accordion.value)} {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion, useAccordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const RootProvider = () => { const accordion = useAccordion({ multiple: true, defaultValue: ['ark-ui'], }) return (
                    Value: {JSON.stringify(accordion().value)} {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Value: {JSON.stringify(accordion().value)} {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Collapsible Use the `collapsible` prop to allow the user to collapse all panels. **Example: collapsible** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const Collapsible = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Collapsible = () => { return ( {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Multiple Use the `multiple` prop to allow multiple panels to be expanded simultaneously. **Example: multiple** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const Multiple = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Multiple = () => { return ( {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Horizontal By default, the Accordion is oriented vertically. Use the `orientation` prop to switch to a horizontal layout. **Example: horizontal** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import styles from 'styles/accordion.module.css' export const Horizontal = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Horizontal = () => { return ( {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### 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. **Example: lazy-mount** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const LazyMount = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Context Use `Accordion.Context` or `useAccordionContext` to access the accordion state. **Example: context** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const Context = () => { return ( {(context) => (
                    context.value: {JSON.stringify(context.value)}
                    context.focusedValue: {context.focusedValue || 'null'}
                    )}
                    {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Context = () => { return ( {(context) => (
                    context.value: {JSON.stringify(context().value)}
                    context.focusedValue: {context().focusedValue || 'null'}
                    )}
                    {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(context)}
                    context.value: {JSON.stringify(context().value)}
                    context.focusedValue: {context().focusedValue || 'null'}
                    {/snippet}
                    {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Item State Use `Accordion.ItemContext` or `useAccordionItemContext` to access the state of an accordion item. **Example: item-context** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import styles from 'styles/accordion.module.css' export const ItemContext = () => { return ( {items.map((item) => ( {item.title} {(context) => ( {context.expanded && Expanded} {context.focused && Focused} )}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const ItemContext = () => { return ( {(item) => ( {item().title} {(context) => (
                    Expanded: {String(context().expanded)} Focused: {String(context().focused)} Disabled: {String(context().disabled)}
                    )}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title} {#snippet render(context)}
                    Expanded: {context().expanded} Focused: {context().focused} Disabled: {context().disabled}
                    {/snippet}
                    {item.content}
                    {/each}
                    ``` ## Guides ### Content Animation Use the `--height` and/or `--width` CSS variables to animate the size of the content when it expands or closes: ```css @keyframes slideDown { from { opacity: 0.01; height: 0; } to { opacity: 1; height: var(--height); } } @keyframes slideUp { from { opacity: 1; height: var(--height); } to { opacity: 0.01; height: 0; } } [data-scope='accordion'][data-part='item-content'][data-state='open'] { animation: slideDown 250ms ease-in-out; } [data-scope='accordion'][data-part='item-content'][data-state='closed'] { animation: slideUp 200ms ease-in-out; } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsible` | `boolean` | No | Whether an accordion item can be closed after it has been expanded. | | `defaultValue` | `string[]` | No | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | `disabled` | `boolean` | No | Whether the accordion items are disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item: (value: string) => string itemContent: (value: string) => string itemTrigger: (value: string) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `multiple` | `boolean` | No | Whether multiple accordion items can be expanded at the same time. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | The callback fired when the focused accordion item changes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the state of expanded/collapsed accordion items changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the accordion items. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the expanded accordion items. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | root | | `[data-orientation]` | The orientation of the accordion | **ItemContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-content | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the accordion item. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the accordion item is disabled. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | **ItemTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-trigger | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "open" | "closed" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAccordionReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsible` | `boolean` | No | Whether an accordion item can be closed after it has been expanded. | | `defaultValue` | `string[]` | No | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | `disabled` | `boolean` | No | Whether the accordion items are disabled | | `ids` | `Partial<{ root: string item: (value: string) => string itemContent: (value: string) => string itemTrigger: (value: string) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `multiple` | `boolean` | No | Whether multiple accordion items can be expanded at the same time. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | The callback fired when the focused accordion item changes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the state of expanded/collapsed accordion items changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the accordion items. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the expanded accordion items. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | root | | `[data-orientation]` | The orientation of the accordion | **ItemContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-content | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the accordion item. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the accordion item is disabled. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | **ItemTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-trigger | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "open" | "closed" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAccordionReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsible` | `boolean` | No | Whether an accordion item can be closed after it has been expanded. | | `defaultValue` | `string[]` | No | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | `disabled` | `boolean` | No | Whether the accordion items are disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item(value: string): string itemContent(value: string): string itemTrigger(value: string): string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modelValue` | `string[]` | No | The v-model value of the accordion | | `multiple` | `boolean` | No | Whether multiple accordion items can be expanded at the same time. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the accordion items. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | root | | `[data-orientation]` | The orientation of the accordion | **ItemContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-content | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the accordion item. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the accordion item is disabled. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | **ItemTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-trigger | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "open" | "closed" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `AccordionApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsible` | `boolean` | No | Whether an accordion item can be closed after it has been expanded. | | `defaultValue` | `string[]` | No | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | `disabled` | `boolean` | No | Whether the accordion items are disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item: (value: string) => string itemContent: (value: string) => string itemTrigger: (value: string) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `multiple` | `boolean` | No | Whether multiple accordion items can be expanded at the same time. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | The callback fired when the focused accordion item changes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the state of expanded/collapsed accordion items changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the accordion items. | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the expanded accordion items. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | root | | `[data-orientation]` | The orientation of the accordion | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseAccordionContext]>` | Yes | | **ItemContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-content | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseAccordionItemContext]>` | Yes | | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the accordion item. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the accordion item is disabled. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | **ItemTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-trigger | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "open" | "closed" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAccordionReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focusedValue` | `string` | The value of the focused accordion item. | | `value` | `string[]` | The value of the accordion | | `setValue` | `(value: string[]) => void` | Sets the value of the accordion | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of an accordion item. | ## Accessibility This component complies with the [Accordion WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/accordion/). ### Keyboard Support **`Space`** Description: When focus is on an trigger of a collapsed item, the item is expanded **`Enter`** Description: When focus is on an trigger of a collapsed section, expands the section. **`Tab`** Description: Moves focus to the next focusable element **`Shift + Tab`** Description: Moves focus to the previous focusable element **`ArrowDown`** Description: Moves focus to the next trigger **`ArrowUp`** Description: Moves focus to the previous trigger. **`Home`** Description: When focus is on an trigger, moves focus to the first trigger. **`End`** Description: When focus is on an trigger, moves focus to the last trigger. --- # Accordion (SOLID) ## Anatomy ```tsx ``` ## Examples ### Default Value Set the `defaultValue` prop to specify which item should be expanded by default. **Example: basic** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const Basic = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Basic = () => { return ( {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Controlled Use the `value` and `onValueChange` props to control the expanded items. **Example: controlled** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/accordion.module.css' export const Controlled = () => { const [value, setValue] = useState([]) return ( setValue(details.value)}> {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/accordion.module.css' export const Controlled = () => { const [value, setValue] = createSignal([]) return ( setValue(details.value)}> {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Accordion, useAccordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const RootProvider = () => { const accordion = useAccordion({ multiple: true, defaultValue: ['ark-ui'], }) return (
                    Value: {JSON.stringify(accordion.value)} {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion, useAccordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const RootProvider = () => { const accordion = useAccordion({ multiple: true, defaultValue: ['ark-ui'], }) return (
                    Value: {JSON.stringify(accordion().value)} {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Value: {JSON.stringify(accordion().value)} {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Collapsible Use the `collapsible` prop to allow the user to collapse all panels. **Example: collapsible** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const Collapsible = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Collapsible = () => { return ( {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Multiple Use the `multiple` prop to allow multiple panels to be expanded simultaneously. **Example: multiple** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const Multiple = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Multiple = () => { return ( {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Horizontal By default, the Accordion is oriented vertically. Use the `orientation` prop to switch to a horizontal layout. **Example: horizontal** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import styles from 'styles/accordion.module.css' export const Horizontal = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Horizontal = () => { return ( {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### 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. **Example: lazy-mount** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const LazyMount = () => { return ( {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Context Use `Accordion.Context` or `useAccordionContext` to access the accordion state. **Example: context** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/accordion.module.css' export const Context = () => { return ( {(context) => (
                    context.value: {JSON.stringify(context.value)}
                    context.focusedValue: {context.focusedValue || 'null'}
                    )}
                    {items.map((item) => ( {item.title}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const Context = () => { return ( {(context) => (
                    context.value: {JSON.stringify(context().value)}
                    context.focusedValue: {context().focusedValue || 'null'}
                    )}
                    {(item) => ( {item().title}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(context)}
                    context.value: {JSON.stringify(context().value)}
                    context.focusedValue: {context().focusedValue || 'null'}
                    {/snippet}
                    {#each items as item (item.value)} {item.title}
                    {item.content}
                    {/each}
                    ``` ### Item State Use `Accordion.ItemContext` or `useAccordionItemContext` to access the state of an accordion item. **Example: item-context** #### React ```tsx import { Accordion } from '@ark-ui/react/accordion' import styles from 'styles/accordion.module.css' export const ItemContext = () => { return ( {items.map((item) => ( {item.title} {(context) => ( {context.expanded && Expanded} {context.focused && Focused} )}
                    {item.content}
                    ))}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Solid ```tsx import { Accordion } from '@ark-ui/solid/accordion' import { ChevronDownIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/accordion.module.css' export const ItemContext = () => { return ( {(item) => ( {item().title} {(context) => (
                    Expanded: {String(context().expanded)} Focused: {String(context().focused)} Disabled: {String(context().disabled)}
                    )}
                    {item().content}
                    )}
                    ) } const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.title} {#snippet render(context)}
                    Expanded: {context().expanded} Focused: {context().focused} Disabled: {context().disabled}
                    {/snippet}
                    {item.content}
                    {/each}
                    ``` ## Guides ### Content Animation Use the `--height` and/or `--width` CSS variables to animate the size of the content when it expands or closes: ```css @keyframes slideDown { from { opacity: 0.01; height: 0; } to { opacity: 1; height: var(--height); } } @keyframes slideUp { from { opacity: 1; height: var(--height); } to { opacity: 0.01; height: 0; } } [data-scope='accordion'][data-part='item-content'][data-state='open'] { animation: slideDown 250ms ease-in-out; } [data-scope='accordion'][data-part='item-content'][data-state='closed'] { animation: slideUp 200ms ease-in-out; } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsible` | `boolean` | No | Whether an accordion item can be closed after it has been expanded. | | `defaultValue` | `string[]` | No | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | `disabled` | `boolean` | No | Whether the accordion items are disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item: (value: string) => string itemContent: (value: string) => string itemTrigger: (value: string) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `multiple` | `boolean` | No | Whether multiple accordion items can be expanded at the same time. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | The callback fired when the focused accordion item changes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the state of expanded/collapsed accordion items changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the accordion items. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the expanded accordion items. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | root | | `[data-orientation]` | The orientation of the accordion | **ItemContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-content | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the accordion item. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the accordion item is disabled. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | **ItemTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-trigger | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "open" | "closed" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAccordionReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsible` | `boolean` | No | Whether an accordion item can be closed after it has been expanded. | | `defaultValue` | `string[]` | No | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | `disabled` | `boolean` | No | Whether the accordion items are disabled | | `ids` | `Partial<{ root: string item: (value: string) => string itemContent: (value: string) => string itemTrigger: (value: string) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `multiple` | `boolean` | No | Whether multiple accordion items can be expanded at the same time. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | The callback fired when the focused accordion item changes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the state of expanded/collapsed accordion items changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the accordion items. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the expanded accordion items. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | root | | `[data-orientation]` | The orientation of the accordion | **ItemContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-content | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the accordion item. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the accordion item is disabled. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | **ItemTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-trigger | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "open" | "closed" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAccordionReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsible` | `boolean` | No | Whether an accordion item can be closed after it has been expanded. | | `defaultValue` | `string[]` | No | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | `disabled` | `boolean` | No | Whether the accordion items are disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item(value: string): string itemContent(value: string): string itemTrigger(value: string): string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modelValue` | `string[]` | No | The v-model value of the accordion | | `multiple` | `boolean` | No | Whether multiple accordion items can be expanded at the same time. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the accordion items. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | root | | `[data-orientation]` | The orientation of the accordion | **ItemContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-content | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the accordion item. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the accordion item is disabled. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | **ItemTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-trigger | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "open" | "closed" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `AccordionApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsible` | `boolean` | No | Whether an accordion item can be closed after it has been expanded. | | `defaultValue` | `string[]` | No | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | `disabled` | `boolean` | No | Whether the accordion items are disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item: (value: string) => string itemContent: (value: string) => string itemTrigger: (value: string) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `multiple` | `boolean` | No | Whether multiple accordion items can be expanded at the same time. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | The callback fired when the focused accordion item changes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the state of expanded/collapsed accordion items changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the accordion items. | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the expanded accordion items. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | root | | `[data-orientation]` | The orientation of the accordion | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseAccordionContext]>` | Yes | | **ItemContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-content | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseAccordionItemContext]>` | Yes | | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the accordion item. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the accordion item is disabled. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | **ItemTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-trigger | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "open" | "closed" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAccordionReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focusedValue` | `string` | The value of the focused accordion item. | | `value` | `string[]` | The value of the accordion | | `setValue` | `(value: string[]) => void` | Sets the value of the accordion | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of an accordion item. | ## Accessibility This component complies with the [Accordion WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/accordion/). ### Keyboard Support **`Space`** Description: When focus is on an trigger of a collapsed item, the item is expanded **`Enter`** Description: When focus is on an trigger of a collapsed section, expands the section. **`Tab`** Description: Moves focus to the next focusable element **`Shift + Tab`** Description: Moves focus to the previous focusable element **`ArrowDown`** Description: Moves focus to the next trigger **`ArrowUp`** Description: Moves focus to the previous trigger. **`Home`** Description: When focus is on an trigger, moves focus to the first trigger. **`End`** Description: When focus is on an trigger, moves focus to the last trigger. --- # Angle Slider (REACT) ## Anatomy ```tsx ``` ## Examples ### Basic Here's a basic example of the Angle Slider component. **Example: basic** #### React ```tsx import { AngleSlider } from '@ark-ui/react/angle-slider' import styles from 'styles/angle-slider.module.css' export const Basic = () => { return ( Rotation {[0, 45, 90, 135, 180, 225, 270, 315].map((value) => ( ))} ) } ``` #### Solid ```tsx import { AngleSlider } from '@ark-ui/solid/angle-slider' import { For } from 'solid-js' import styles from 'styles/angle-slider.module.css' export const Basic = () => { return ( Rotation {(value) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Rotation {#each [0, 45, 90, 135, 180, 225, 270, 315] as value} {/each} ``` ### Controlled Use the `value` and `onValueChange` props to control the value of the Angle Slider. **Example: controlled** #### React ```tsx import { AngleSlider } from '@ark-ui/react/angle-slider' import { useState } from 'react' import styles from 'styles/angle-slider.module.css' export const Controlled = () => { const [value, setValue] = useState(45) return ( setValue(e.value)}> Rotation {[0, 45, 90, 135, 180, 225, 270, 315].map((value) => ( ))} ) } ``` #### Solid ```tsx import { AngleSlider } from '@ark-ui/solid/angle-slider' import { For, createSignal } from 'solid-js' import styles from 'styles/angle-slider.module.css' export const Controlled = () => { const [value, setValue] = createSignal(45) return ( setValue(e.value)}> Rotation {(value) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Rotation {#each [0, 45, 90, 135, 180, 225, 270, 315] as markerValue} {/each} ``` ### Steps Use the `step` prop to set the discrete steps of the Angle Slider. **Example: step** #### React ```tsx import { AngleSlider } from '@ark-ui/react/angle-slider' import styles from 'styles/angle-slider.module.css' export const Step = () => { return ( 15 Step {[0, 45, 90, 135, 180, 225, 270, 315].map((value) => ( ))} ) } ``` #### Solid ```tsx import { AngleSlider } from '@ark-ui/solid/angle-slider' import { For } from 'solid-js' import styles from 'styles/angle-slider.module.css' export const Step = () => { return ( 15 Step {(value) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte 15 Step {#each [0, 45, 90, 135, 180, 225, 270, 315] as value} {/each} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | The accessible label for the slider thumb. | | `aria-labelledby` | `string` | No | The id of the element that labels the slider thumb. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number` | No | The initial value of the slider. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: string hiddenInput: string control: string valueText: string label: string }>` | No | The ids of the elements in the machine. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid. | | `name` | `string` | No | The name of the slider. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes ends. | | `readOnly` | `boolean` | No | Whether the slider is read-only. | | `step` | `number` | No | The step value for the slider. | | `value` | `number` | No | The value of the slider. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | | `--angle` | The angle in degrees | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | The value of the marker | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | marker | | `[data-value]` | The value of the item | | `[data-state]` | | | `[data-disabled]` | Present when disabled | **Marker CSS Variables:** | Variable | Description | |----------|-------------| | `--marker-value` | The marker value value for the Marker | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAngleSliderReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number` | No | The initial value of the slider. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled. | | `ids` | `Partial<{ root: string thumb: string hiddenInput: string control: string valueText: string label: string }>` | No | The ids of the elements in the machine. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid. | | `name` | `string` | No | The name of the slider. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes ends. | | `readOnly` | `boolean` | No | Whether the slider is read-only. | | `step` | `number` | No | The step value for the slider. | | `value` | `number` | No | The value of the slider. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | | `--angle` | The angle in degrees | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | The value of the marker | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | marker | | `[data-value]` | The value of the item | | `[data-state]` | | | `[data-disabled]` | Present when disabled | **Marker CSS Variables:** | Variable | Description | |----------|-------------| | `--marker-value` | The marker value value for the Marker | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAngleSliderReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | The aria-label of the slider. | | `aria-labelledby` | `string` | No | The aria-labelledby of the slider. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number` | No | The initial value of the slider. Use when you don't need to control the value of the slider. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the slider is disabled. | | `getRootNode` | `() => ShadowRoot | Node | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; thumb: string; hiddenInput: string; control: string; valueText: string }>` | No | The ids of the elements in the machine. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid. | | `modelValue` | `number` | No | The v-model value of the angle slider | | `name` | `string` | No | The name of the slider. Useful for form submission. | | `readOnly` | `boolean` | No | Whether the slider is read-only. | | `step` | `number` | No | The step value for the slider. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | | `--angle` | The angle in degrees | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | The value of the marker | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | marker | | `[data-value]` | The value of the item | | `[data-state]` | | | `[data-disabled]` | Present when disabled | **Marker CSS Variables:** | Variable | Description | |----------|-------------| | `--marker-value` | The marker value value for the Marker | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `AngleSliderApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | The accessible label for the slider thumb. | | `aria-labelledby` | `string` | No | The id of the element that labels the slider thumb. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number` | No | The initial value of the slider. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: string hiddenInput: string control: string valueText: string label: string }>` | No | The ids of the elements in the machine. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid. | | `name` | `string` | No | The name of the slider. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes ends. | | `readOnly` | `boolean` | No | Whether the slider is read-only. | | `ref` | `Element` | No | | | `step` | `number` | No | The step value for the slider. | | `value` | `number` | No | The value of the slider. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | | `--angle` | The angle in degrees | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseAngleSliderContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | The value of the marker | | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | marker | | `[data-value]` | The value of the item | | `[data-state]` | | | `[data-disabled]` | Present when disabled | **Marker CSS Variables:** | Variable | Description | |----------|-------------| | `--marker-value` | The marker value value for the Marker | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAngleSliderReturn` | Yes | | | `ref` | `Element` | No | | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `number` | The current value of the angle slider | | `valueAsDegree` | `string` | The current value as a degree string | | `setValue` | `(value: number) => void` | Sets the value of the angle slider | | `dragging` | `boolean` | Whether the slider is being dragged. | --- # Angle Slider (VUE) ## Anatomy ```tsx ``` ## Examples ### Basic Here's a basic example of the Angle Slider component. **Example: basic** #### React ```tsx import { AngleSlider } from '@ark-ui/react/angle-slider' import styles from 'styles/angle-slider.module.css' export const Basic = () => { return ( Rotation {[0, 45, 90, 135, 180, 225, 270, 315].map((value) => ( ))} ) } ``` #### Solid ```tsx import { AngleSlider } from '@ark-ui/solid/angle-slider' import { For } from 'solid-js' import styles from 'styles/angle-slider.module.css' export const Basic = () => { return ( Rotation {(value) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Rotation {#each [0, 45, 90, 135, 180, 225, 270, 315] as value} {/each} ``` ### Controlled Use the `value` and `onValueChange` props to control the value of the Angle Slider. **Example: controlled** #### React ```tsx import { AngleSlider } from '@ark-ui/react/angle-slider' import { useState } from 'react' import styles from 'styles/angle-slider.module.css' export const Controlled = () => { const [value, setValue] = useState(45) return ( setValue(e.value)}> Rotation {[0, 45, 90, 135, 180, 225, 270, 315].map((value) => ( ))} ) } ``` #### Solid ```tsx import { AngleSlider } from '@ark-ui/solid/angle-slider' import { For, createSignal } from 'solid-js' import styles from 'styles/angle-slider.module.css' export const Controlled = () => { const [value, setValue] = createSignal(45) return ( setValue(e.value)}> Rotation {(value) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Rotation {#each [0, 45, 90, 135, 180, 225, 270, 315] as markerValue} {/each} ``` ### Steps Use the `step` prop to set the discrete steps of the Angle Slider. **Example: step** #### React ```tsx import { AngleSlider } from '@ark-ui/react/angle-slider' import styles from 'styles/angle-slider.module.css' export const Step = () => { return ( 15 Step {[0, 45, 90, 135, 180, 225, 270, 315].map((value) => ( ))} ) } ``` #### Solid ```tsx import { AngleSlider } from '@ark-ui/solid/angle-slider' import { For } from 'solid-js' import styles from 'styles/angle-slider.module.css' export const Step = () => { return ( 15 Step {(value) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte 15 Step {#each [0, 45, 90, 135, 180, 225, 270, 315] as value} {/each} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | The accessible label for the slider thumb. | | `aria-labelledby` | `string` | No | The id of the element that labels the slider thumb. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number` | No | The initial value of the slider. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: string hiddenInput: string control: string valueText: string label: string }>` | No | The ids of the elements in the machine. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid. | | `name` | `string` | No | The name of the slider. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes ends. | | `readOnly` | `boolean` | No | Whether the slider is read-only. | | `step` | `number` | No | The step value for the slider. | | `value` | `number` | No | The value of the slider. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | | `--angle` | The angle in degrees | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | The value of the marker | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | marker | | `[data-value]` | The value of the item | | `[data-state]` | | | `[data-disabled]` | Present when disabled | **Marker CSS Variables:** | Variable | Description | |----------|-------------| | `--marker-value` | The marker value value for the Marker | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAngleSliderReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number` | No | The initial value of the slider. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled. | | `ids` | `Partial<{ root: string thumb: string hiddenInput: string control: string valueText: string label: string }>` | No | The ids of the elements in the machine. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid. | | `name` | `string` | No | The name of the slider. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes ends. | | `readOnly` | `boolean` | No | Whether the slider is read-only. | | `step` | `number` | No | The step value for the slider. | | `value` | `number` | No | The value of the slider. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | | `--angle` | The angle in degrees | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | The value of the marker | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | marker | | `[data-value]` | The value of the item | | `[data-state]` | | | `[data-disabled]` | Present when disabled | **Marker CSS Variables:** | Variable | Description | |----------|-------------| | `--marker-value` | The marker value value for the Marker | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAngleSliderReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | The aria-label of the slider. | | `aria-labelledby` | `string` | No | The aria-labelledby of the slider. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number` | No | The initial value of the slider. Use when you don't need to control the value of the slider. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the slider is disabled. | | `getRootNode` | `() => ShadowRoot | Node | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; thumb: string; hiddenInput: string; control: string; valueText: string }>` | No | The ids of the elements in the machine. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid. | | `modelValue` | `number` | No | The v-model value of the angle slider | | `name` | `string` | No | The name of the slider. Useful for form submission. | | `readOnly` | `boolean` | No | Whether the slider is read-only. | | `step` | `number` | No | The step value for the slider. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | | `--angle` | The angle in degrees | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | The value of the marker | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | marker | | `[data-value]` | The value of the item | | `[data-state]` | | | `[data-disabled]` | Present when disabled | **Marker CSS Variables:** | Variable | Description | |----------|-------------| | `--marker-value` | The marker value value for the Marker | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `AngleSliderApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | The accessible label for the slider thumb. | | `aria-labelledby` | `string` | No | The id of the element that labels the slider thumb. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number` | No | The initial value of the slider. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: string hiddenInput: string control: string valueText: string label: string }>` | No | The ids of the elements in the machine. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid. | | `name` | `string` | No | The name of the slider. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes ends. | | `readOnly` | `boolean` | No | Whether the slider is read-only. | | `ref` | `Element` | No | | | `step` | `number` | No | The step value for the slider. | | `value` | `number` | No | The value of the slider. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | | `--angle` | The angle in degrees | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseAngleSliderContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | The value of the marker | | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | marker | | `[data-value]` | The value of the item | | `[data-state]` | | | `[data-disabled]` | Present when disabled | **Marker CSS Variables:** | Variable | Description | |----------|-------------| | `--marker-value` | The marker value value for the Marker | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAngleSliderReturn` | Yes | | | `ref` | `Element` | No | | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `number` | The current value of the angle slider | | `valueAsDegree` | `string` | The current value as a degree string | | `setValue` | `(value: number) => void` | Sets the value of the angle slider | | `dragging` | `boolean` | Whether the slider is being dragged. | --- # Angle Slider (SVELTE) ## Anatomy ```tsx ``` ## Examples ### Basic Here's a basic example of the Angle Slider component. **Example: basic** #### React ```tsx import { AngleSlider } from '@ark-ui/react/angle-slider' import styles from 'styles/angle-slider.module.css' export const Basic = () => { return ( Rotation {[0, 45, 90, 135, 180, 225, 270, 315].map((value) => ( ))} ) } ``` #### Solid ```tsx import { AngleSlider } from '@ark-ui/solid/angle-slider' import { For } from 'solid-js' import styles from 'styles/angle-slider.module.css' export const Basic = () => { return ( Rotation {(value) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Rotation {#each [0, 45, 90, 135, 180, 225, 270, 315] as value} {/each} ``` ### Controlled Use the `value` and `onValueChange` props to control the value of the Angle Slider. **Example: controlled** #### React ```tsx import { AngleSlider } from '@ark-ui/react/angle-slider' import { useState } from 'react' import styles from 'styles/angle-slider.module.css' export const Controlled = () => { const [value, setValue] = useState(45) return ( setValue(e.value)}> Rotation {[0, 45, 90, 135, 180, 225, 270, 315].map((value) => ( ))} ) } ``` #### Solid ```tsx import { AngleSlider } from '@ark-ui/solid/angle-slider' import { For, createSignal } from 'solid-js' import styles from 'styles/angle-slider.module.css' export const Controlled = () => { const [value, setValue] = createSignal(45) return ( setValue(e.value)}> Rotation {(value) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Rotation {#each [0, 45, 90, 135, 180, 225, 270, 315] as markerValue} {/each} ``` ### Steps Use the `step` prop to set the discrete steps of the Angle Slider. **Example: step** #### React ```tsx import { AngleSlider } from '@ark-ui/react/angle-slider' import styles from 'styles/angle-slider.module.css' export const Step = () => { return ( 15 Step {[0, 45, 90, 135, 180, 225, 270, 315].map((value) => ( ))} ) } ``` #### Solid ```tsx import { AngleSlider } from '@ark-ui/solid/angle-slider' import { For } from 'solid-js' import styles from 'styles/angle-slider.module.css' export const Step = () => { return ( 15 Step {(value) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte 15 Step {#each [0, 45, 90, 135, 180, 225, 270, 315] as value} {/each} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | The accessible label for the slider thumb. | | `aria-labelledby` | `string` | No | The id of the element that labels the slider thumb. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number` | No | The initial value of the slider. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: string hiddenInput: string control: string valueText: string label: string }>` | No | The ids of the elements in the machine. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid. | | `name` | `string` | No | The name of the slider. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes ends. | | `readOnly` | `boolean` | No | Whether the slider is read-only. | | `step` | `number` | No | The step value for the slider. | | `value` | `number` | No | The value of the slider. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | | `--angle` | The angle in degrees | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | The value of the marker | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | marker | | `[data-value]` | The value of the item | | `[data-state]` | | | `[data-disabled]` | Present when disabled | **Marker CSS Variables:** | Variable | Description | |----------|-------------| | `--marker-value` | The marker value value for the Marker | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAngleSliderReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number` | No | The initial value of the slider. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled. | | `ids` | `Partial<{ root: string thumb: string hiddenInput: string control: string valueText: string label: string }>` | No | The ids of the elements in the machine. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid. | | `name` | `string` | No | The name of the slider. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes ends. | | `readOnly` | `boolean` | No | Whether the slider is read-only. | | `step` | `number` | No | The step value for the slider. | | `value` | `number` | No | The value of the slider. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | | `--angle` | The angle in degrees | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | The value of the marker | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | marker | | `[data-value]` | The value of the item | | `[data-state]` | | | `[data-disabled]` | Present when disabled | **Marker CSS Variables:** | Variable | Description | |----------|-------------| | `--marker-value` | The marker value value for the Marker | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAngleSliderReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | The aria-label of the slider. | | `aria-labelledby` | `string` | No | The aria-labelledby of the slider. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number` | No | The initial value of the slider. Use when you don't need to control the value of the slider. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the slider is disabled. | | `getRootNode` | `() => ShadowRoot | Node | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; thumb: string; hiddenInput: string; control: string; valueText: string }>` | No | The ids of the elements in the machine. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid. | | `modelValue` | `number` | No | The v-model value of the angle slider | | `name` | `string` | No | The name of the slider. Useful for form submission. | | `readOnly` | `boolean` | No | Whether the slider is read-only. | | `step` | `number` | No | The step value for the slider. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | | `--angle` | The angle in degrees | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | The value of the marker | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | marker | | `[data-value]` | The value of the item | | `[data-state]` | | | `[data-disabled]` | Present when disabled | **Marker CSS Variables:** | Variable | Description | |----------|-------------| | `--marker-value` | The marker value value for the Marker | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `AngleSliderApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | The accessible label for the slider thumb. | | `aria-labelledby` | `string` | No | The id of the element that labels the slider thumb. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number` | No | The initial value of the slider. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: string hiddenInput: string control: string valueText: string label: string }>` | No | The ids of the elements in the machine. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid. | | `name` | `string` | No | The name of the slider. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes ends. | | `readOnly` | `boolean` | No | Whether the slider is read-only. | | `ref` | `Element` | No | | | `step` | `number` | No | The step value for the slider. | | `value` | `number` | No | The value of the slider. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | | `--angle` | The angle in degrees | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseAngleSliderContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | The value of the marker | | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | marker | | `[data-value]` | The value of the item | | `[data-state]` | | | `[data-disabled]` | Present when disabled | **Marker CSS Variables:** | Variable | Description | |----------|-------------| | `--marker-value` | The marker value value for the Marker | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAngleSliderReturn` | Yes | | | `ref` | `Element` | No | | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `number` | The current value of the angle slider | | `valueAsDegree` | `string` | The current value as a degree string | | `setValue` | `(value: number) => void` | Sets the value of the angle slider | | `dragging` | `boolean` | Whether the slider is being dragged. | --- # Angle Slider (SOLID) ## Anatomy ```tsx ``` ## Examples ### Basic Here's a basic example of the Angle Slider component. **Example: basic** #### React ```tsx import { AngleSlider } from '@ark-ui/react/angle-slider' import styles from 'styles/angle-slider.module.css' export const Basic = () => { return ( Rotation {[0, 45, 90, 135, 180, 225, 270, 315].map((value) => ( ))} ) } ``` #### Solid ```tsx import { AngleSlider } from '@ark-ui/solid/angle-slider' import { For } from 'solid-js' import styles from 'styles/angle-slider.module.css' export const Basic = () => { return ( Rotation {(value) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Rotation {#each [0, 45, 90, 135, 180, 225, 270, 315] as value} {/each} ``` ### Controlled Use the `value` and `onValueChange` props to control the value of the Angle Slider. **Example: controlled** #### React ```tsx import { AngleSlider } from '@ark-ui/react/angle-slider' import { useState } from 'react' import styles from 'styles/angle-slider.module.css' export const Controlled = () => { const [value, setValue] = useState(45) return ( setValue(e.value)}> Rotation {[0, 45, 90, 135, 180, 225, 270, 315].map((value) => ( ))} ) } ``` #### Solid ```tsx import { AngleSlider } from '@ark-ui/solid/angle-slider' import { For, createSignal } from 'solid-js' import styles from 'styles/angle-slider.module.css' export const Controlled = () => { const [value, setValue] = createSignal(45) return ( setValue(e.value)}> Rotation {(value) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Rotation {#each [0, 45, 90, 135, 180, 225, 270, 315] as markerValue} {/each} ``` ### Steps Use the `step` prop to set the discrete steps of the Angle Slider. **Example: step** #### React ```tsx import { AngleSlider } from '@ark-ui/react/angle-slider' import styles from 'styles/angle-slider.module.css' export const Step = () => { return ( 15 Step {[0, 45, 90, 135, 180, 225, 270, 315].map((value) => ( ))} ) } ``` #### Solid ```tsx import { AngleSlider } from '@ark-ui/solid/angle-slider' import { For } from 'solid-js' import styles from 'styles/angle-slider.module.css' export const Step = () => { return ( 15 Step {(value) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte 15 Step {#each [0, 45, 90, 135, 180, 225, 270, 315] as value} {/each} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | The accessible label for the slider thumb. | | `aria-labelledby` | `string` | No | The id of the element that labels the slider thumb. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number` | No | The initial value of the slider. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: string hiddenInput: string control: string valueText: string label: string }>` | No | The ids of the elements in the machine. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid. | | `name` | `string` | No | The name of the slider. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes ends. | | `readOnly` | `boolean` | No | Whether the slider is read-only. | | `step` | `number` | No | The step value for the slider. | | `value` | `number` | No | The value of the slider. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | | `--angle` | The angle in degrees | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | The value of the marker | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | marker | | `[data-value]` | The value of the item | | `[data-state]` | | | `[data-disabled]` | Present when disabled | **Marker CSS Variables:** | Variable | Description | |----------|-------------| | `--marker-value` | The marker value value for the Marker | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAngleSliderReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number` | No | The initial value of the slider. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled. | | `ids` | `Partial<{ root: string thumb: string hiddenInput: string control: string valueText: string label: string }>` | No | The ids of the elements in the machine. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid. | | `name` | `string` | No | The name of the slider. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes ends. | | `readOnly` | `boolean` | No | Whether the slider is read-only. | | `step` | `number` | No | The step value for the slider. | | `value` | `number` | No | The value of the slider. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | | `--angle` | The angle in degrees | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | The value of the marker | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | marker | | `[data-value]` | The value of the item | | `[data-state]` | | | `[data-disabled]` | Present when disabled | **Marker CSS Variables:** | Variable | Description | |----------|-------------| | `--marker-value` | The marker value value for the Marker | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAngleSliderReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | The aria-label of the slider. | | `aria-labelledby` | `string` | No | The aria-labelledby of the slider. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number` | No | The initial value of the slider. Use when you don't need to control the value of the slider. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the slider is disabled. | | `getRootNode` | `() => ShadowRoot | Node | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; thumb: string; hiddenInput: string; control: string; valueText: string }>` | No | The ids of the elements in the machine. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid. | | `modelValue` | `number` | No | The v-model value of the angle slider | | `name` | `string` | No | The name of the slider. Useful for form submission. | | `readOnly` | `boolean` | No | Whether the slider is read-only. | | `step` | `number` | No | The step value for the slider. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | | `--angle` | The angle in degrees | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | The value of the marker | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | marker | | `[data-value]` | The value of the item | | `[data-state]` | | | `[data-disabled]` | Present when disabled | **Marker CSS Variables:** | Variable | Description | |----------|-------------| | `--marker-value` | The marker value value for the Marker | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `AngleSliderApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | The accessible label for the slider thumb. | | `aria-labelledby` | `string` | No | The id of the element that labels the slider thumb. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number` | No | The initial value of the slider. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: string hiddenInput: string control: string valueText: string label: string }>` | No | The ids of the elements in the machine. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid. | | `name` | `string` | No | The name of the slider. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | The callback function for when the value changes ends. | | `readOnly` | `boolean` | No | Whether the slider is read-only. | | `ref` | `Element` | No | | | `step` | `number` | No | The step value for the slider. | | `value` | `number` | No | The value of the slider. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | | `--angle` | The angle in degrees | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseAngleSliderContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | The value of the marker | | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | marker | | `[data-value]` | The value of the item | | `[data-state]` | | | `[data-disabled]` | Present when disabled | **Marker CSS Variables:** | Variable | Description | |----------|-------------| | `--marker-value` | The marker value value for the Marker | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAngleSliderReturn` | Yes | | | `ref` | `Element` | No | | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | angle-slider | | `[data-part]` | thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `number` | The current value of the angle slider | | `valueAsDegree` | `string` | The current value as a degree string | | `setValue` | `(value: number) => void` | Sets the value of the angle slider | | `dragging` | `boolean` | Whether the slider is being dragged. | --- # Avatar (REACT) ## Anatomy ```tsx ``` ## Examples ### Basic Display a user's profile image with a fallback. **Example: basic** #### React ```tsx import { Avatar } from '@ark-ui/react/avatar' import styles from 'styles/avatar.module.css' export const Basic = () => ( PA ) ``` #### Solid ```tsx import { Avatar } from '@ark-ui/solid/avatar' import styles from 'styles/avatar.module.css' export const Basic = () => ( PA ) ``` #### Vue ```vue ``` #### Svelte ```svelte PA ``` ### Events Use `onStatusChange` to listen for loading state changes. **Example: events** #### React ```tsx import { Avatar } from '@ark-ui/react/avatar' import { useState } from 'react' import styles from 'styles/avatar.module.css' export const Events = () => { const [status, setStatus] = useState('loading...') return (
                    Status: {status} setStatus(e.status)}> PA
                    ) } ``` #### Solid ```tsx import { Avatar } from '@ark-ui/solid/avatar' import { createSignal } from 'solid-js' import styles from 'styles/avatar.module.css' export const Events = () => { const [status, setStatus] = createSignal('loading...') return (
                    Status: {status()} setStatus(e.status)}> PA
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Status: {status} (status = e.status)}> PA
                    ``` ### Root Provider An alternative way to control the avatar is to use the `RootProvider` component and the `useAvatar` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { Avatar, useAvatar } from '@ark-ui/react/avatar' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/avatar.module.css' export const RootProvider = () => { const [count, setCount] = useState(0) const avatar = useAvatar() return (
                    PA
                    ) } ``` #### Solid ```tsx import { Avatar, useAvatar } from '@ark-ui/solid/avatar' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/avatar.module.css' export const RootProvider = () => { const [count, setCount] = createSignal(0) const avatar = useAvatar() return (
                    PA
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    PA
                    ``` ## Guides ### Next.js Image Here's an example of how to use the `Image` component from `next/image`. ```tsx import { Avatar, useAvatarContext } from '@ark-ui/react/avatar' import { getImageProps, type ImageProps } from 'next/image' const AvatarNextImage = (props: ImageProps) => { const avatar = useAvatarContext() const { hidden, ...arkImageProps } = avatar.getImageProps() const nextImage = getImageProps(props) return ( ) } const Demo = () => { return ( JD ) } ``` > Refer to this [Github Discussion](https://github.com/chakra-ui/ark/discussions/3147) for more information. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ids` | `Partial<{ root: string; image: string; fallback: string }>` | No | The ids of the elements in the avatar. Useful for composition. | | `onStatusChange` | `(details: StatusChangeDetails) => void` | No | Functional called when the image loading status changes. | **Fallback Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Fallback Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | fallback | | `[data-state]` | "hidden" | "visible" | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | image | | `[data-state]` | "visible" | "hidden" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAvatarReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ids` | `Partial<{ root: string; image: string; fallback: string }>` | No | The ids of the elements in the avatar. Useful for composition. | | `onStatusChange` | `(details: StatusChangeDetails) => void` | No | Functional called when the image loading status changes. | **Fallback Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Fallback Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | fallback | | `[data-state]` | "hidden" | "visible" | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'img'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | image | | `[data-state]` | "visible" | "hidden" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAvatarReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; image: string; fallback: string }>` | No | The ids of the elements in the avatar. Useful for composition. | **Fallback Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Fallback Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | fallback | | `[data-state]` | "hidden" | "visible" | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | image | | `[data-state]` | "visible" | "hidden" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `AvatarApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; image: string; fallback: string }>` | No | The ids of the elements in the avatar. Useful for composition. | | `onStatusChange` | `(details: StatusChangeDetails) => void` | No | Functional called when the image loading status changes. | | `ref` | `Element` | No | | **Fallback Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Fallback Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | fallback | | `[data-state]` | "hidden" | "visible" | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'img'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | image | | `[data-state]` | "visible" | "hidden" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAvatarReturn` | Yes | | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `loaded` | `boolean` | Whether the image is loaded. | | `setSrc` | `(src: string) => void` | Function to set new src. | | `setLoaded` | `VoidFunction` | Function to set loaded state. | | `setError` | `VoidFunction` | Function to set error state. | --- # Avatar (VUE) ## Anatomy ```tsx ``` ## Examples ### Basic Display a user's profile image with a fallback. **Example: basic** #### React ```tsx import { Avatar } from '@ark-ui/react/avatar' import styles from 'styles/avatar.module.css' export const Basic = () => ( PA ) ``` #### Solid ```tsx import { Avatar } from '@ark-ui/solid/avatar' import styles from 'styles/avatar.module.css' export const Basic = () => ( PA ) ``` #### Vue ```vue ``` #### Svelte ```svelte PA ``` ### Events Use `onStatusChange` to listen for loading state changes. **Example: events** #### React ```tsx import { Avatar } from '@ark-ui/react/avatar' import { useState } from 'react' import styles from 'styles/avatar.module.css' export const Events = () => { const [status, setStatus] = useState('loading...') return (
                    Status: {status} setStatus(e.status)}> PA
                    ) } ``` #### Solid ```tsx import { Avatar } from '@ark-ui/solid/avatar' import { createSignal } from 'solid-js' import styles from 'styles/avatar.module.css' export const Events = () => { const [status, setStatus] = createSignal('loading...') return (
                    Status: {status()} setStatus(e.status)}> PA
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Status: {status} (status = e.status)}> PA
                    ``` ### Root Provider An alternative way to control the avatar is to use the `RootProvider` component and the `useAvatar` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { Avatar, useAvatar } from '@ark-ui/react/avatar' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/avatar.module.css' export const RootProvider = () => { const [count, setCount] = useState(0) const avatar = useAvatar() return (
                    PA
                    ) } ``` #### Solid ```tsx import { Avatar, useAvatar } from '@ark-ui/solid/avatar' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/avatar.module.css' export const RootProvider = () => { const [count, setCount] = createSignal(0) const avatar = useAvatar() return (
                    PA
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    PA
                    ``` ## Guides ### Next.js Image Here's an example of how to use the `Image` component from `next/image`. ```tsx import { Avatar, useAvatarContext } from '@ark-ui/react/avatar' import { getImageProps, type ImageProps } from 'next/image' const AvatarNextImage = (props: ImageProps) => { const avatar = useAvatarContext() const { hidden, ...arkImageProps } = avatar.getImageProps() const nextImage = getImageProps(props) return ( ) } const Demo = () => { return ( JD ) } ``` > Refer to this [Github Discussion](https://github.com/chakra-ui/ark/discussions/3147) for more information. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ids` | `Partial<{ root: string; image: string; fallback: string }>` | No | The ids of the elements in the avatar. Useful for composition. | | `onStatusChange` | `(details: StatusChangeDetails) => void` | No | Functional called when the image loading status changes. | **Fallback Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Fallback Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | fallback | | `[data-state]` | "hidden" | "visible" | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | image | | `[data-state]` | "visible" | "hidden" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAvatarReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ids` | `Partial<{ root: string; image: string; fallback: string }>` | No | The ids of the elements in the avatar. Useful for composition. | | `onStatusChange` | `(details: StatusChangeDetails) => void` | No | Functional called when the image loading status changes. | **Fallback Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Fallback Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | fallback | | `[data-state]` | "hidden" | "visible" | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'img'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | image | | `[data-state]` | "visible" | "hidden" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAvatarReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; image: string; fallback: string }>` | No | The ids of the elements in the avatar. Useful for composition. | **Fallback Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Fallback Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | fallback | | `[data-state]` | "hidden" | "visible" | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | image | | `[data-state]` | "visible" | "hidden" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `AvatarApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; image: string; fallback: string }>` | No | The ids of the elements in the avatar. Useful for composition. | | `onStatusChange` | `(details: StatusChangeDetails) => void` | No | Functional called when the image loading status changes. | | `ref` | `Element` | No | | **Fallback Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Fallback Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | fallback | | `[data-state]` | "hidden" | "visible" | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'img'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | image | | `[data-state]` | "visible" | "hidden" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAvatarReturn` | Yes | | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `loaded` | `boolean` | Whether the image is loaded. | | `setSrc` | `(src: string) => void` | Function to set new src. | | `setLoaded` | `VoidFunction` | Function to set loaded state. | | `setError` | `VoidFunction` | Function to set error state. | --- # Avatar (SVELTE) ## Anatomy ```tsx ``` ## Examples ### Basic Display a user's profile image with a fallback. **Example: basic** #### React ```tsx import { Avatar } from '@ark-ui/react/avatar' import styles from 'styles/avatar.module.css' export const Basic = () => ( PA ) ``` #### Solid ```tsx import { Avatar } from '@ark-ui/solid/avatar' import styles from 'styles/avatar.module.css' export const Basic = () => ( PA ) ``` #### Vue ```vue ``` #### Svelte ```svelte PA ``` ### Events Use `onStatusChange` to listen for loading state changes. **Example: events** #### React ```tsx import { Avatar } from '@ark-ui/react/avatar' import { useState } from 'react' import styles from 'styles/avatar.module.css' export const Events = () => { const [status, setStatus] = useState('loading...') return (
                    Status: {status} setStatus(e.status)}> PA
                    ) } ``` #### Solid ```tsx import { Avatar } from '@ark-ui/solid/avatar' import { createSignal } from 'solid-js' import styles from 'styles/avatar.module.css' export const Events = () => { const [status, setStatus] = createSignal('loading...') return (
                    Status: {status()} setStatus(e.status)}> PA
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Status: {status} (status = e.status)}> PA
                    ``` ### Root Provider An alternative way to control the avatar is to use the `RootProvider` component and the `useAvatar` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { Avatar, useAvatar } from '@ark-ui/react/avatar' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/avatar.module.css' export const RootProvider = () => { const [count, setCount] = useState(0) const avatar = useAvatar() return (
                    PA
                    ) } ``` #### Solid ```tsx import { Avatar, useAvatar } from '@ark-ui/solid/avatar' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/avatar.module.css' export const RootProvider = () => { const [count, setCount] = createSignal(0) const avatar = useAvatar() return (
                    PA
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    PA
                    ``` ## Guides ### Next.js Image Here's an example of how to use the `Image` component from `next/image`. ```tsx import { Avatar, useAvatarContext } from '@ark-ui/react/avatar' import { getImageProps, type ImageProps } from 'next/image' const AvatarNextImage = (props: ImageProps) => { const avatar = useAvatarContext() const { hidden, ...arkImageProps } = avatar.getImageProps() const nextImage = getImageProps(props) return ( ) } const Demo = () => { return ( JD ) } ``` > Refer to this [Github Discussion](https://github.com/chakra-ui/ark/discussions/3147) for more information. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ids` | `Partial<{ root: string; image: string; fallback: string }>` | No | The ids of the elements in the avatar. Useful for composition. | | `onStatusChange` | `(details: StatusChangeDetails) => void` | No | Functional called when the image loading status changes. | **Fallback Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Fallback Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | fallback | | `[data-state]` | "hidden" | "visible" | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | image | | `[data-state]` | "visible" | "hidden" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAvatarReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ids` | `Partial<{ root: string; image: string; fallback: string }>` | No | The ids of the elements in the avatar. Useful for composition. | | `onStatusChange` | `(details: StatusChangeDetails) => void` | No | Functional called when the image loading status changes. | **Fallback Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Fallback Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | fallback | | `[data-state]` | "hidden" | "visible" | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'img'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | image | | `[data-state]` | "visible" | "hidden" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAvatarReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; image: string; fallback: string }>` | No | The ids of the elements in the avatar. Useful for composition. | **Fallback Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Fallback Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | fallback | | `[data-state]` | "hidden" | "visible" | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | image | | `[data-state]` | "visible" | "hidden" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `AvatarApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; image: string; fallback: string }>` | No | The ids of the elements in the avatar. Useful for composition. | | `onStatusChange` | `(details: StatusChangeDetails) => void` | No | Functional called when the image loading status changes. | | `ref` | `Element` | No | | **Fallback Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Fallback Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | fallback | | `[data-state]` | "hidden" | "visible" | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'img'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | image | | `[data-state]` | "visible" | "hidden" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAvatarReturn` | Yes | | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `loaded` | `boolean` | Whether the image is loaded. | | `setSrc` | `(src: string) => void` | Function to set new src. | | `setLoaded` | `VoidFunction` | Function to set loaded state. | | `setError` | `VoidFunction` | Function to set error state. | --- # Avatar (SOLID) ## Anatomy ```tsx ``` ## Examples ### Basic Display a user's profile image with a fallback. **Example: basic** #### React ```tsx import { Avatar } from '@ark-ui/react/avatar' import styles from 'styles/avatar.module.css' export const Basic = () => ( PA ) ``` #### Solid ```tsx import { Avatar } from '@ark-ui/solid/avatar' import styles from 'styles/avatar.module.css' export const Basic = () => ( PA ) ``` #### Vue ```vue ``` #### Svelte ```svelte PA ``` ### Events Use `onStatusChange` to listen for loading state changes. **Example: events** #### React ```tsx import { Avatar } from '@ark-ui/react/avatar' import { useState } from 'react' import styles from 'styles/avatar.module.css' export const Events = () => { const [status, setStatus] = useState('loading...') return (
                    Status: {status} setStatus(e.status)}> PA
                    ) } ``` #### Solid ```tsx import { Avatar } from '@ark-ui/solid/avatar' import { createSignal } from 'solid-js' import styles from 'styles/avatar.module.css' export const Events = () => { const [status, setStatus] = createSignal('loading...') return (
                    Status: {status()} setStatus(e.status)}> PA
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Status: {status} (status = e.status)}> PA
                    ``` ### Root Provider An alternative way to control the avatar is to use the `RootProvider` component and the `useAvatar` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { Avatar, useAvatar } from '@ark-ui/react/avatar' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/avatar.module.css' export const RootProvider = () => { const [count, setCount] = useState(0) const avatar = useAvatar() return (
                    PA
                    ) } ``` #### Solid ```tsx import { Avatar, useAvatar } from '@ark-ui/solid/avatar' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/avatar.module.css' export const RootProvider = () => { const [count, setCount] = createSignal(0) const avatar = useAvatar() return (
                    PA
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    PA
                    ``` ## Guides ### Next.js Image Here's an example of how to use the `Image` component from `next/image`. ```tsx import { Avatar, useAvatarContext } from '@ark-ui/react/avatar' import { getImageProps, type ImageProps } from 'next/image' const AvatarNextImage = (props: ImageProps) => { const avatar = useAvatarContext() const { hidden, ...arkImageProps } = avatar.getImageProps() const nextImage = getImageProps(props) return ( ) } const Demo = () => { return ( JD ) } ``` > Refer to this [Github Discussion](https://github.com/chakra-ui/ark/discussions/3147) for more information. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ids` | `Partial<{ root: string; image: string; fallback: string }>` | No | The ids of the elements in the avatar. Useful for composition. | | `onStatusChange` | `(details: StatusChangeDetails) => void` | No | Functional called when the image loading status changes. | **Fallback Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Fallback Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | fallback | | `[data-state]` | "hidden" | "visible" | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | image | | `[data-state]` | "visible" | "hidden" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAvatarReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ids` | `Partial<{ root: string; image: string; fallback: string }>` | No | The ids of the elements in the avatar. Useful for composition. | | `onStatusChange` | `(details: StatusChangeDetails) => void` | No | Functional called when the image loading status changes. | **Fallback Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Fallback Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | fallback | | `[data-state]` | "hidden" | "visible" | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'img'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | image | | `[data-state]` | "visible" | "hidden" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAvatarReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; image: string; fallback: string }>` | No | The ids of the elements in the avatar. Useful for composition. | **Fallback Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Fallback Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | fallback | | `[data-state]` | "hidden" | "visible" | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | image | | `[data-state]` | "visible" | "hidden" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `AvatarApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; image: string; fallback: string }>` | No | The ids of the elements in the avatar. Useful for composition. | | `onStatusChange` | `(details: StatusChangeDetails) => void` | No | Functional called when the image loading status changes. | | `ref` | `Element` | No | | **Fallback Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Fallback Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | fallback | | `[data-state]` | "hidden" | "visible" | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'img'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | avatar | | `[data-part]` | image | | `[data-state]` | "visible" | "hidden" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAvatarReturn` | Yes | | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `loaded` | `boolean` | Whether the image is loaded. | | `setSrc` | `(src: string) => void` | Function to set new src. | | `setLoaded` | `VoidFunction` | Function to set loaded state. | | `setError` | `VoidFunction` | Function to set error state. | --- # Carousel (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Basic = () => { return ( {images.map((image, index) => ( {image.alt} ))} {images.map((_, index) => ( ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Basic = () => { return ( {(image, index) => ( {image().alt} )} {(_, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each images as image, index} {image.alt} {/each} {#each images as _, index} {/each} ``` ### 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: **Example: controlled** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Controlled = () => { const [page, setPage] = useState(0) return ( setPage(e.page)}> {images.map((image, index) => ( {image.alt} ))} {images.map((_, index) => ( ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Controlled = () => { const [page, setPage] = createSignal(0) return ( setPage(details.page)} > {(image, index) => ( {image().alt} )} {(_, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Current page: {page}
                    {#each images as image, index} {image.alt} {/each} {#each images as _, index} {/each}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Carousel, useCarousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const RootProvider = () => { const carousel = useCarousel({ slideCount: images.length }) return (
                    Page: {carousel.page} {images.map((image, index) => ( {image.alt} ))} {images.map((_, index) => ( ))}
                    ) } ``` #### Solid ```tsx import { Carousel, useCarousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const RootProvider = () => { const carousel = useCarousel({ slideCount: images.length }) return (
                    Page: {carousel().page} {(image, index) => ( {image().alt} )} {(_, index) => }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Page: {carousel().page} {#each images as image, index} {image.alt} {/each} {#each images as _, index} {/each}
                    ``` ### Autoplay Pass the `autoplay` and `loop` props to `Carousel.Root` to make the carousel play automatically. **Example: autoplay** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ChevronLeftIcon, ChevronRightIcon, PauseIcon, PlayIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Autoplay = () => { return ( {images.map((image, index) => ( {image.alt} ))} }> ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ChevronLeftIcon, ChevronRightIcon, PauseIcon, PlayIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Autoplay = () => { return ( {(image, index) => ( {image().alt} )} }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each images as image, index} {image.alt} {/each} {#snippet fallback()}{/snippet} ``` ### 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. **Example: pause-on-hover** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const PauseOnHover = () => { return ( {({ isPlaying }) => ( Autoplay is: {isPlaying ? 'playing' : 'paused'} )} {(api) => ( api.pause()} onPointerLeave={() => api.play()} > {images.map((image, index) => ( {image.alt} ))} )} {images.map((_, index) => ( ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const PauseOnHover = () => { return ( {(carousel) => ( Autoplay is: {carousel().isPlaying ? 'playing' : 'paused'} )} {(api) => ( api().pause()} onPointerLeave={() => api().play()} > {(image, index) => ( {image().alt} )} )} {(_, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(api)} Autoplay is: {api().isPlaying ? 'playing' : 'paused'} {/snippet} {#snippet render(api)} api().pause()} onpointerleave={() => api().play()} > {#each images as image, index} {image.alt} {/each} {/snippet} {#each images as _, index} {/each} ``` ### Thumbnail Indicators Replace default indicator dots with image thumbnails. Render each thumbnail inside `Carousel.Indicator` to create a visual preview of each slide: **Example: thumbnail-indicator** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const ThumbnailIndicator = () => { return ( {images.map((image, index) => ( {image.alt} ))} {images.map((image, index) => ( {image.alt} ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const ThumbnailIndicator = () => { return ( {(image, index) => ( {image().alt} )} {(image, index) => ( {image().alt} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each images as image, index} {image.alt} {/each} {#each images as image, index} {image.alt} {/each} ``` ### 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. **Example: vertical** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowDownIcon, ArrowUpIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Vertical = () => { return ( {images.map((image, index) => ( {image.alt} ))} {images.map((_, index) => ( ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowDownIcon, ArrowUpIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Vertical = () => { return ( {(image, index) => ( {image().alt} )} {(_, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each images as image, index} {image.alt} {/each} {#each images as _, index} {/each} ``` ### 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. **Example: dynamic-slides** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon, PlusIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/carousel.module.css' export const DynamicSlides = () => { const [slides, setSlides] = useState([0, 1, 2, 3, 4]) const [page, setPage] = useState(0) const addSlide = () => { setSlides((prevSlides) => { const max = Math.max(...prevSlides) return [...prevSlides, max + 1] }) } return (
                    setPage(details.page)} > {slides.map((slide, index) => (
                    Slide {slide + 1}
                    ))}
                    {slides.map((_, index) => ( ))}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon, PlusIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/carousel.module.css' export const DynamicSlides = () => { const [slides, setSlides] = createSignal([0, 1, 2, 3, 4]) const [page, setPage] = createSignal(0) const addSlide = () => { setSlides((prevSlides) => { const max = Math.max(...prevSlides) return [...prevSlides, max + 1] }) } return (
                    setPage(details.page)} > {(slide, index) => (
                    Slide {slide() + 1}
                    )}
                    {(_, index) => }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each slides as slide, index}
                    Slide {slide + 1}
                    {/each}
                    {#each slides as _, index} {/each}
                    ``` ### 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. **Example: scroll-to** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/carousel.module.css' export const ScrollTo = () => { return ( {(api) => ( )} {Array.from({ length: 5 }, (_, index) => (
                    Slide {index + 1}
                    ))}
                    {Array.from({ length: 5 }, (_, index) => ( ))}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/carousel.module.css' const slides = Array.from({ length: 6 }) export const ScrollTo = () => { return ( {(api) => ( )} {(_, index) => (
                    Slide {index + 1}
                    )}
                    {(_, index) => }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(api)} {/snippet} {#each slides as _, index}
                    Slide {index + 1}
                    {/each}
                    {#each slides as _, index} {/each}
                    ``` ### 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. **Example: slides-per-page** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' export const SlidesPerPage = () => { const slides = Array.from({ length: 6 }) return ( {slides.map((_, index) => (
                    Slide {index + 1}
                    ))}
                    {(api) => ( {api.pageSnapPoints.map((_, index) => ( ))} )}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const slides = Array.from({ length: 6 }) export const SlidesPerPage = () => { return ( {(_, index) => (
                    Slide {index + 1}
                    )}
                    {(api) => ( {(_, index) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each slides as _, index}
                    Slide {index + 1}
                    {/each}
                    {#snippet render(api)} {#each api().pageSnapPoints as _, index} {/each} {/snippet}
                    ``` ### 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. **Example: spacing** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const slides = Array.from({ length: 6 }) export const Spacing = () => { return ( spacing='48px' {slides.map((_, index) => (
                    {index + 1}
                    ))}
                    {(api) => ( {api.pageSnapPoints.map((_, index) => ( ))} )}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const slides = Array.from({ length: 6 }) export const Spacing = () => { return ( spacing='48px' {(_, index) => (
                    {index + 1}
                    )}
                    {(api) => ( {(_, index) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte spacing='48px' {#each slides as _, index}
                    {index + 1}
                    {/each}
                    {#snippet render(api)} {#each api().pageSnapPoints as _, index} {/each} {/snippet}
                    ``` ### 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. **Example: variable-size** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const items = [ { id: '1', width: '120px', label: 'Small' }, { id: '2', width: '200px', label: 'Medium Size' }, { id: '3', width: '80px', label: 'XS' }, { id: '4', width: '250px', label: 'Large Content Here' }, { id: '5', width: '150px', label: 'Regular' }, ] export const VariableSize = () => { return ( {items.map((item, index) => (
                    {item.label}
                    ))}
                    {(api) => ( {api.pageSnapPoints.map((_, index) => ( ))} )}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/carousel.module.css' const items = [ { id: '1', width: '120px', label: 'Small' }, { id: '2', width: '200px', label: 'Medium Size' }, { id: '3', width: '80px', label: 'XS' }, { id: '4', width: '250px', label: 'Large Content Here' }, { id: '5', width: '150px', label: 'Regular' }, ] export const VariableSize = () => { return ( {(item, index) => (
                    {item.label}
                    )}
                    {(api) => ( {(_, index) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item, index}
                    {item.label}
                    {/each}
                    {#snippet render(api)} {#each api().pageSnapPoints as _, index} {/each} {/snippet}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `slideCount` | `number` | Yes | The total number of slides. Useful for SSR to render the initial ating the snap points. | | `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. | | `defaultPage` | `number` | No | The initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. | | `ids` | `Partial<{ root: string item: (index: number) => string itemGroup: string nextTrigger: string prevTrigger: string indicatorGroup: string indicator: (index: number) => string }>` | No | The ids of the elements in the carousel. Useful for composition. | | `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. | | `loop` | `boolean` | No | Whether the carousel should loop around. | | `onAutoplayStatusChange` | `(details: AutoplayStatusDetails) => void` | No | Function called when the autoplay status changes. | | `onDragStatusChange` | `(details: DragStatusDetails) => void` | No | Function called when the drag status changes. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Function called when the page changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `padding` | `string` | No | Defines the extra space added around the scrollable area, enabling nearby items to remain partially in view. | | `page` | `number` | No | The controlled page of the carousel. | | `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. | | `slidesPerPage` | `number` | No | The number of slides to show at a time. | | `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. | | `spacing` | `string` | No | The amount of space between items. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | root | | `[data-orientation]` | The orientation of the carousel | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slides-per-page` | The number of slides visible per page | | `--slide-spacing` | The spacing between slides | | `--slide-item-size` | The calculated size of each slide item | **AutoplayIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `paused` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | The content to render when autoplay is paused. | | `playing` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | The content to render when autoplay is playing. | **AutoplayTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AutoplayTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | autoplay-trigger | | `[data-orientation]` | The orientation of the autoplaytrigger | | `[data-pressed]` | Present when pressed | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | control | | `[data-orientation]` | The orientation of the control | **IndicatorGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IndicatorGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator-group | | `[data-orientation]` | The orientation of the indicatorgroup | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the indicator. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `readOnly` | `boolean` | No | Whether the indicator is read only. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator | | `[data-orientation]` | The orientation of the indicator | | `[data-index]` | The index of the item | | `[data-readonly]` | Present when read-only | | `[data-current]` | Present when current | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item-group | | `[data-orientation]` | The orientation of the item | | `[data-dragging]` | Present when in the dragging state | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the item. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `snapAlign` | `'center' | 'start' | 'end'` | No | The snap alignment of the item. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-inview]` | Present when in viewport | | `[data-orientation]` | The orientation of the item | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | next-trigger | | `[data-orientation]` | The orientation of the nexttrigger | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | prev-trigger | | `[data-orientation]` | The orientation of the prevtrigger | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCarouselReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `slideCount` | `number` | Yes | The total number of slides. Useful for SSR to render the initial ating the snap points. | | `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. | | `defaultPage` | `number` | No | The initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. | | `ids` | `Partial<{ root: string item: (index: number) => string itemGroup: string nextTrigger: string prevTrigger: string indicatorGroup: string indicator: (index: number) => string }>` | No | The ids of the elements in the carousel. Useful for composition. | | `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. | | `loop` | `boolean` | No | Whether the carousel should loop around. | | `onAutoplayStatusChange` | `(details: AutoplayStatusDetails) => void` | No | Function called when the autoplay status changes. | | `onDragStatusChange` | `(details: DragStatusDetails) => void` | No | Function called when the drag status changes. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Function called when the page changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `padding` | `string` | No | Defines the extra space added around the scrollable area, enabling nearby items to remain partially in view. | | `page` | `number` | No | The controlled page of the carousel. | | `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. | | `slidesPerPage` | `number` | No | The number of slides to show at a time. | | `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. | | `spacing` | `string` | No | The amount of space between items. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | root | | `[data-orientation]` | The orientation of the carousel | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slides-per-page` | The number of slides visible per page | | `--slide-spacing` | The spacing between slides | | `--slide-item-size` | The calculated size of each slide item | **AutoplayTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AutoplayTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | autoplay-trigger | | `[data-orientation]` | The orientation of the autoplaytrigger | | `[data-pressed]` | Present when pressed | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | control | | `[data-orientation]` | The orientation of the control | **IndicatorGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IndicatorGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator-group | | `[data-orientation]` | The orientation of the indicatorgroup | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the indicator. | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `readOnly` | `boolean` | No | Whether the indicator is read only. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator | | `[data-orientation]` | The orientation of the indicator | | `[data-index]` | The index of the item | | `[data-readonly]` | Present when read-only | | `[data-current]` | Present when current | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item-group | | `[data-orientation]` | The orientation of the item | | `[data-dragging]` | Present when in the dragging state | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the item. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `snapAlign` | `'start' | 'end' | 'center'` | No | The snap alignment of the item. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-inview]` | Present when in viewport | | `[data-orientation]` | The orientation of the item | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | next-trigger | | `[data-orientation]` | The orientation of the nexttrigger | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | prev-trigger | | `[data-orientation]` | The orientation of the prevtrigger | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCarouselReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `slideCount` | `number` | Yes | The total number of slides. Useful for SSR to render the initial ating the snap points. | | `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. | | `defaultPage` | `number` | No | The initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item(index: number): string itemGroup: string nextTrigger: string prevTrigger: string indicatorGroup: string indicator(index: number): string }>` | No | The ids of the elements in the carousel. Useful for composition. | | `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. | | `loop` | `boolean` | No | Whether the carousel should loop around. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `padding` | `string` | No | Defines the extra space added around the scrollable area, enabling nearby items to remain partially in view. | | `page` | `number` | No | The controlled page of the carousel. | | `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. | | `slidesPerPage` | `number` | No | The number of slides to show at a time. | | `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. | | `spacing` | `string` | No | The amount of space between items. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | root | | `[data-orientation]` | The orientation of the carousel | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slides-per-page` | The number of slides visible per page | | `--slide-spacing` | The spacing between slides | | `--slide-item-size` | The calculated size of each slide item | **AutoplayTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AutoplayTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | autoplay-trigger | | `[data-orientation]` | The orientation of the autoplaytrigger | | `[data-pressed]` | Present when pressed | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | control | | `[data-orientation]` | The orientation of the control | **IndicatorGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IndicatorGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator-group | | `[data-orientation]` | The orientation of the indicatorgroup | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the indicator. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `readOnly` | `boolean` | No | Whether the indicator is read only. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator | | `[data-orientation]` | The orientation of the indicator | | `[data-index]` | The index of the item | | `[data-readonly]` | Present when read-only | | `[data-current]` | Present when current | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item-group | | `[data-orientation]` | The orientation of the item | | `[data-dragging]` | Present when in the dragging state | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the item. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `snapAlign` | `'start' | 'end' | 'center'` | No | The snap alignment of the item. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-inview]` | Present when in viewport | | `[data-orientation]` | The orientation of the item | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | next-trigger | | `[data-orientation]` | The orientation of the nexttrigger | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | prev-trigger | | `[data-orientation]` | The orientation of the prevtrigger | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `CarouselApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `slideCount` | `number` | Yes | The total number of slides. Useful for SSR to render the initial ating the snap points. | | `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. | | `defaultPage` | `number` | No | The initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item: (index: number) => string itemGroup: string nextTrigger: string prevTrigger: string indicatorGroup: string indicator: (index: number) => string }>` | No | The ids of the elements in the carousel. Useful for composition. | | `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. | | `loop` | `boolean` | No | Whether the carousel should loop around. | | `onAutoplayStatusChange` | `(details: AutoplayStatusDetails) => void` | No | Function called when the autoplay status changes. | | `onDragStatusChange` | `(details: DragStatusDetails) => void` | No | Function called when the drag status changes. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Function called when the page changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `padding` | `string` | No | Defines the extra space added around the scrollable area, enabling nearby items to remain partially in view. | | `page` | `number` | No | The controlled page of the carousel. | | `ref` | `Element` | No | | | `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. | | `slidesPerPage` | `number` | No | The number of slides to show at a time. | | `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. | | `spacing` | `string` | No | The amount of space between items. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | root | | `[data-orientation]` | The orientation of the carousel | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slides-per-page` | The number of slides visible per page | | `--slide-spacing` | The spacing between slides | | `--slide-item-size` | The calculated size of each slide item | **AutoplayTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **AutoplayTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | autoplay-trigger | | `[data-orientation]` | The orientation of the autoplaytrigger | | `[data-pressed]` | Present when pressed | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseCarouselContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | control | | `[data-orientation]` | The orientation of the control | **IndicatorGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **IndicatorGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator-group | | `[data-orientation]` | The orientation of the indicatorgroup | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the indicator. | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `readOnly` | `boolean` | No | Whether the indicator is read only. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator | | `[data-orientation]` | The orientation of the indicator | | `[data-index]` | The index of the item | | `[data-readonly]` | Present when read-only | | `[data-current]` | Present when current | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item-group | | `[data-orientation]` | The orientation of the item | | `[data-dragging]` | Present when in the dragging state | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the item. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `snapAlign` | `'start' | 'end' | 'center'` | No | The snap alignment of the item. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-inview]` | Present when in viewport | | `[data-orientation]` | The orientation of the item | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | next-trigger | | `[data-orientation]` | The orientation of the nexttrigger | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | prev-trigger | | `[data-orientation]` | The orientation of the prevtrigger | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCarouselReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `page` | `number` | The current index of the carousel | | `pageSnapPoints` | `number[]` | The current snap points of the carousel | | `isPlaying` | `boolean` | Whether the carousel is auto playing | | `isDragging` | `boolean` | Whether the carousel is being dragged. This only works when `draggable` is true. | | `canScrollNext` | `boolean` | Whether the carousel is can scroll to the next view | | `canScrollPrev` | `boolean` | Whether the carousel is can scroll to the previous view | | `scrollToIndex` | `(index: number, instant?: boolean) => void` | Function to scroll to a specific item index | | `scrollTo` | `(page: number, instant?: boolean) => void` | Function to scroll to a specific page | | `scrollNext` | `(instant?: boolean) => void` | Function to scroll to the next page | | `scrollPrev` | `(instant?: boolean) => void` | Function to scroll to the previous page | | `getProgress` | `() => number` | Returns the current scroll progress as a percentage | | `getProgressText` | `() => string` | Returns the progress text | | `play` | `VoidFunction` | Function to start/resume autoplay | | `pause` | `VoidFunction` | Function to pause autoplay | | `isInView` | `(index: number) => boolean` | Whether the item is in view | | `refresh` | `VoidFunction` | Function to re-compute the snap points and clamp the page | ## Accessibility Complies with the [Carousel WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/carousel/). --- # Carousel (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Basic = () => { return ( {images.map((image, index) => ( {image.alt} ))} {images.map((_, index) => ( ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Basic = () => { return ( {(image, index) => ( {image().alt} )} {(_, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each images as image, index} {image.alt} {/each} {#each images as _, index} {/each} ``` ### 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: **Example: controlled** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Controlled = () => { const [page, setPage] = useState(0) return ( setPage(e.page)}> {images.map((image, index) => ( {image.alt} ))} {images.map((_, index) => ( ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Controlled = () => { const [page, setPage] = createSignal(0) return ( setPage(details.page)} > {(image, index) => ( {image().alt} )} {(_, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Current page: {page}
                    {#each images as image, index} {image.alt} {/each} {#each images as _, index} {/each}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Carousel, useCarousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const RootProvider = () => { const carousel = useCarousel({ slideCount: images.length }) return (
                    Page: {carousel.page} {images.map((image, index) => ( {image.alt} ))} {images.map((_, index) => ( ))}
                    ) } ``` #### Solid ```tsx import { Carousel, useCarousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const RootProvider = () => { const carousel = useCarousel({ slideCount: images.length }) return (
                    Page: {carousel().page} {(image, index) => ( {image().alt} )} {(_, index) => }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Page: {carousel().page} {#each images as image, index} {image.alt} {/each} {#each images as _, index} {/each}
                    ``` ### Autoplay Pass the `autoplay` and `loop` props to `Carousel.Root` to make the carousel play automatically. **Example: autoplay** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ChevronLeftIcon, ChevronRightIcon, PauseIcon, PlayIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Autoplay = () => { return ( {images.map((image, index) => ( {image.alt} ))} }> ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ChevronLeftIcon, ChevronRightIcon, PauseIcon, PlayIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Autoplay = () => { return ( {(image, index) => ( {image().alt} )} }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each images as image, index} {image.alt} {/each} {#snippet fallback()}{/snippet} ``` ### 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. **Example: pause-on-hover** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const PauseOnHover = () => { return ( {({ isPlaying }) => ( Autoplay is: {isPlaying ? 'playing' : 'paused'} )} {(api) => ( api.pause()} onPointerLeave={() => api.play()} > {images.map((image, index) => ( {image.alt} ))} )} {images.map((_, index) => ( ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const PauseOnHover = () => { return ( {(carousel) => ( Autoplay is: {carousel().isPlaying ? 'playing' : 'paused'} )} {(api) => ( api().pause()} onPointerLeave={() => api().play()} > {(image, index) => ( {image().alt} )} )} {(_, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(api)} Autoplay is: {api().isPlaying ? 'playing' : 'paused'} {/snippet} {#snippet render(api)} api().pause()} onpointerleave={() => api().play()} > {#each images as image, index} {image.alt} {/each} {/snippet} {#each images as _, index} {/each} ``` ### Thumbnail Indicators Replace default indicator dots with image thumbnails. Render each thumbnail inside `Carousel.Indicator` to create a visual preview of each slide: **Example: thumbnail-indicator** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const ThumbnailIndicator = () => { return ( {images.map((image, index) => ( {image.alt} ))} {images.map((image, index) => ( {image.alt} ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const ThumbnailIndicator = () => { return ( {(image, index) => ( {image().alt} )} {(image, index) => ( {image().alt} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each images as image, index} {image.alt} {/each} {#each images as image, index} {image.alt} {/each} ``` ### 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. **Example: vertical** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowDownIcon, ArrowUpIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Vertical = () => { return ( {images.map((image, index) => ( {image.alt} ))} {images.map((_, index) => ( ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowDownIcon, ArrowUpIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Vertical = () => { return ( {(image, index) => ( {image().alt} )} {(_, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each images as image, index} {image.alt} {/each} {#each images as _, index} {/each} ``` ### 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. **Example: dynamic-slides** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon, PlusIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/carousel.module.css' export const DynamicSlides = () => { const [slides, setSlides] = useState([0, 1, 2, 3, 4]) const [page, setPage] = useState(0) const addSlide = () => { setSlides((prevSlides) => { const max = Math.max(...prevSlides) return [...prevSlides, max + 1] }) } return (
                    setPage(details.page)} > {slides.map((slide, index) => (
                    Slide {slide + 1}
                    ))}
                    {slides.map((_, index) => ( ))}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon, PlusIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/carousel.module.css' export const DynamicSlides = () => { const [slides, setSlides] = createSignal([0, 1, 2, 3, 4]) const [page, setPage] = createSignal(0) const addSlide = () => { setSlides((prevSlides) => { const max = Math.max(...prevSlides) return [...prevSlides, max + 1] }) } return (
                    setPage(details.page)} > {(slide, index) => (
                    Slide {slide() + 1}
                    )}
                    {(_, index) => }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each slides as slide, index}
                    Slide {slide + 1}
                    {/each}
                    {#each slides as _, index} {/each}
                    ``` ### 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. **Example: scroll-to** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/carousel.module.css' export const ScrollTo = () => { return ( {(api) => ( )} {Array.from({ length: 5 }, (_, index) => (
                    Slide {index + 1}
                    ))}
                    {Array.from({ length: 5 }, (_, index) => ( ))}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/carousel.module.css' const slides = Array.from({ length: 6 }) export const ScrollTo = () => { return ( {(api) => ( )} {(_, index) => (
                    Slide {index + 1}
                    )}
                    {(_, index) => }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(api)} {/snippet} {#each slides as _, index}
                    Slide {index + 1}
                    {/each}
                    {#each slides as _, index} {/each}
                    ``` ### 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. **Example: slides-per-page** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' export const SlidesPerPage = () => { const slides = Array.from({ length: 6 }) return ( {slides.map((_, index) => (
                    Slide {index + 1}
                    ))}
                    {(api) => ( {api.pageSnapPoints.map((_, index) => ( ))} )}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const slides = Array.from({ length: 6 }) export const SlidesPerPage = () => { return ( {(_, index) => (
                    Slide {index + 1}
                    )}
                    {(api) => ( {(_, index) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each slides as _, index}
                    Slide {index + 1}
                    {/each}
                    {#snippet render(api)} {#each api().pageSnapPoints as _, index} {/each} {/snippet}
                    ``` ### 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. **Example: spacing** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const slides = Array.from({ length: 6 }) export const Spacing = () => { return ( spacing='48px' {slides.map((_, index) => (
                    {index + 1}
                    ))}
                    {(api) => ( {api.pageSnapPoints.map((_, index) => ( ))} )}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const slides = Array.from({ length: 6 }) export const Spacing = () => { return ( spacing='48px' {(_, index) => (
                    {index + 1}
                    )}
                    {(api) => ( {(_, index) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte spacing='48px' {#each slides as _, index}
                    {index + 1}
                    {/each}
                    {#snippet render(api)} {#each api().pageSnapPoints as _, index} {/each} {/snippet}
                    ``` ### 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. **Example: variable-size** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const items = [ { id: '1', width: '120px', label: 'Small' }, { id: '2', width: '200px', label: 'Medium Size' }, { id: '3', width: '80px', label: 'XS' }, { id: '4', width: '250px', label: 'Large Content Here' }, { id: '5', width: '150px', label: 'Regular' }, ] export const VariableSize = () => { return ( {items.map((item, index) => (
                    {item.label}
                    ))}
                    {(api) => ( {api.pageSnapPoints.map((_, index) => ( ))} )}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/carousel.module.css' const items = [ { id: '1', width: '120px', label: 'Small' }, { id: '2', width: '200px', label: 'Medium Size' }, { id: '3', width: '80px', label: 'XS' }, { id: '4', width: '250px', label: 'Large Content Here' }, { id: '5', width: '150px', label: 'Regular' }, ] export const VariableSize = () => { return ( {(item, index) => (
                    {item.label}
                    )}
                    {(api) => ( {(_, index) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item, index}
                    {item.label}
                    {/each}
                    {#snippet render(api)} {#each api().pageSnapPoints as _, index} {/each} {/snippet}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `slideCount` | `number` | Yes | The total number of slides. Useful for SSR to render the initial ating the snap points. | | `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. | | `defaultPage` | `number` | No | The initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. | | `ids` | `Partial<{ root: string item: (index: number) => string itemGroup: string nextTrigger: string prevTrigger: string indicatorGroup: string indicator: (index: number) => string }>` | No | The ids of the elements in the carousel. Useful for composition. | | `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. | | `loop` | `boolean` | No | Whether the carousel should loop around. | | `onAutoplayStatusChange` | `(details: AutoplayStatusDetails) => void` | No | Function called when the autoplay status changes. | | `onDragStatusChange` | `(details: DragStatusDetails) => void` | No | Function called when the drag status changes. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Function called when the page changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `padding` | `string` | No | Defines the extra space added around the scrollable area, enabling nearby items to remain partially in view. | | `page` | `number` | No | The controlled page of the carousel. | | `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. | | `slidesPerPage` | `number` | No | The number of slides to show at a time. | | `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. | | `spacing` | `string` | No | The amount of space between items. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | root | | `[data-orientation]` | The orientation of the carousel | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slides-per-page` | The number of slides visible per page | | `--slide-spacing` | The spacing between slides | | `--slide-item-size` | The calculated size of each slide item | **AutoplayIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `paused` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | The content to render when autoplay is paused. | | `playing` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | The content to render when autoplay is playing. | **AutoplayTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AutoplayTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | autoplay-trigger | | `[data-orientation]` | The orientation of the autoplaytrigger | | `[data-pressed]` | Present when pressed | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | control | | `[data-orientation]` | The orientation of the control | **IndicatorGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IndicatorGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator-group | | `[data-orientation]` | The orientation of the indicatorgroup | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the indicator. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `readOnly` | `boolean` | No | Whether the indicator is read only. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator | | `[data-orientation]` | The orientation of the indicator | | `[data-index]` | The index of the item | | `[data-readonly]` | Present when read-only | | `[data-current]` | Present when current | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item-group | | `[data-orientation]` | The orientation of the item | | `[data-dragging]` | Present when in the dragging state | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the item. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `snapAlign` | `'center' | 'start' | 'end'` | No | The snap alignment of the item. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-inview]` | Present when in viewport | | `[data-orientation]` | The orientation of the item | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | next-trigger | | `[data-orientation]` | The orientation of the nexttrigger | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | prev-trigger | | `[data-orientation]` | The orientation of the prevtrigger | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCarouselReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `slideCount` | `number` | Yes | The total number of slides. Useful for SSR to render the initial ating the snap points. | | `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. | | `defaultPage` | `number` | No | The initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. | | `ids` | `Partial<{ root: string item: (index: number) => string itemGroup: string nextTrigger: string prevTrigger: string indicatorGroup: string indicator: (index: number) => string }>` | No | The ids of the elements in the carousel. Useful for composition. | | `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. | | `loop` | `boolean` | No | Whether the carousel should loop around. | | `onAutoplayStatusChange` | `(details: AutoplayStatusDetails) => void` | No | Function called when the autoplay status changes. | | `onDragStatusChange` | `(details: DragStatusDetails) => void` | No | Function called when the drag status changes. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Function called when the page changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `padding` | `string` | No | Defines the extra space added around the scrollable area, enabling nearby items to remain partially in view. | | `page` | `number` | No | The controlled page of the carousel. | | `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. | | `slidesPerPage` | `number` | No | The number of slides to show at a time. | | `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. | | `spacing` | `string` | No | The amount of space between items. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | root | | `[data-orientation]` | The orientation of the carousel | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slides-per-page` | The number of slides visible per page | | `--slide-spacing` | The spacing between slides | | `--slide-item-size` | The calculated size of each slide item | **AutoplayTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AutoplayTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | autoplay-trigger | | `[data-orientation]` | The orientation of the autoplaytrigger | | `[data-pressed]` | Present when pressed | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | control | | `[data-orientation]` | The orientation of the control | **IndicatorGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IndicatorGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator-group | | `[data-orientation]` | The orientation of the indicatorgroup | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the indicator. | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `readOnly` | `boolean` | No | Whether the indicator is read only. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator | | `[data-orientation]` | The orientation of the indicator | | `[data-index]` | The index of the item | | `[data-readonly]` | Present when read-only | | `[data-current]` | Present when current | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item-group | | `[data-orientation]` | The orientation of the item | | `[data-dragging]` | Present when in the dragging state | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the item. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `snapAlign` | `'start' | 'end' | 'center'` | No | The snap alignment of the item. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-inview]` | Present when in viewport | | `[data-orientation]` | The orientation of the item | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | next-trigger | | `[data-orientation]` | The orientation of the nexttrigger | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | prev-trigger | | `[data-orientation]` | The orientation of the prevtrigger | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCarouselReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `slideCount` | `number` | Yes | The total number of slides. Useful for SSR to render the initial ating the snap points. | | `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. | | `defaultPage` | `number` | No | The initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item(index: number): string itemGroup: string nextTrigger: string prevTrigger: string indicatorGroup: string indicator(index: number): string }>` | No | The ids of the elements in the carousel. Useful for composition. | | `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. | | `loop` | `boolean` | No | Whether the carousel should loop around. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `padding` | `string` | No | Defines the extra space added around the scrollable area, enabling nearby items to remain partially in view. | | `page` | `number` | No | The controlled page of the carousel. | | `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. | | `slidesPerPage` | `number` | No | The number of slides to show at a time. | | `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. | | `spacing` | `string` | No | The amount of space between items. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | root | | `[data-orientation]` | The orientation of the carousel | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slides-per-page` | The number of slides visible per page | | `--slide-spacing` | The spacing between slides | | `--slide-item-size` | The calculated size of each slide item | **AutoplayTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AutoplayTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | autoplay-trigger | | `[data-orientation]` | The orientation of the autoplaytrigger | | `[data-pressed]` | Present when pressed | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | control | | `[data-orientation]` | The orientation of the control | **IndicatorGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IndicatorGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator-group | | `[data-orientation]` | The orientation of the indicatorgroup | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the indicator. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `readOnly` | `boolean` | No | Whether the indicator is read only. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator | | `[data-orientation]` | The orientation of the indicator | | `[data-index]` | The index of the item | | `[data-readonly]` | Present when read-only | | `[data-current]` | Present when current | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item-group | | `[data-orientation]` | The orientation of the item | | `[data-dragging]` | Present when in the dragging state | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the item. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `snapAlign` | `'start' | 'end' | 'center'` | No | The snap alignment of the item. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-inview]` | Present when in viewport | | `[data-orientation]` | The orientation of the item | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | next-trigger | | `[data-orientation]` | The orientation of the nexttrigger | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | prev-trigger | | `[data-orientation]` | The orientation of the prevtrigger | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `CarouselApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `slideCount` | `number` | Yes | The total number of slides. Useful for SSR to render the initial ating the snap points. | | `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. | | `defaultPage` | `number` | No | The initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item: (index: number) => string itemGroup: string nextTrigger: string prevTrigger: string indicatorGroup: string indicator: (index: number) => string }>` | No | The ids of the elements in the carousel. Useful for composition. | | `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. | | `loop` | `boolean` | No | Whether the carousel should loop around. | | `onAutoplayStatusChange` | `(details: AutoplayStatusDetails) => void` | No | Function called when the autoplay status changes. | | `onDragStatusChange` | `(details: DragStatusDetails) => void` | No | Function called when the drag status changes. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Function called when the page changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `padding` | `string` | No | Defines the extra space added around the scrollable area, enabling nearby items to remain partially in view. | | `page` | `number` | No | The controlled page of the carousel. | | `ref` | `Element` | No | | | `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. | | `slidesPerPage` | `number` | No | The number of slides to show at a time. | | `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. | | `spacing` | `string` | No | The amount of space between items. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | root | | `[data-orientation]` | The orientation of the carousel | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slides-per-page` | The number of slides visible per page | | `--slide-spacing` | The spacing between slides | | `--slide-item-size` | The calculated size of each slide item | **AutoplayTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **AutoplayTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | autoplay-trigger | | `[data-orientation]` | The orientation of the autoplaytrigger | | `[data-pressed]` | Present when pressed | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseCarouselContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | control | | `[data-orientation]` | The orientation of the control | **IndicatorGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **IndicatorGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator-group | | `[data-orientation]` | The orientation of the indicatorgroup | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the indicator. | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `readOnly` | `boolean` | No | Whether the indicator is read only. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator | | `[data-orientation]` | The orientation of the indicator | | `[data-index]` | The index of the item | | `[data-readonly]` | Present when read-only | | `[data-current]` | Present when current | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item-group | | `[data-orientation]` | The orientation of the item | | `[data-dragging]` | Present when in the dragging state | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the item. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `snapAlign` | `'start' | 'end' | 'center'` | No | The snap alignment of the item. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-inview]` | Present when in viewport | | `[data-orientation]` | The orientation of the item | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | next-trigger | | `[data-orientation]` | The orientation of the nexttrigger | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | prev-trigger | | `[data-orientation]` | The orientation of the prevtrigger | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCarouselReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `page` | `number` | The current index of the carousel | | `pageSnapPoints` | `number[]` | The current snap points of the carousel | | `isPlaying` | `boolean` | Whether the carousel is auto playing | | `isDragging` | `boolean` | Whether the carousel is being dragged. This only works when `draggable` is true. | | `canScrollNext` | `boolean` | Whether the carousel is can scroll to the next view | | `canScrollPrev` | `boolean` | Whether the carousel is can scroll to the previous view | | `scrollToIndex` | `(index: number, instant?: boolean) => void` | Function to scroll to a specific item index | | `scrollTo` | `(page: number, instant?: boolean) => void` | Function to scroll to a specific page | | `scrollNext` | `(instant?: boolean) => void` | Function to scroll to the next page | | `scrollPrev` | `(instant?: boolean) => void` | Function to scroll to the previous page | | `getProgress` | `() => number` | Returns the current scroll progress as a percentage | | `getProgressText` | `() => string` | Returns the progress text | | `play` | `VoidFunction` | Function to start/resume autoplay | | `pause` | `VoidFunction` | Function to pause autoplay | | `isInView` | `(index: number) => boolean` | Whether the item is in view | | `refresh` | `VoidFunction` | Function to re-compute the snap points and clamp the page | ## Accessibility Complies with the [Carousel WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/carousel/). --- # Carousel (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Basic = () => { return ( {images.map((image, index) => ( {image.alt} ))} {images.map((_, index) => ( ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Basic = () => { return ( {(image, index) => ( {image().alt} )} {(_, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each images as image, index} {image.alt} {/each} {#each images as _, index} {/each} ``` ### 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: **Example: controlled** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Controlled = () => { const [page, setPage] = useState(0) return ( setPage(e.page)}> {images.map((image, index) => ( {image.alt} ))} {images.map((_, index) => ( ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Controlled = () => { const [page, setPage] = createSignal(0) return ( setPage(details.page)} > {(image, index) => ( {image().alt} )} {(_, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Current page: {page}
                    {#each images as image, index} {image.alt} {/each} {#each images as _, index} {/each}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Carousel, useCarousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const RootProvider = () => { const carousel = useCarousel({ slideCount: images.length }) return (
                    Page: {carousel.page} {images.map((image, index) => ( {image.alt} ))} {images.map((_, index) => ( ))}
                    ) } ``` #### Solid ```tsx import { Carousel, useCarousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const RootProvider = () => { const carousel = useCarousel({ slideCount: images.length }) return (
                    Page: {carousel().page} {(image, index) => ( {image().alt} )} {(_, index) => }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Page: {carousel().page} {#each images as image, index} {image.alt} {/each} {#each images as _, index} {/each}
                    ``` ### Autoplay Pass the `autoplay` and `loop` props to `Carousel.Root` to make the carousel play automatically. **Example: autoplay** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ChevronLeftIcon, ChevronRightIcon, PauseIcon, PlayIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Autoplay = () => { return ( {images.map((image, index) => ( {image.alt} ))} }> ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ChevronLeftIcon, ChevronRightIcon, PauseIcon, PlayIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Autoplay = () => { return ( {(image, index) => ( {image().alt} )} }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each images as image, index} {image.alt} {/each} {#snippet fallback()}{/snippet} ``` ### 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. **Example: pause-on-hover** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const PauseOnHover = () => { return ( {({ isPlaying }) => ( Autoplay is: {isPlaying ? 'playing' : 'paused'} )} {(api) => ( api.pause()} onPointerLeave={() => api.play()} > {images.map((image, index) => ( {image.alt} ))} )} {images.map((_, index) => ( ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const PauseOnHover = () => { return ( {(carousel) => ( Autoplay is: {carousel().isPlaying ? 'playing' : 'paused'} )} {(api) => ( api().pause()} onPointerLeave={() => api().play()} > {(image, index) => ( {image().alt} )} )} {(_, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(api)} Autoplay is: {api().isPlaying ? 'playing' : 'paused'} {/snippet} {#snippet render(api)} api().pause()} onpointerleave={() => api().play()} > {#each images as image, index} {image.alt} {/each} {/snippet} {#each images as _, index} {/each} ``` ### Thumbnail Indicators Replace default indicator dots with image thumbnails. Render each thumbnail inside `Carousel.Indicator` to create a visual preview of each slide: **Example: thumbnail-indicator** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const ThumbnailIndicator = () => { return ( {images.map((image, index) => ( {image.alt} ))} {images.map((image, index) => ( {image.alt} ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const ThumbnailIndicator = () => { return ( {(image, index) => ( {image().alt} )} {(image, index) => ( {image().alt} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each images as image, index} {image.alt} {/each} {#each images as image, index} {image.alt} {/each} ``` ### 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. **Example: vertical** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowDownIcon, ArrowUpIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Vertical = () => { return ( {images.map((image, index) => ( {image.alt} ))} {images.map((_, index) => ( ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowDownIcon, ArrowUpIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Vertical = () => { return ( {(image, index) => ( {image().alt} )} {(_, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each images as image, index} {image.alt} {/each} {#each images as _, index} {/each} ``` ### 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. **Example: dynamic-slides** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon, PlusIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/carousel.module.css' export const DynamicSlides = () => { const [slides, setSlides] = useState([0, 1, 2, 3, 4]) const [page, setPage] = useState(0) const addSlide = () => { setSlides((prevSlides) => { const max = Math.max(...prevSlides) return [...prevSlides, max + 1] }) } return (
                    setPage(details.page)} > {slides.map((slide, index) => (
                    Slide {slide + 1}
                    ))}
                    {slides.map((_, index) => ( ))}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon, PlusIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/carousel.module.css' export const DynamicSlides = () => { const [slides, setSlides] = createSignal([0, 1, 2, 3, 4]) const [page, setPage] = createSignal(0) const addSlide = () => { setSlides((prevSlides) => { const max = Math.max(...prevSlides) return [...prevSlides, max + 1] }) } return (
                    setPage(details.page)} > {(slide, index) => (
                    Slide {slide() + 1}
                    )}
                    {(_, index) => }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each slides as slide, index}
                    Slide {slide + 1}
                    {/each}
                    {#each slides as _, index} {/each}
                    ``` ### 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. **Example: scroll-to** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/carousel.module.css' export const ScrollTo = () => { return ( {(api) => ( )} {Array.from({ length: 5 }, (_, index) => (
                    Slide {index + 1}
                    ))}
                    {Array.from({ length: 5 }, (_, index) => ( ))}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/carousel.module.css' const slides = Array.from({ length: 6 }) export const ScrollTo = () => { return ( {(api) => ( )} {(_, index) => (
                    Slide {index + 1}
                    )}
                    {(_, index) => }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(api)} {/snippet} {#each slides as _, index}
                    Slide {index + 1}
                    {/each}
                    {#each slides as _, index} {/each}
                    ``` ### 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. **Example: slides-per-page** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' export const SlidesPerPage = () => { const slides = Array.from({ length: 6 }) return ( {slides.map((_, index) => (
                    Slide {index + 1}
                    ))}
                    {(api) => ( {api.pageSnapPoints.map((_, index) => ( ))} )}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const slides = Array.from({ length: 6 }) export const SlidesPerPage = () => { return ( {(_, index) => (
                    Slide {index + 1}
                    )}
                    {(api) => ( {(_, index) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each slides as _, index}
                    Slide {index + 1}
                    {/each}
                    {#snippet render(api)} {#each api().pageSnapPoints as _, index} {/each} {/snippet}
                    ``` ### 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. **Example: spacing** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const slides = Array.from({ length: 6 }) export const Spacing = () => { return ( spacing='48px' {slides.map((_, index) => (
                    {index + 1}
                    ))}
                    {(api) => ( {api.pageSnapPoints.map((_, index) => ( ))} )}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const slides = Array.from({ length: 6 }) export const Spacing = () => { return ( spacing='48px' {(_, index) => (
                    {index + 1}
                    )}
                    {(api) => ( {(_, index) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte spacing='48px' {#each slides as _, index}
                    {index + 1}
                    {/each}
                    {#snippet render(api)} {#each api().pageSnapPoints as _, index} {/each} {/snippet}
                    ``` ### 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. **Example: variable-size** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const items = [ { id: '1', width: '120px', label: 'Small' }, { id: '2', width: '200px', label: 'Medium Size' }, { id: '3', width: '80px', label: 'XS' }, { id: '4', width: '250px', label: 'Large Content Here' }, { id: '5', width: '150px', label: 'Regular' }, ] export const VariableSize = () => { return ( {items.map((item, index) => (
                    {item.label}
                    ))}
                    {(api) => ( {api.pageSnapPoints.map((_, index) => ( ))} )}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/carousel.module.css' const items = [ { id: '1', width: '120px', label: 'Small' }, { id: '2', width: '200px', label: 'Medium Size' }, { id: '3', width: '80px', label: 'XS' }, { id: '4', width: '250px', label: 'Large Content Here' }, { id: '5', width: '150px', label: 'Regular' }, ] export const VariableSize = () => { return ( {(item, index) => (
                    {item.label}
                    )}
                    {(api) => ( {(_, index) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item, index}
                    {item.label}
                    {/each}
                    {#snippet render(api)} {#each api().pageSnapPoints as _, index} {/each} {/snippet}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `slideCount` | `number` | Yes | The total number of slides. Useful for SSR to render the initial ating the snap points. | | `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. | | `defaultPage` | `number` | No | The initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. | | `ids` | `Partial<{ root: string item: (index: number) => string itemGroup: string nextTrigger: string prevTrigger: string indicatorGroup: string indicator: (index: number) => string }>` | No | The ids of the elements in the carousel. Useful for composition. | | `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. | | `loop` | `boolean` | No | Whether the carousel should loop around. | | `onAutoplayStatusChange` | `(details: AutoplayStatusDetails) => void` | No | Function called when the autoplay status changes. | | `onDragStatusChange` | `(details: DragStatusDetails) => void` | No | Function called when the drag status changes. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Function called when the page changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `padding` | `string` | No | Defines the extra space added around the scrollable area, enabling nearby items to remain partially in view. | | `page` | `number` | No | The controlled page of the carousel. | | `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. | | `slidesPerPage` | `number` | No | The number of slides to show at a time. | | `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. | | `spacing` | `string` | No | The amount of space between items. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | root | | `[data-orientation]` | The orientation of the carousel | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slides-per-page` | The number of slides visible per page | | `--slide-spacing` | The spacing between slides | | `--slide-item-size` | The calculated size of each slide item | **AutoplayIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `paused` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | The content to render when autoplay is paused. | | `playing` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | The content to render when autoplay is playing. | **AutoplayTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AutoplayTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | autoplay-trigger | | `[data-orientation]` | The orientation of the autoplaytrigger | | `[data-pressed]` | Present when pressed | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | control | | `[data-orientation]` | The orientation of the control | **IndicatorGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IndicatorGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator-group | | `[data-orientation]` | The orientation of the indicatorgroup | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the indicator. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `readOnly` | `boolean` | No | Whether the indicator is read only. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator | | `[data-orientation]` | The orientation of the indicator | | `[data-index]` | The index of the item | | `[data-readonly]` | Present when read-only | | `[data-current]` | Present when current | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item-group | | `[data-orientation]` | The orientation of the item | | `[data-dragging]` | Present when in the dragging state | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the item. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `snapAlign` | `'center' | 'start' | 'end'` | No | The snap alignment of the item. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-inview]` | Present when in viewport | | `[data-orientation]` | The orientation of the item | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | next-trigger | | `[data-orientation]` | The orientation of the nexttrigger | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | prev-trigger | | `[data-orientation]` | The orientation of the prevtrigger | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCarouselReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `slideCount` | `number` | Yes | The total number of slides. Useful for SSR to render the initial ating the snap points. | | `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. | | `defaultPage` | `number` | No | The initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. | | `ids` | `Partial<{ root: string item: (index: number) => string itemGroup: string nextTrigger: string prevTrigger: string indicatorGroup: string indicator: (index: number) => string }>` | No | The ids of the elements in the carousel. Useful for composition. | | `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. | | `loop` | `boolean` | No | Whether the carousel should loop around. | | `onAutoplayStatusChange` | `(details: AutoplayStatusDetails) => void` | No | Function called when the autoplay status changes. | | `onDragStatusChange` | `(details: DragStatusDetails) => void` | No | Function called when the drag status changes. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Function called when the page changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `padding` | `string` | No | Defines the extra space added around the scrollable area, enabling nearby items to remain partially in view. | | `page` | `number` | No | The controlled page of the carousel. | | `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. | | `slidesPerPage` | `number` | No | The number of slides to show at a time. | | `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. | | `spacing` | `string` | No | The amount of space between items. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | root | | `[data-orientation]` | The orientation of the carousel | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slides-per-page` | The number of slides visible per page | | `--slide-spacing` | The spacing between slides | | `--slide-item-size` | The calculated size of each slide item | **AutoplayTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AutoplayTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | autoplay-trigger | | `[data-orientation]` | The orientation of the autoplaytrigger | | `[data-pressed]` | Present when pressed | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | control | | `[data-orientation]` | The orientation of the control | **IndicatorGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IndicatorGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator-group | | `[data-orientation]` | The orientation of the indicatorgroup | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the indicator. | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `readOnly` | `boolean` | No | Whether the indicator is read only. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator | | `[data-orientation]` | The orientation of the indicator | | `[data-index]` | The index of the item | | `[data-readonly]` | Present when read-only | | `[data-current]` | Present when current | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item-group | | `[data-orientation]` | The orientation of the item | | `[data-dragging]` | Present when in the dragging state | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the item. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `snapAlign` | `'start' | 'end' | 'center'` | No | The snap alignment of the item. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-inview]` | Present when in viewport | | `[data-orientation]` | The orientation of the item | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | next-trigger | | `[data-orientation]` | The orientation of the nexttrigger | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | prev-trigger | | `[data-orientation]` | The orientation of the prevtrigger | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCarouselReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `slideCount` | `number` | Yes | The total number of slides. Useful for SSR to render the initial ating the snap points. | | `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. | | `defaultPage` | `number` | No | The initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item(index: number): string itemGroup: string nextTrigger: string prevTrigger: string indicatorGroup: string indicator(index: number): string }>` | No | The ids of the elements in the carousel. Useful for composition. | | `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. | | `loop` | `boolean` | No | Whether the carousel should loop around. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `padding` | `string` | No | Defines the extra space added around the scrollable area, enabling nearby items to remain partially in view. | | `page` | `number` | No | The controlled page of the carousel. | | `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. | | `slidesPerPage` | `number` | No | The number of slides to show at a time. | | `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. | | `spacing` | `string` | No | The amount of space between items. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | root | | `[data-orientation]` | The orientation of the carousel | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slides-per-page` | The number of slides visible per page | | `--slide-spacing` | The spacing between slides | | `--slide-item-size` | The calculated size of each slide item | **AutoplayTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AutoplayTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | autoplay-trigger | | `[data-orientation]` | The orientation of the autoplaytrigger | | `[data-pressed]` | Present when pressed | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | control | | `[data-orientation]` | The orientation of the control | **IndicatorGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IndicatorGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator-group | | `[data-orientation]` | The orientation of the indicatorgroup | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the indicator. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `readOnly` | `boolean` | No | Whether the indicator is read only. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator | | `[data-orientation]` | The orientation of the indicator | | `[data-index]` | The index of the item | | `[data-readonly]` | Present when read-only | | `[data-current]` | Present when current | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item-group | | `[data-orientation]` | The orientation of the item | | `[data-dragging]` | Present when in the dragging state | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the item. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `snapAlign` | `'start' | 'end' | 'center'` | No | The snap alignment of the item. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-inview]` | Present when in viewport | | `[data-orientation]` | The orientation of the item | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | next-trigger | | `[data-orientation]` | The orientation of the nexttrigger | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | prev-trigger | | `[data-orientation]` | The orientation of the prevtrigger | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `CarouselApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `slideCount` | `number` | Yes | The total number of slides. Useful for SSR to render the initial ating the snap points. | | `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. | | `defaultPage` | `number` | No | The initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item: (index: number) => string itemGroup: string nextTrigger: string prevTrigger: string indicatorGroup: string indicator: (index: number) => string }>` | No | The ids of the elements in the carousel. Useful for composition. | | `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. | | `loop` | `boolean` | No | Whether the carousel should loop around. | | `onAutoplayStatusChange` | `(details: AutoplayStatusDetails) => void` | No | Function called when the autoplay status changes. | | `onDragStatusChange` | `(details: DragStatusDetails) => void` | No | Function called when the drag status changes. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Function called when the page changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `padding` | `string` | No | Defines the extra space added around the scrollable area, enabling nearby items to remain partially in view. | | `page` | `number` | No | The controlled page of the carousel. | | `ref` | `Element` | No | | | `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. | | `slidesPerPage` | `number` | No | The number of slides to show at a time. | | `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. | | `spacing` | `string` | No | The amount of space between items. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | root | | `[data-orientation]` | The orientation of the carousel | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slides-per-page` | The number of slides visible per page | | `--slide-spacing` | The spacing between slides | | `--slide-item-size` | The calculated size of each slide item | **AutoplayTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **AutoplayTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | autoplay-trigger | | `[data-orientation]` | The orientation of the autoplaytrigger | | `[data-pressed]` | Present when pressed | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseCarouselContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | control | | `[data-orientation]` | The orientation of the control | **IndicatorGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **IndicatorGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator-group | | `[data-orientation]` | The orientation of the indicatorgroup | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the indicator. | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `readOnly` | `boolean` | No | Whether the indicator is read only. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator | | `[data-orientation]` | The orientation of the indicator | | `[data-index]` | The index of the item | | `[data-readonly]` | Present when read-only | | `[data-current]` | Present when current | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item-group | | `[data-orientation]` | The orientation of the item | | `[data-dragging]` | Present when in the dragging state | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the item. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `snapAlign` | `'start' | 'end' | 'center'` | No | The snap alignment of the item. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-inview]` | Present when in viewport | | `[data-orientation]` | The orientation of the item | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | next-trigger | | `[data-orientation]` | The orientation of the nexttrigger | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | prev-trigger | | `[data-orientation]` | The orientation of the prevtrigger | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCarouselReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `page` | `number` | The current index of the carousel | | `pageSnapPoints` | `number[]` | The current snap points of the carousel | | `isPlaying` | `boolean` | Whether the carousel is auto playing | | `isDragging` | `boolean` | Whether the carousel is being dragged. This only works when `draggable` is true. | | `canScrollNext` | `boolean` | Whether the carousel is can scroll to the next view | | `canScrollPrev` | `boolean` | Whether the carousel is can scroll to the previous view | | `scrollToIndex` | `(index: number, instant?: boolean) => void` | Function to scroll to a specific item index | | `scrollTo` | `(page: number, instant?: boolean) => void` | Function to scroll to a specific page | | `scrollNext` | `(instant?: boolean) => void` | Function to scroll to the next page | | `scrollPrev` | `(instant?: boolean) => void` | Function to scroll to the previous page | | `getProgress` | `() => number` | Returns the current scroll progress as a percentage | | `getProgressText` | `() => string` | Returns the progress text | | `play` | `VoidFunction` | Function to start/resume autoplay | | `pause` | `VoidFunction` | Function to pause autoplay | | `isInView` | `(index: number) => boolean` | Whether the item is in view | | `refresh` | `VoidFunction` | Function to re-compute the snap points and clamp the page | ## Accessibility Complies with the [Carousel WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/carousel/). --- # Carousel (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Basic = () => { return ( {images.map((image, index) => ( {image.alt} ))} {images.map((_, index) => ( ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Basic = () => { return ( {(image, index) => ( {image().alt} )} {(_, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each images as image, index} {image.alt} {/each} {#each images as _, index} {/each} ``` ### 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: **Example: controlled** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Controlled = () => { const [page, setPage] = useState(0) return ( setPage(e.page)}> {images.map((image, index) => ( {image.alt} ))} {images.map((_, index) => ( ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Controlled = () => { const [page, setPage] = createSignal(0) return ( setPage(details.page)} > {(image, index) => ( {image().alt} )} {(_, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Current page: {page}
                    {#each images as image, index} {image.alt} {/each} {#each images as _, index} {/each}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Carousel, useCarousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const RootProvider = () => { const carousel = useCarousel({ slideCount: images.length }) return (
                    Page: {carousel.page} {images.map((image, index) => ( {image.alt} ))} {images.map((_, index) => ( ))}
                    ) } ``` #### Solid ```tsx import { Carousel, useCarousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const RootProvider = () => { const carousel = useCarousel({ slideCount: images.length }) return (
                    Page: {carousel().page} {(image, index) => ( {image().alt} )} {(_, index) => }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Page: {carousel().page} {#each images as image, index} {image.alt} {/each} {#each images as _, index} {/each}
                    ``` ### Autoplay Pass the `autoplay` and `loop` props to `Carousel.Root` to make the carousel play automatically. **Example: autoplay** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ChevronLeftIcon, ChevronRightIcon, PauseIcon, PlayIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Autoplay = () => { return ( {images.map((image, index) => ( {image.alt} ))} }> ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ChevronLeftIcon, ChevronRightIcon, PauseIcon, PlayIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Autoplay = () => { return ( {(image, index) => ( {image().alt} )} }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each images as image, index} {image.alt} {/each} {#snippet fallback()}{/snippet} ``` ### 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. **Example: pause-on-hover** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const PauseOnHover = () => { return ( {({ isPlaying }) => ( Autoplay is: {isPlaying ? 'playing' : 'paused'} )} {(api) => ( api.pause()} onPointerLeave={() => api.play()} > {images.map((image, index) => ( {image.alt} ))} )} {images.map((_, index) => ( ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const PauseOnHover = () => { return ( {(carousel) => ( Autoplay is: {carousel().isPlaying ? 'playing' : 'paused'} )} {(api) => ( api().pause()} onPointerLeave={() => api().play()} > {(image, index) => ( {image().alt} )} )} {(_, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(api)} Autoplay is: {api().isPlaying ? 'playing' : 'paused'} {/snippet} {#snippet render(api)} api().pause()} onpointerleave={() => api().play()} > {#each images as image, index} {image.alt} {/each} {/snippet} {#each images as _, index} {/each} ``` ### Thumbnail Indicators Replace default indicator dots with image thumbnails. Render each thumbnail inside `Carousel.Indicator` to create a visual preview of each slide: **Example: thumbnail-indicator** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const ThumbnailIndicator = () => { return ( {images.map((image, index) => ( {image.alt} ))} {images.map((image, index) => ( {image.alt} ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const ThumbnailIndicator = () => { return ( {(image, index) => ( {image().alt} )} {(image, index) => ( {image().alt} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each images as image, index} {image.alt} {/each} {#each images as image, index} {image.alt} {/each} ``` ### 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. **Example: vertical** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowDownIcon, ArrowUpIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Vertical = () => { return ( {images.map((image, index) => ( {image.alt} ))} {images.map((_, index) => ( ))} ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowDownIcon, ArrowUpIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const images = [ { src: 'https://picsum.photos/seed/1/500/300', alt: 'Nature landscape' }, { src: 'https://picsum.photos/seed/2/500/300', alt: 'City skyline' }, { src: 'https://picsum.photos/seed/3/500/300', alt: 'Mountain view' }, { src: 'https://picsum.photos/seed/4/500/300', alt: 'Ocean sunset' }, { src: 'https://picsum.photos/seed/5/500/300', alt: 'Forest path' }, ] export const Vertical = () => { return ( {(image, index) => ( {image().alt} )} {(_, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each images as image, index} {image.alt} {/each} {#each images as _, index} {/each} ``` ### 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. **Example: dynamic-slides** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon, PlusIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/carousel.module.css' export const DynamicSlides = () => { const [slides, setSlides] = useState([0, 1, 2, 3, 4]) const [page, setPage] = useState(0) const addSlide = () => { setSlides((prevSlides) => { const max = Math.max(...prevSlides) return [...prevSlides, max + 1] }) } return (
                    setPage(details.page)} > {slides.map((slide, index) => (
                    Slide {slide + 1}
                    ))}
                    {slides.map((_, index) => ( ))}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon, PlusIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/carousel.module.css' export const DynamicSlides = () => { const [slides, setSlides] = createSignal([0, 1, 2, 3, 4]) const [page, setPage] = createSignal(0) const addSlide = () => { setSlides((prevSlides) => { const max = Math.max(...prevSlides) return [...prevSlides, max + 1] }) } return (
                    setPage(details.page)} > {(slide, index) => (
                    Slide {slide() + 1}
                    )}
                    {(_, index) => }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each slides as slide, index}
                    Slide {slide + 1}
                    {/each}
                    {#each slides as _, index} {/each}
                    ``` ### 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. **Example: scroll-to** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/carousel.module.css' export const ScrollTo = () => { return ( {(api) => ( )} {Array.from({ length: 5 }, (_, index) => (
                    Slide {index + 1}
                    ))}
                    {Array.from({ length: 5 }, (_, index) => ( ))}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/carousel.module.css' const slides = Array.from({ length: 6 }) export const ScrollTo = () => { return ( {(api) => ( )} {(_, index) => (
                    Slide {index + 1}
                    )}
                    {(_, index) => }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(api)} {/snippet} {#each slides as _, index}
                    Slide {index + 1}
                    {/each}
                    {#each slides as _, index} {/each}
                    ``` ### 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. **Example: slides-per-page** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' export const SlidesPerPage = () => { const slides = Array.from({ length: 6 }) return ( {slides.map((_, index) => (
                    Slide {index + 1}
                    ))}
                    {(api) => ( {api.pageSnapPoints.map((_, index) => ( ))} )}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const slides = Array.from({ length: 6 }) export const SlidesPerPage = () => { return ( {(_, index) => (
                    Slide {index + 1}
                    )}
                    {(api) => ( {(_, index) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each slides as _, index}
                    Slide {index + 1}
                    {/each}
                    {#snippet render(api)} {#each api().pageSnapPoints as _, index} {/each} {/snippet}
                    ``` ### 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. **Example: spacing** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const slides = Array.from({ length: 6 }) export const Spacing = () => { return ( spacing='48px' {slides.map((_, index) => (
                    {index + 1}
                    ))}
                    {(api) => ( {api.pageSnapPoints.map((_, index) => ( ))} )}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/carousel.module.css' const slides = Array.from({ length: 6 }) export const Spacing = () => { return ( spacing='48px' {(_, index) => (
                    {index + 1}
                    )}
                    {(api) => ( {(_, index) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte spacing='48px' {#each slides as _, index}
                    {index + 1}
                    {/each}
                    {#snippet render(api)} {#each api().pageSnapPoints as _, index} {/each} {/snippet}
                    ``` ### 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. **Example: variable-size** #### React ```tsx import { Carousel } from '@ark-ui/react/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react' import styles from 'styles/carousel.module.css' const items = [ { id: '1', width: '120px', label: 'Small' }, { id: '2', width: '200px', label: 'Medium Size' }, { id: '3', width: '80px', label: 'XS' }, { id: '4', width: '250px', label: 'Large Content Here' }, { id: '5', width: '150px', label: 'Regular' }, ] export const VariableSize = () => { return ( {items.map((item, index) => (
                    {item.label}
                    ))}
                    {(api) => ( {api.pageSnapPoints.map((_, index) => ( ))} )}
                    ) } ``` #### Solid ```tsx import { Carousel } from '@ark-ui/solid/carousel' import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/carousel.module.css' const items = [ { id: '1', width: '120px', label: 'Small' }, { id: '2', width: '200px', label: 'Medium Size' }, { id: '3', width: '80px', label: 'XS' }, { id: '4', width: '250px', label: 'Large Content Here' }, { id: '5', width: '150px', label: 'Regular' }, ] export const VariableSize = () => { return ( {(item, index) => (
                    {item.label}
                    )}
                    {(api) => ( {(_, index) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item, index}
                    {item.label}
                    {/each}
                    {#snippet render(api)} {#each api().pageSnapPoints as _, index} {/each} {/snippet}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `slideCount` | `number` | Yes | The total number of slides. Useful for SSR to render the initial ating the snap points. | | `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. | | `defaultPage` | `number` | No | The initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. | | `ids` | `Partial<{ root: string item: (index: number) => string itemGroup: string nextTrigger: string prevTrigger: string indicatorGroup: string indicator: (index: number) => string }>` | No | The ids of the elements in the carousel. Useful for composition. | | `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. | | `loop` | `boolean` | No | Whether the carousel should loop around. | | `onAutoplayStatusChange` | `(details: AutoplayStatusDetails) => void` | No | Function called when the autoplay status changes. | | `onDragStatusChange` | `(details: DragStatusDetails) => void` | No | Function called when the drag status changes. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Function called when the page changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `padding` | `string` | No | Defines the extra space added around the scrollable area, enabling nearby items to remain partially in view. | | `page` | `number` | No | The controlled page of the carousel. | | `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. | | `slidesPerPage` | `number` | No | The number of slides to show at a time. | | `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. | | `spacing` | `string` | No | The amount of space between items. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | root | | `[data-orientation]` | The orientation of the carousel | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slides-per-page` | The number of slides visible per page | | `--slide-spacing` | The spacing between slides | | `--slide-item-size` | The calculated size of each slide item | **AutoplayIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `paused` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | The content to render when autoplay is paused. | | `playing` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | The content to render when autoplay is playing. | **AutoplayTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AutoplayTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | autoplay-trigger | | `[data-orientation]` | The orientation of the autoplaytrigger | | `[data-pressed]` | Present when pressed | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | control | | `[data-orientation]` | The orientation of the control | **IndicatorGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IndicatorGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator-group | | `[data-orientation]` | The orientation of the indicatorgroup | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the indicator. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `readOnly` | `boolean` | No | Whether the indicator is read only. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator | | `[data-orientation]` | The orientation of the indicator | | `[data-index]` | The index of the item | | `[data-readonly]` | Present when read-only | | `[data-current]` | Present when current | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item-group | | `[data-orientation]` | The orientation of the item | | `[data-dragging]` | Present when in the dragging state | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the item. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `snapAlign` | `'center' | 'start' | 'end'` | No | The snap alignment of the item. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-inview]` | Present when in viewport | | `[data-orientation]` | The orientation of the item | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | next-trigger | | `[data-orientation]` | The orientation of the nexttrigger | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | prev-trigger | | `[data-orientation]` | The orientation of the prevtrigger | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCarouselReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `slideCount` | `number` | Yes | The total number of slides. Useful for SSR to render the initial ating the snap points. | | `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. | | `defaultPage` | `number` | No | The initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. | | `ids` | `Partial<{ root: string item: (index: number) => string itemGroup: string nextTrigger: string prevTrigger: string indicatorGroup: string indicator: (index: number) => string }>` | No | The ids of the elements in the carousel. Useful for composition. | | `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. | | `loop` | `boolean` | No | Whether the carousel should loop around. | | `onAutoplayStatusChange` | `(details: AutoplayStatusDetails) => void` | No | Function called when the autoplay status changes. | | `onDragStatusChange` | `(details: DragStatusDetails) => void` | No | Function called when the drag status changes. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Function called when the page changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `padding` | `string` | No | Defines the extra space added around the scrollable area, enabling nearby items to remain partially in view. | | `page` | `number` | No | The controlled page of the carousel. | | `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. | | `slidesPerPage` | `number` | No | The number of slides to show at a time. | | `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. | | `spacing` | `string` | No | The amount of space between items. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | root | | `[data-orientation]` | The orientation of the carousel | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slides-per-page` | The number of slides visible per page | | `--slide-spacing` | The spacing between slides | | `--slide-item-size` | The calculated size of each slide item | **AutoplayTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AutoplayTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | autoplay-trigger | | `[data-orientation]` | The orientation of the autoplaytrigger | | `[data-pressed]` | Present when pressed | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | control | | `[data-orientation]` | The orientation of the control | **IndicatorGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IndicatorGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator-group | | `[data-orientation]` | The orientation of the indicatorgroup | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the indicator. | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `readOnly` | `boolean` | No | Whether the indicator is read only. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator | | `[data-orientation]` | The orientation of the indicator | | `[data-index]` | The index of the item | | `[data-readonly]` | Present when read-only | | `[data-current]` | Present when current | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item-group | | `[data-orientation]` | The orientation of the item | | `[data-dragging]` | Present when in the dragging state | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the item. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `snapAlign` | `'start' | 'end' | 'center'` | No | The snap alignment of the item. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-inview]` | Present when in viewport | | `[data-orientation]` | The orientation of the item | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | next-trigger | | `[data-orientation]` | The orientation of the nexttrigger | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | prev-trigger | | `[data-orientation]` | The orientation of the prevtrigger | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCarouselReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `slideCount` | `number` | Yes | The total number of slides. Useful for SSR to render the initial ating the snap points. | | `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. | | `defaultPage` | `number` | No | The initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item(index: number): string itemGroup: string nextTrigger: string prevTrigger: string indicatorGroup: string indicator(index: number): string }>` | No | The ids of the elements in the carousel. Useful for composition. | | `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. | | `loop` | `boolean` | No | Whether the carousel should loop around. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `padding` | `string` | No | Defines the extra space added around the scrollable area, enabling nearby items to remain partially in view. | | `page` | `number` | No | The controlled page of the carousel. | | `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. | | `slidesPerPage` | `number` | No | The number of slides to show at a time. | | `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. | | `spacing` | `string` | No | The amount of space between items. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | root | | `[data-orientation]` | The orientation of the carousel | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slides-per-page` | The number of slides visible per page | | `--slide-spacing` | The spacing between slides | | `--slide-item-size` | The calculated size of each slide item | **AutoplayTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AutoplayTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | autoplay-trigger | | `[data-orientation]` | The orientation of the autoplaytrigger | | `[data-pressed]` | Present when pressed | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | control | | `[data-orientation]` | The orientation of the control | **IndicatorGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IndicatorGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator-group | | `[data-orientation]` | The orientation of the indicatorgroup | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the indicator. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `readOnly` | `boolean` | No | Whether the indicator is read only. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator | | `[data-orientation]` | The orientation of the indicator | | `[data-index]` | The index of the item | | `[data-readonly]` | Present when read-only | | `[data-current]` | Present when current | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item-group | | `[data-orientation]` | The orientation of the item | | `[data-dragging]` | Present when in the dragging state | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the item. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `snapAlign` | `'start' | 'end' | 'center'` | No | The snap alignment of the item. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-inview]` | Present when in viewport | | `[data-orientation]` | The orientation of the item | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | next-trigger | | `[data-orientation]` | The orientation of the nexttrigger | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | prev-trigger | | `[data-orientation]` | The orientation of the prevtrigger | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `CarouselApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `slideCount` | `number` | Yes | The total number of slides. Useful for SSR to render the initial ating the snap points. | | `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. | | `defaultPage` | `number` | No | The initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item: (index: number) => string itemGroup: string nextTrigger: string prevTrigger: string indicatorGroup: string indicator: (index: number) => string }>` | No | The ids of the elements in the carousel. Useful for composition. | | `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. | | `loop` | `boolean` | No | Whether the carousel should loop around. | | `onAutoplayStatusChange` | `(details: AutoplayStatusDetails) => void` | No | Function called when the autoplay status changes. | | `onDragStatusChange` | `(details: DragStatusDetails) => void` | No | Function called when the drag status changes. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Function called when the page changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `padding` | `string` | No | Defines the extra space added around the scrollable area, enabling nearby items to remain partially in view. | | `page` | `number` | No | The controlled page of the carousel. | | `ref` | `Element` | No | | | `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. | | `slidesPerPage` | `number` | No | The number of slides to show at a time. | | `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. | | `spacing` | `string` | No | The amount of space between items. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | root | | `[data-orientation]` | The orientation of the carousel | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slides-per-page` | The number of slides visible per page | | `--slide-spacing` | The spacing between slides | | `--slide-item-size` | The calculated size of each slide item | **AutoplayTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **AutoplayTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | autoplay-trigger | | `[data-orientation]` | The orientation of the autoplaytrigger | | `[data-pressed]` | Present when pressed | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseCarouselContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | control | | `[data-orientation]` | The orientation of the control | **IndicatorGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **IndicatorGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator-group | | `[data-orientation]` | The orientation of the indicatorgroup | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the indicator. | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `readOnly` | `boolean` | No | Whether the indicator is read only. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | indicator | | `[data-orientation]` | The orientation of the indicator | | `[data-index]` | The index of the item | | `[data-readonly]` | Present when read-only | | `[data-current]` | Present when current | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item-group | | `[data-orientation]` | The orientation of the item | | `[data-dragging]` | Present when in the dragging state | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | The index of the item. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `snapAlign` | `'start' | 'end' | 'center'` | No | The snap alignment of the item. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-inview]` | Present when in viewport | | `[data-orientation]` | The orientation of the item | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | next-trigger | | `[data-orientation]` | The orientation of the nexttrigger | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | carousel | | `[data-part]` | prev-trigger | | `[data-orientation]` | The orientation of the prevtrigger | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCarouselReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `page` | `number` | The current index of the carousel | | `pageSnapPoints` | `number[]` | The current snap points of the carousel | | `isPlaying` | `boolean` | Whether the carousel is auto playing | | `isDragging` | `boolean` | Whether the carousel is being dragged. This only works when `draggable` is true. | | `canScrollNext` | `boolean` | Whether the carousel is can scroll to the next view | | `canScrollPrev` | `boolean` | Whether the carousel is can scroll to the previous view | | `scrollToIndex` | `(index: number, instant?: boolean) => void` | Function to scroll to a specific item index | | `scrollTo` | `(page: number, instant?: boolean) => void` | Function to scroll to a specific page | | `scrollNext` | `(instant?: boolean) => void` | Function to scroll to the next page | | `scrollPrev` | `(instant?: boolean) => void` | Function to scroll to the previous page | | `getProgress` | `() => number` | Returns the current scroll progress as a percentage | | `getProgressText` | `() => string` | Returns the progress text | | `play` | `VoidFunction` | Function to start/resume autoplay | | `pause` | `VoidFunction` | Function to pause autoplay | | `isInView` | `(index: number) => boolean` | Whether the item is in view | | `refresh` | `VoidFunction` | Function to re-compute the snap points and clamp the page | ## Accessibility Complies with the [Carousel WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/carousel/). --- # Checkbox (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Basic = () => ( Checkbox ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const Basic = () => ( Checkbox ) ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### Default Checked Use the `defaultChecked` prop to set the initial checked state in an uncontrolled manner. The checkbox will manage its own state internally. **Example: default-checked** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const DefaultChecked = () => ( Checkbox ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const DefaultChecked = () => ( Checkbox ) ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### Controlled Use the `checked` and `onCheckedChange` props to programatically control the checkbox's state. **Example: controlled** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/checkbox.module.css' export const Controlled = () => { const [checked, setChecked] = useState(true) return ( setChecked(e.checked)}> Checkbox ) } ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/checkbox.module.css' export const Controlled = () => { const [checked, setChecked] = createSignal(true) return ( setChecked(e.checked)}> Checkbox ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### 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. **Example: root-provider** #### React ```tsx import { Checkbox, useCheckbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const RootProvider = () => { const checkbox = useCheckbox() return (
                    Checkbox {checkbox.checked ? ( ) : ( )}
                    ) } ``` #### Solid ```tsx import { Checkbox, useCheckbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const RootProvider = () => { const checkbox = useCheckbox() return (
                    Checkbox {checkbox().checked ? ( ) : ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Checkbox {#if checkbox().checked} {:else} {/if}
                    ``` ### Disabled Use the `disabled` prop to make the checkbox non-interactive. **Example: disabled** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Disabled = () => ( Checkbox ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const Disabled = () => ( Checkbox ) ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### Indeterminate Use the `indeterminate` prop to create a checkbox in an indeterminate state (partially checked). **Example: indeterminate** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon, MinusIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Indeterminate = () => ( Checkbox ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon, MinusIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const Indeterminate = () => ( Checkbox ) ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### Field The checkbox integrates smoothly with the `Field` component to handle form state, helper text, and error text for proper accessibility. **Example: with-field** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { Field } from '@ark-ui/react/field' import { CheckIcon, MinusIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import field from 'styles/field.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { Field } from '@ark-ui/solid/field' import { CheckIcon, MinusIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' import field from 'styles/field.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Additional Info Error Info ``` ### Form Pass the `name` and `value` props to the `Checkbox.Root` component to make the checkbox part of a form. The checkbox's value will be submitted with the form when the user submits it. **Example: with-form** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const WithForm = () => (
                    { e.preventDefault() const formData = new FormData(e.currentTarget) console.log('terms:', formData.get('terms')) }} > I agree to the terms and conditions
                    ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const WithForm = () => (
                    { e.preventDefault() const formData = new FormData(e.currentTarget) console.log('terms:', formData.get('terms')) }} > I agree to the terms and conditions
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    { e.preventDefault() const formData = new FormData(e.currentTarget) console.log('terms:', formData.get('terms')) }} > I agree to the terms and conditions
                    ``` ### Context Use the `Checkbox.Context` component to access the checkbox's state and methods. **Example: context** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Context = () => ( {(checkbox) => Checked: {String(checkbox.checked)}} ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const Context = () => ( {(checkbox) => Checked: {String(checkbox().checked)}} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(api)} Checked: {String(api().checked)} {/snippet} ``` ### 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. **Example: group** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Group = () => ( {items.map((item) => ( {item.label} ))} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' export const Group = () => ( {(item) => ( {item.label} )} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.label} {/each} ``` ### Controlled Group Use the `value` and `onValueChange` props to programmatically control the checkbox group's state. This example demonstrates how to manage selected checkboxes in an array and display the current selection. **Example: group-controlled** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/checkbox.module.css' export const GroupControlled = () => { const [value, setValue] = useState(['react']) return (
                    value: {JSON.stringify(value)} {items.map((item) => ( {item.label} ))}
                    ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { createSignal, For } from 'solid-js' import styles from 'styles/checkbox.module.css' export const GroupControlled = () => { const [value, setValue] = createSignal(['react']) return (
                    value: {JSON.stringify(value())} {(item) => ( {item.label} )}
                    ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    value: {JSON.stringify(value)} {#each items as item (item.value)} {item.label} {/each}
                    ``` ### 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. **Example: group-provider** #### React ```tsx import { Checkbox, useCheckboxGroup } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const GroupProvider = () => { const group = useCheckboxGroup({ defaultValue: ['react'], name: 'framework', }) return ( {items.map((item) => ( {item.label} ))} ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox, useCheckboxGroup } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' export const GroupProvider = () => { const group = useCheckboxGroup({ defaultValue: ['react'], name: 'framework', }) return ( {(item) => ( {item.label} )} ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.label} {/each} ``` ### 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. **Example: group-with-invalid** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const GroupWithInvalid = () => ( {items.map((item) => ( {item.label} ))} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' export const GroupWithInvalid = () => ( {(item) => ( {item.label} )} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.label} {/each} ``` ### 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. **Example: group-with-select-all** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon, MinusIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/checkbox.module.css' const CheckboxItem = (props: Checkbox.RootProps) => { return ( {props.children} ) } export const GroupWithSelectAll = () => { const [value, setValue] = useState([]) const handleSelectAll = (checked: boolean) => { setValue(checked ? items.map((item) => item.value) : []) } const allSelected = value.length === items.length const indeterminate = value.length > 0 && value.length < items.length return (
                    Selected: {JSON.stringify(value)} handleSelectAll(!!e.checked)} > JSX Frameworks {items.map((item) => ( {item.label} ))}
                    ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon, MinusIcon } from 'lucide-solid' import { For, createSignal, createMemo } from 'solid-js' import styles from 'styles/checkbox.module.css' const CheckboxItem = (props: Checkbox.RootProps) => ( {props.children} ) export const GroupWithSelectAll = () => { const [value, setValue] = createSignal([]) const handleSelectAll = (checked: boolean) => { setValue(checked ? items.map((item) => item.value) : []) } const allSelected = createMemo(() => value().length === items.length) const indeterminate = createMemo(() => value().length > 0 && value().length < items.length) return (
                    Selected: {JSON.stringify(value())} handleSelectAll(!!details.checked)} > JSX Frameworks {(item) => {item.label}}
                    ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet CheckboxItem(item: (typeof items)[number])} {item.label} {/snippet}
                    Selected: {JSON.stringify(value)} handleSelectAll(!!e.checked)} > JSX Frameworks {#each items as item (item.value)} {@render CheckboxItem(item)} {/each}
                    ``` ### Group Form Use the `Checkbox.Group` component within a form to handle multiple checkbox values with form submission. The `name` prop ensures all selected values are collected as an array when the form is submitted using `FormData.getAll()`. **Example: group-with-form** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const GroupWithForm = () => (
                    { e.preventDefault() console.log(new FormData(e.currentTarget).getAll('framework')) }} > {items.map((item) => ( {item.label} ))}
                    ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const GroupWithForm = () => (
                    { e.preventDefault() console.log(new FormData(e.currentTarget).getAll('framework')) }} > {(item) => ( {item.label} )}
                    ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    { e.preventDefault() console.log(new FormData(e.currentTarget).getAll('framework')) }} > {#each items as item (item.value)} {item.label} {/each}
                    ``` ### Fieldset Use the `Fieldset` component with `Checkbox.Group` to provide semantic grouping with legend, helper text, and error text support. **Example: group-with-fieldset** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { Fieldset } from '@ark-ui/react/fieldset' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import fieldset from 'styles/fieldset.module.css' export const GroupWithFieldset = () => ( Select frameworks Choose your preferred frameworks {items.map((item) => ( {item.label} ))} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { Fieldset } from '@ark-ui/solid/fieldset' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' import fieldset from 'styles/fieldset.module.css' export const GroupWithFieldset = () => ( Select frameworks Choose your preferred frameworks {(item) => ( {item.label} )} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte Select frameworks Choose your preferred frameworks {#each items as item (item.value)} {item.label} {/each} ``` ## Guides ### asChild Behavior The `Checkbox.Root` element of the checkbox is a `label` element. This is because the checkbox is a form control and should be associated with a label to provide context and meaning to the user. Otherwise, the HTML and accessibility structure will be invalid. > If you need to use the `asChild` property, make sure that the `label` element is the direct child of the > `Checkbox.Root` component. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `CheckedState` | No | The controlled checked state of the checkbox | | `defaultChecked` | `CheckedState` | No | The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | | `disabled` | `boolean` | No | Whether the checkbox is disabled | | `form` | `string` | No | The id of the form that the checkbox belongs to. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | No | The ids of the elements in the checkbox. Useful for composition. | | `invalid` | `boolean` | No | Whether the checkbox is invalid | | `name` | `string` | No | The name of the input field in a checkbox. Useful for form submission. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | The callback invoked when the checked state changes. | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `required` | `boolean` | No | Whether the checkbox is required | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Group Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial value of `value` when uncontrolled | | `disabled` | `boolean` | No | If `true`, the checkbox group is disabled | | `invalid` | `boolean` | No | If `true`, the checkbox group is invalid | | `name` | `string` | No | The name of the input fields in the checkbox group (Useful for form submission). | | `onValueChange` | `(value: string[]) => void` | No | The callback to call when the value changes | | `readOnly` | `boolean` | No | If `true`, the checkbox group is read-only | | `value` | `string[]` | No | The controlled value of the checkbox group | **GroupProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxGroupContext` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indeterminate` | `boolean` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `CheckedState` | No | The controlled checked state of the checkbox | | `defaultChecked` | `CheckedState` | No | The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | | `disabled` | `boolean` | No | Whether the checkbox is disabled | | `form` | `string` | No | The id of the form that the checkbox belongs to. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | No | The ids of the elements in the checkbox. Useful for composition. | | `invalid` | `boolean` | No | Whether the checkbox is invalid | | `name` | `string` | No | The name of the input field in a checkbox. Useful for form submission. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | The callback invoked when the checked state changes. | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `required` | `boolean` | No | Whether the checkbox is required | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Group Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[] | Accessor` | No | The initial value of `value` when uncontrolled | | `disabled` | `boolean` | No | If `true`, the checkbox group is disabled | | `invalid` | `boolean` | No | If `true`, the checkbox group is invalid | | `name` | `string` | No | The name of the input fields in the checkbox group (Useful for form submission). | | `onValueChange` | `(value: string[]) => void` | No | The callback to call when the value changes | | `readOnly` | `boolean` | No | If `true`, the checkbox group is read-only | | `value` | `Accessor` | No | The controlled value of the checkbox group | **GroupProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxGroupContext` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indeterminate` | `boolean` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxReturn` | Yes | | | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `CheckedState` | No | The controlled checked state of the checkbox | | `defaultChecked` | `CheckedState` | No | The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | | `disabled` | `boolean` | No | Whether the checkbox is disabled | | `form` | `string` | No | The id of the form that the checkbox belongs to. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | No | The ids of the elements in the checkbox. Useful for composition. | | `invalid` | `boolean` | No | Whether the checkbox is invalid | | `name` | `string` | No | The name of the input field in a checkbox. Useful for form submission. | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `required` | `boolean` | No | Whether the checkbox is required | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Group Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial value of `value` when uncontrolled | | `disabled` | `boolean` | No | If `true`, the checkbox group is disabled | | `invalid` | `boolean` | No | If `true`, the checkbox group is invalid | | `modelValue` | `string[]` | No | The controlled value of the checkbox group | | `name` | `string` | No | The name of the input fields in the checkbox group (Useful for form submission). | | `readOnly` | `boolean` | No | If `true`, the checkbox group is read-only | **GroupProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ isChecked: (val: string | undefined) => boolean; value: string[]; name: string | undefined; disabled: boolean | undefined; readOnly: boolean | undefined; invalid: boolean | undefined; addValue: (val: string) => void; setValue: (value: string[]) => void; toggleValue: (val: string) => void; getItemProps: (itemProps:...` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indeterminate` | `boolean` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `CheckboxApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `CheckedState` | No | The controlled checked state of the checkbox | | `defaultChecked` | `CheckedState` | No | The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | | `disabled` | `boolean` | No | Whether the checkbox is disabled | | `form` | `string` | No | The id of the form that the checkbox belongs to. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | No | The ids of the elements in the checkbox. Useful for composition. | | `invalid` | `boolean` | No | Whether the checkbox is invalid | | `name` | `string` | No | The name of the input field in a checkbox. Useful for form submission. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | The callback invoked when the checked state changes. | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the checkbox is required | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseCheckboxReturn]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Group Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial value of `value` when uncontrolled | | `disabled` | `boolean` | No | If `true`, the checkbox group is disabled | | `invalid` | `boolean` | No | If `true`, the checkbox group is invalid | | `name` | `string` | No | The name of the input fields in the checkbox group (Useful for form submission). | | `onValueChange` | `(value: string[]) => void` | No | The callback to call when the value changes | | `readOnly` | `boolean` | No | If `true`, the checkbox group is read-only | | `ref` | `Element` | No | | | `value` | `string[]` | No | The controlled value of the checkbox group | **GroupProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `() => { isChecked: (val: string | undefined) => boolean; value: string[]; name: string | undefined; disabled: boolean; readOnly: boolean; invalid: boolean; setValue: (newValue: string[]) => void; addValue: (val: string) => void; toggleValue: (val: string) => void; getItemProps: (itemProps: CheckboxGroupItemProps) =>...` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indeterminate` | `boolean` | No | | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `checked` | `boolean` | Whether the checkbox is checked | | `disabled` | `boolean` | Whether the checkbox is disabled | | `indeterminate` | `boolean` | Whether the checkbox is indeterminate | | `focused` | `boolean` | Whether the checkbox is focused | | `checkedState` | `CheckedState` | The checked state of the checkbox | | `setChecked` | `(checked: CheckedState) => void` | Function to set the checked state of the checkbox | | `toggleChecked` | `VoidFunction` | Function to toggle the checked state of the checkbox | ## Accessibility Complies with the [Checkbox WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/). ### Keyboard Support **`Space`** Description: Toggle the checkbox --- # Checkbox (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Basic = () => ( Checkbox ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const Basic = () => ( Checkbox ) ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### Default Checked Use the `defaultChecked` prop to set the initial checked state in an uncontrolled manner. The checkbox will manage its own state internally. **Example: default-checked** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const DefaultChecked = () => ( Checkbox ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const DefaultChecked = () => ( Checkbox ) ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### Controlled Use the `checked` and `onCheckedChange` props to programatically control the checkbox's state. **Example: controlled** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/checkbox.module.css' export const Controlled = () => { const [checked, setChecked] = useState(true) return ( setChecked(e.checked)}> Checkbox ) } ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/checkbox.module.css' export const Controlled = () => { const [checked, setChecked] = createSignal(true) return ( setChecked(e.checked)}> Checkbox ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### 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. **Example: root-provider** #### React ```tsx import { Checkbox, useCheckbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const RootProvider = () => { const checkbox = useCheckbox() return (
                    Checkbox {checkbox.checked ? ( ) : ( )}
                    ) } ``` #### Solid ```tsx import { Checkbox, useCheckbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const RootProvider = () => { const checkbox = useCheckbox() return (
                    Checkbox {checkbox().checked ? ( ) : ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Checkbox {#if checkbox().checked} {:else} {/if}
                    ``` ### Disabled Use the `disabled` prop to make the checkbox non-interactive. **Example: disabled** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Disabled = () => ( Checkbox ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const Disabled = () => ( Checkbox ) ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### Indeterminate Use the `indeterminate` prop to create a checkbox in an indeterminate state (partially checked). **Example: indeterminate** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon, MinusIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Indeterminate = () => ( Checkbox ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon, MinusIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const Indeterminate = () => ( Checkbox ) ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### Field The checkbox integrates smoothly with the `Field` component to handle form state, helper text, and error text for proper accessibility. **Example: with-field** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { Field } from '@ark-ui/react/field' import { CheckIcon, MinusIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import field from 'styles/field.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { Field } from '@ark-ui/solid/field' import { CheckIcon, MinusIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' import field from 'styles/field.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Additional Info Error Info ``` ### Form Pass the `name` and `value` props to the `Checkbox.Root` component to make the checkbox part of a form. The checkbox's value will be submitted with the form when the user submits it. **Example: with-form** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const WithForm = () => (
                    { e.preventDefault() const formData = new FormData(e.currentTarget) console.log('terms:', formData.get('terms')) }} > I agree to the terms and conditions
                    ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const WithForm = () => (
                    { e.preventDefault() const formData = new FormData(e.currentTarget) console.log('terms:', formData.get('terms')) }} > I agree to the terms and conditions
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    { e.preventDefault() const formData = new FormData(e.currentTarget) console.log('terms:', formData.get('terms')) }} > I agree to the terms and conditions
                    ``` ### Context Use the `Checkbox.Context` component to access the checkbox's state and methods. **Example: context** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Context = () => ( {(checkbox) => Checked: {String(checkbox.checked)}} ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const Context = () => ( {(checkbox) => Checked: {String(checkbox().checked)}} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(api)} Checked: {String(api().checked)} {/snippet} ``` ### 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. **Example: group** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Group = () => ( {items.map((item) => ( {item.label} ))} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' export const Group = () => ( {(item) => ( {item.label} )} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.label} {/each} ``` ### Controlled Group Use the `value` and `onValueChange` props to programmatically control the checkbox group's state. This example demonstrates how to manage selected checkboxes in an array and display the current selection. **Example: group-controlled** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/checkbox.module.css' export const GroupControlled = () => { const [value, setValue] = useState(['react']) return (
                    value: {JSON.stringify(value)} {items.map((item) => ( {item.label} ))}
                    ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { createSignal, For } from 'solid-js' import styles from 'styles/checkbox.module.css' export const GroupControlled = () => { const [value, setValue] = createSignal(['react']) return (
                    value: {JSON.stringify(value())} {(item) => ( {item.label} )}
                    ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    value: {JSON.stringify(value)} {#each items as item (item.value)} {item.label} {/each}
                    ``` ### 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. **Example: group-provider** #### React ```tsx import { Checkbox, useCheckboxGroup } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const GroupProvider = () => { const group = useCheckboxGroup({ defaultValue: ['react'], name: 'framework', }) return ( {items.map((item) => ( {item.label} ))} ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox, useCheckboxGroup } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' export const GroupProvider = () => { const group = useCheckboxGroup({ defaultValue: ['react'], name: 'framework', }) return ( {(item) => ( {item.label} )} ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.label} {/each} ``` ### 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. **Example: group-with-invalid** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const GroupWithInvalid = () => ( {items.map((item) => ( {item.label} ))} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' export const GroupWithInvalid = () => ( {(item) => ( {item.label} )} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.label} {/each} ``` ### 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. **Example: group-with-select-all** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon, MinusIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/checkbox.module.css' const CheckboxItem = (props: Checkbox.RootProps) => { return ( {props.children} ) } export const GroupWithSelectAll = () => { const [value, setValue] = useState([]) const handleSelectAll = (checked: boolean) => { setValue(checked ? items.map((item) => item.value) : []) } const allSelected = value.length === items.length const indeterminate = value.length > 0 && value.length < items.length return (
                    Selected: {JSON.stringify(value)} handleSelectAll(!!e.checked)} > JSX Frameworks {items.map((item) => ( {item.label} ))}
                    ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon, MinusIcon } from 'lucide-solid' import { For, createSignal, createMemo } from 'solid-js' import styles from 'styles/checkbox.module.css' const CheckboxItem = (props: Checkbox.RootProps) => ( {props.children} ) export const GroupWithSelectAll = () => { const [value, setValue] = createSignal([]) const handleSelectAll = (checked: boolean) => { setValue(checked ? items.map((item) => item.value) : []) } const allSelected = createMemo(() => value().length === items.length) const indeterminate = createMemo(() => value().length > 0 && value().length < items.length) return (
                    Selected: {JSON.stringify(value())} handleSelectAll(!!details.checked)} > JSX Frameworks {(item) => {item.label}}
                    ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet CheckboxItem(item: (typeof items)[number])} {item.label} {/snippet}
                    Selected: {JSON.stringify(value)} handleSelectAll(!!e.checked)} > JSX Frameworks {#each items as item (item.value)} {@render CheckboxItem(item)} {/each}
                    ``` ### Group Form Use the `Checkbox.Group` component within a form to handle multiple checkbox values with form submission. The `name` prop ensures all selected values are collected as an array when the form is submitted using `FormData.getAll()`. **Example: group-with-form** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const GroupWithForm = () => (
                    { e.preventDefault() console.log(new FormData(e.currentTarget).getAll('framework')) }} > {items.map((item) => ( {item.label} ))}
                    ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const GroupWithForm = () => (
                    { e.preventDefault() console.log(new FormData(e.currentTarget).getAll('framework')) }} > {(item) => ( {item.label} )}
                    ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    { e.preventDefault() console.log(new FormData(e.currentTarget).getAll('framework')) }} > {#each items as item (item.value)} {item.label} {/each}
                    ``` ### Fieldset Use the `Fieldset` component with `Checkbox.Group` to provide semantic grouping with legend, helper text, and error text support. **Example: group-with-fieldset** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { Fieldset } from '@ark-ui/react/fieldset' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import fieldset from 'styles/fieldset.module.css' export const GroupWithFieldset = () => ( Select frameworks Choose your preferred frameworks {items.map((item) => ( {item.label} ))} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { Fieldset } from '@ark-ui/solid/fieldset' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' import fieldset from 'styles/fieldset.module.css' export const GroupWithFieldset = () => ( Select frameworks Choose your preferred frameworks {(item) => ( {item.label} )} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte Select frameworks Choose your preferred frameworks {#each items as item (item.value)} {item.label} {/each} ``` ## Guides ### asChild Behavior The `Checkbox.Root` element of the checkbox is a `label` element. This is because the checkbox is a form control and should be associated with a label to provide context and meaning to the user. Otherwise, the HTML and accessibility structure will be invalid. > If you need to use the `asChild` property, make sure that the `label` element is the direct child of the > `Checkbox.Root` component. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `CheckedState` | No | The controlled checked state of the checkbox | | `defaultChecked` | `CheckedState` | No | The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | | `disabled` | `boolean` | No | Whether the checkbox is disabled | | `form` | `string` | No | The id of the form that the checkbox belongs to. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | No | The ids of the elements in the checkbox. Useful for composition. | | `invalid` | `boolean` | No | Whether the checkbox is invalid | | `name` | `string` | No | The name of the input field in a checkbox. Useful for form submission. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | The callback invoked when the checked state changes. | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `required` | `boolean` | No | Whether the checkbox is required | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Group Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial value of `value` when uncontrolled | | `disabled` | `boolean` | No | If `true`, the checkbox group is disabled | | `invalid` | `boolean` | No | If `true`, the checkbox group is invalid | | `name` | `string` | No | The name of the input fields in the checkbox group (Useful for form submission). | | `onValueChange` | `(value: string[]) => void` | No | The callback to call when the value changes | | `readOnly` | `boolean` | No | If `true`, the checkbox group is read-only | | `value` | `string[]` | No | The controlled value of the checkbox group | **GroupProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxGroupContext` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indeterminate` | `boolean` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `CheckedState` | No | The controlled checked state of the checkbox | | `defaultChecked` | `CheckedState` | No | The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | | `disabled` | `boolean` | No | Whether the checkbox is disabled | | `form` | `string` | No | The id of the form that the checkbox belongs to. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | No | The ids of the elements in the checkbox. Useful for composition. | | `invalid` | `boolean` | No | Whether the checkbox is invalid | | `name` | `string` | No | The name of the input field in a checkbox. Useful for form submission. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | The callback invoked when the checked state changes. | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `required` | `boolean` | No | Whether the checkbox is required | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Group Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[] | Accessor` | No | The initial value of `value` when uncontrolled | | `disabled` | `boolean` | No | If `true`, the checkbox group is disabled | | `invalid` | `boolean` | No | If `true`, the checkbox group is invalid | | `name` | `string` | No | The name of the input fields in the checkbox group (Useful for form submission). | | `onValueChange` | `(value: string[]) => void` | No | The callback to call when the value changes | | `readOnly` | `boolean` | No | If `true`, the checkbox group is read-only | | `value` | `Accessor` | No | The controlled value of the checkbox group | **GroupProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxGroupContext` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indeterminate` | `boolean` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxReturn` | Yes | | | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `CheckedState` | No | The controlled checked state of the checkbox | | `defaultChecked` | `CheckedState` | No | The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | | `disabled` | `boolean` | No | Whether the checkbox is disabled | | `form` | `string` | No | The id of the form that the checkbox belongs to. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | No | The ids of the elements in the checkbox. Useful for composition. | | `invalid` | `boolean` | No | Whether the checkbox is invalid | | `name` | `string` | No | The name of the input field in a checkbox. Useful for form submission. | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `required` | `boolean` | No | Whether the checkbox is required | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Group Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial value of `value` when uncontrolled | | `disabled` | `boolean` | No | If `true`, the checkbox group is disabled | | `invalid` | `boolean` | No | If `true`, the checkbox group is invalid | | `modelValue` | `string[]` | No | The controlled value of the checkbox group | | `name` | `string` | No | The name of the input fields in the checkbox group (Useful for form submission). | | `readOnly` | `boolean` | No | If `true`, the checkbox group is read-only | **GroupProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ isChecked: (val: string | undefined) => boolean; value: string[]; name: string | undefined; disabled: boolean | undefined; readOnly: boolean | undefined; invalid: boolean | undefined; addValue: (val: string) => void; setValue: (value: string[]) => void; toggleValue: (val: string) => void; getItemProps: (itemProps:...` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indeterminate` | `boolean` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `CheckboxApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `CheckedState` | No | The controlled checked state of the checkbox | | `defaultChecked` | `CheckedState` | No | The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | | `disabled` | `boolean` | No | Whether the checkbox is disabled | | `form` | `string` | No | The id of the form that the checkbox belongs to. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | No | The ids of the elements in the checkbox. Useful for composition. | | `invalid` | `boolean` | No | Whether the checkbox is invalid | | `name` | `string` | No | The name of the input field in a checkbox. Useful for form submission. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | The callback invoked when the checked state changes. | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the checkbox is required | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseCheckboxReturn]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Group Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial value of `value` when uncontrolled | | `disabled` | `boolean` | No | If `true`, the checkbox group is disabled | | `invalid` | `boolean` | No | If `true`, the checkbox group is invalid | | `name` | `string` | No | The name of the input fields in the checkbox group (Useful for form submission). | | `onValueChange` | `(value: string[]) => void` | No | The callback to call when the value changes | | `readOnly` | `boolean` | No | If `true`, the checkbox group is read-only | | `ref` | `Element` | No | | | `value` | `string[]` | No | The controlled value of the checkbox group | **GroupProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `() => { isChecked: (val: string | undefined) => boolean; value: string[]; name: string | undefined; disabled: boolean; readOnly: boolean; invalid: boolean; setValue: (newValue: string[]) => void; addValue: (val: string) => void; toggleValue: (val: string) => void; getItemProps: (itemProps: CheckboxGroupItemProps) =>...` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indeterminate` | `boolean` | No | | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `checked` | `boolean` | Whether the checkbox is checked | | `disabled` | `boolean` | Whether the checkbox is disabled | | `indeterminate` | `boolean` | Whether the checkbox is indeterminate | | `focused` | `boolean` | Whether the checkbox is focused | | `checkedState` | `CheckedState` | The checked state of the checkbox | | `setChecked` | `(checked: CheckedState) => void` | Function to set the checked state of the checkbox | | `toggleChecked` | `VoidFunction` | Function to toggle the checked state of the checkbox | ## Accessibility Complies with the [Checkbox WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/). ### Keyboard Support **`Space`** Description: Toggle the checkbox --- # Checkbox (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Basic = () => ( Checkbox ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const Basic = () => ( Checkbox ) ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### Default Checked Use the `defaultChecked` prop to set the initial checked state in an uncontrolled manner. The checkbox will manage its own state internally. **Example: default-checked** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const DefaultChecked = () => ( Checkbox ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const DefaultChecked = () => ( Checkbox ) ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### Controlled Use the `checked` and `onCheckedChange` props to programatically control the checkbox's state. **Example: controlled** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/checkbox.module.css' export const Controlled = () => { const [checked, setChecked] = useState(true) return ( setChecked(e.checked)}> Checkbox ) } ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/checkbox.module.css' export const Controlled = () => { const [checked, setChecked] = createSignal(true) return ( setChecked(e.checked)}> Checkbox ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### 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. **Example: root-provider** #### React ```tsx import { Checkbox, useCheckbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const RootProvider = () => { const checkbox = useCheckbox() return (
                    Checkbox {checkbox.checked ? ( ) : ( )}
                    ) } ``` #### Solid ```tsx import { Checkbox, useCheckbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const RootProvider = () => { const checkbox = useCheckbox() return (
                    Checkbox {checkbox().checked ? ( ) : ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Checkbox {#if checkbox().checked} {:else} {/if}
                    ``` ### Disabled Use the `disabled` prop to make the checkbox non-interactive. **Example: disabled** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Disabled = () => ( Checkbox ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const Disabled = () => ( Checkbox ) ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### Indeterminate Use the `indeterminate` prop to create a checkbox in an indeterminate state (partially checked). **Example: indeterminate** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon, MinusIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Indeterminate = () => ( Checkbox ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon, MinusIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const Indeterminate = () => ( Checkbox ) ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### Field The checkbox integrates smoothly with the `Field` component to handle form state, helper text, and error text for proper accessibility. **Example: with-field** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { Field } from '@ark-ui/react/field' import { CheckIcon, MinusIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import field from 'styles/field.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { Field } from '@ark-ui/solid/field' import { CheckIcon, MinusIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' import field from 'styles/field.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Additional Info Error Info ``` ### Form Pass the `name` and `value` props to the `Checkbox.Root` component to make the checkbox part of a form. The checkbox's value will be submitted with the form when the user submits it. **Example: with-form** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const WithForm = () => (
                    { e.preventDefault() const formData = new FormData(e.currentTarget) console.log('terms:', formData.get('terms')) }} > I agree to the terms and conditions
                    ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const WithForm = () => (
                    { e.preventDefault() const formData = new FormData(e.currentTarget) console.log('terms:', formData.get('terms')) }} > I agree to the terms and conditions
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    { e.preventDefault() const formData = new FormData(e.currentTarget) console.log('terms:', formData.get('terms')) }} > I agree to the terms and conditions
                    ``` ### Context Use the `Checkbox.Context` component to access the checkbox's state and methods. **Example: context** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Context = () => ( {(checkbox) => Checked: {String(checkbox.checked)}} ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const Context = () => ( {(checkbox) => Checked: {String(checkbox().checked)}} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(api)} Checked: {String(api().checked)} {/snippet} ``` ### 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. **Example: group** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Group = () => ( {items.map((item) => ( {item.label} ))} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' export const Group = () => ( {(item) => ( {item.label} )} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.label} {/each} ``` ### Controlled Group Use the `value` and `onValueChange` props to programmatically control the checkbox group's state. This example demonstrates how to manage selected checkboxes in an array and display the current selection. **Example: group-controlled** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/checkbox.module.css' export const GroupControlled = () => { const [value, setValue] = useState(['react']) return (
                    value: {JSON.stringify(value)} {items.map((item) => ( {item.label} ))}
                    ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { createSignal, For } from 'solid-js' import styles from 'styles/checkbox.module.css' export const GroupControlled = () => { const [value, setValue] = createSignal(['react']) return (
                    value: {JSON.stringify(value())} {(item) => ( {item.label} )}
                    ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    value: {JSON.stringify(value)} {#each items as item (item.value)} {item.label} {/each}
                    ``` ### 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. **Example: group-provider** #### React ```tsx import { Checkbox, useCheckboxGroup } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const GroupProvider = () => { const group = useCheckboxGroup({ defaultValue: ['react'], name: 'framework', }) return ( {items.map((item) => ( {item.label} ))} ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox, useCheckboxGroup } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' export const GroupProvider = () => { const group = useCheckboxGroup({ defaultValue: ['react'], name: 'framework', }) return ( {(item) => ( {item.label} )} ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.label} {/each} ``` ### 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. **Example: group-with-invalid** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const GroupWithInvalid = () => ( {items.map((item) => ( {item.label} ))} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' export const GroupWithInvalid = () => ( {(item) => ( {item.label} )} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.label} {/each} ``` ### 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. **Example: group-with-select-all** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon, MinusIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/checkbox.module.css' const CheckboxItem = (props: Checkbox.RootProps) => { return ( {props.children} ) } export const GroupWithSelectAll = () => { const [value, setValue] = useState([]) const handleSelectAll = (checked: boolean) => { setValue(checked ? items.map((item) => item.value) : []) } const allSelected = value.length === items.length const indeterminate = value.length > 0 && value.length < items.length return (
                    Selected: {JSON.stringify(value)} handleSelectAll(!!e.checked)} > JSX Frameworks {items.map((item) => ( {item.label} ))}
                    ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon, MinusIcon } from 'lucide-solid' import { For, createSignal, createMemo } from 'solid-js' import styles from 'styles/checkbox.module.css' const CheckboxItem = (props: Checkbox.RootProps) => ( {props.children} ) export const GroupWithSelectAll = () => { const [value, setValue] = createSignal([]) const handleSelectAll = (checked: boolean) => { setValue(checked ? items.map((item) => item.value) : []) } const allSelected = createMemo(() => value().length === items.length) const indeterminate = createMemo(() => value().length > 0 && value().length < items.length) return (
                    Selected: {JSON.stringify(value())} handleSelectAll(!!details.checked)} > JSX Frameworks {(item) => {item.label}}
                    ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet CheckboxItem(item: (typeof items)[number])} {item.label} {/snippet}
                    Selected: {JSON.stringify(value)} handleSelectAll(!!e.checked)} > JSX Frameworks {#each items as item (item.value)} {@render CheckboxItem(item)} {/each}
                    ``` ### Group Form Use the `Checkbox.Group` component within a form to handle multiple checkbox values with form submission. The `name` prop ensures all selected values are collected as an array when the form is submitted using `FormData.getAll()`. **Example: group-with-form** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const GroupWithForm = () => (
                    { e.preventDefault() console.log(new FormData(e.currentTarget).getAll('framework')) }} > {items.map((item) => ( {item.label} ))}
                    ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const GroupWithForm = () => (
                    { e.preventDefault() console.log(new FormData(e.currentTarget).getAll('framework')) }} > {(item) => ( {item.label} )}
                    ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    { e.preventDefault() console.log(new FormData(e.currentTarget).getAll('framework')) }} > {#each items as item (item.value)} {item.label} {/each}
                    ``` ### Fieldset Use the `Fieldset` component with `Checkbox.Group` to provide semantic grouping with legend, helper text, and error text support. **Example: group-with-fieldset** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { Fieldset } from '@ark-ui/react/fieldset' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import fieldset from 'styles/fieldset.module.css' export const GroupWithFieldset = () => ( Select frameworks Choose your preferred frameworks {items.map((item) => ( {item.label} ))} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { Fieldset } from '@ark-ui/solid/fieldset' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' import fieldset from 'styles/fieldset.module.css' export const GroupWithFieldset = () => ( Select frameworks Choose your preferred frameworks {(item) => ( {item.label} )} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte Select frameworks Choose your preferred frameworks {#each items as item (item.value)} {item.label} {/each} ``` ## Guides ### asChild Behavior The `Checkbox.Root` element of the checkbox is a `label` element. This is because the checkbox is a form control and should be associated with a label to provide context and meaning to the user. Otherwise, the HTML and accessibility structure will be invalid. > If you need to use the `asChild` property, make sure that the `label` element is the direct child of the > `Checkbox.Root` component. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `CheckedState` | No | The controlled checked state of the checkbox | | `defaultChecked` | `CheckedState` | No | The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | | `disabled` | `boolean` | No | Whether the checkbox is disabled | | `form` | `string` | No | The id of the form that the checkbox belongs to. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | No | The ids of the elements in the checkbox. Useful for composition. | | `invalid` | `boolean` | No | Whether the checkbox is invalid | | `name` | `string` | No | The name of the input field in a checkbox. Useful for form submission. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | The callback invoked when the checked state changes. | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `required` | `boolean` | No | Whether the checkbox is required | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Group Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial value of `value` when uncontrolled | | `disabled` | `boolean` | No | If `true`, the checkbox group is disabled | | `invalid` | `boolean` | No | If `true`, the checkbox group is invalid | | `name` | `string` | No | The name of the input fields in the checkbox group (Useful for form submission). | | `onValueChange` | `(value: string[]) => void` | No | The callback to call when the value changes | | `readOnly` | `boolean` | No | If `true`, the checkbox group is read-only | | `value` | `string[]` | No | The controlled value of the checkbox group | **GroupProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxGroupContext` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indeterminate` | `boolean` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `CheckedState` | No | The controlled checked state of the checkbox | | `defaultChecked` | `CheckedState` | No | The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | | `disabled` | `boolean` | No | Whether the checkbox is disabled | | `form` | `string` | No | The id of the form that the checkbox belongs to. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | No | The ids of the elements in the checkbox. Useful for composition. | | `invalid` | `boolean` | No | Whether the checkbox is invalid | | `name` | `string` | No | The name of the input field in a checkbox. Useful for form submission. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | The callback invoked when the checked state changes. | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `required` | `boolean` | No | Whether the checkbox is required | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Group Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[] | Accessor` | No | The initial value of `value` when uncontrolled | | `disabled` | `boolean` | No | If `true`, the checkbox group is disabled | | `invalid` | `boolean` | No | If `true`, the checkbox group is invalid | | `name` | `string` | No | The name of the input fields in the checkbox group (Useful for form submission). | | `onValueChange` | `(value: string[]) => void` | No | The callback to call when the value changes | | `readOnly` | `boolean` | No | If `true`, the checkbox group is read-only | | `value` | `Accessor` | No | The controlled value of the checkbox group | **GroupProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxGroupContext` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indeterminate` | `boolean` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxReturn` | Yes | | | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `CheckedState` | No | The controlled checked state of the checkbox | | `defaultChecked` | `CheckedState` | No | The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | | `disabled` | `boolean` | No | Whether the checkbox is disabled | | `form` | `string` | No | The id of the form that the checkbox belongs to. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | No | The ids of the elements in the checkbox. Useful for composition. | | `invalid` | `boolean` | No | Whether the checkbox is invalid | | `name` | `string` | No | The name of the input field in a checkbox. Useful for form submission. | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `required` | `boolean` | No | Whether the checkbox is required | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Group Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial value of `value` when uncontrolled | | `disabled` | `boolean` | No | If `true`, the checkbox group is disabled | | `invalid` | `boolean` | No | If `true`, the checkbox group is invalid | | `modelValue` | `string[]` | No | The controlled value of the checkbox group | | `name` | `string` | No | The name of the input fields in the checkbox group (Useful for form submission). | | `readOnly` | `boolean` | No | If `true`, the checkbox group is read-only | **GroupProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ isChecked: (val: string | undefined) => boolean; value: string[]; name: string | undefined; disabled: boolean | undefined; readOnly: boolean | undefined; invalid: boolean | undefined; addValue: (val: string) => void; setValue: (value: string[]) => void; toggleValue: (val: string) => void; getItemProps: (itemProps:...` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indeterminate` | `boolean` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `CheckboxApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `CheckedState` | No | The controlled checked state of the checkbox | | `defaultChecked` | `CheckedState` | No | The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | | `disabled` | `boolean` | No | Whether the checkbox is disabled | | `form` | `string` | No | The id of the form that the checkbox belongs to. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | No | The ids of the elements in the checkbox. Useful for composition. | | `invalid` | `boolean` | No | Whether the checkbox is invalid | | `name` | `string` | No | The name of the input field in a checkbox. Useful for form submission. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | The callback invoked when the checked state changes. | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the checkbox is required | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseCheckboxReturn]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Group Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial value of `value` when uncontrolled | | `disabled` | `boolean` | No | If `true`, the checkbox group is disabled | | `invalid` | `boolean` | No | If `true`, the checkbox group is invalid | | `name` | `string` | No | The name of the input fields in the checkbox group (Useful for form submission). | | `onValueChange` | `(value: string[]) => void` | No | The callback to call when the value changes | | `readOnly` | `boolean` | No | If `true`, the checkbox group is read-only | | `ref` | `Element` | No | | | `value` | `string[]` | No | The controlled value of the checkbox group | **GroupProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `() => { isChecked: (val: string | undefined) => boolean; value: string[]; name: string | undefined; disabled: boolean; readOnly: boolean; invalid: boolean; setValue: (newValue: string[]) => void; addValue: (val: string) => void; toggleValue: (val: string) => void; getItemProps: (itemProps: CheckboxGroupItemProps) =>...` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indeterminate` | `boolean` | No | | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `checked` | `boolean` | Whether the checkbox is checked | | `disabled` | `boolean` | Whether the checkbox is disabled | | `indeterminate` | `boolean` | Whether the checkbox is indeterminate | | `focused` | `boolean` | Whether the checkbox is focused | | `checkedState` | `CheckedState` | The checked state of the checkbox | | `setChecked` | `(checked: CheckedState) => void` | Function to set the checked state of the checkbox | | `toggleChecked` | `VoidFunction` | Function to toggle the checked state of the checkbox | ## Accessibility Complies with the [Checkbox WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/). ### Keyboard Support **`Space`** Description: Toggle the checkbox --- # Checkbox (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Basic = () => ( Checkbox ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const Basic = () => ( Checkbox ) ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### Default Checked Use the `defaultChecked` prop to set the initial checked state in an uncontrolled manner. The checkbox will manage its own state internally. **Example: default-checked** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const DefaultChecked = () => ( Checkbox ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const DefaultChecked = () => ( Checkbox ) ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### Controlled Use the `checked` and `onCheckedChange` props to programatically control the checkbox's state. **Example: controlled** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/checkbox.module.css' export const Controlled = () => { const [checked, setChecked] = useState(true) return ( setChecked(e.checked)}> Checkbox ) } ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/checkbox.module.css' export const Controlled = () => { const [checked, setChecked] = createSignal(true) return ( setChecked(e.checked)}> Checkbox ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### 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. **Example: root-provider** #### React ```tsx import { Checkbox, useCheckbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const RootProvider = () => { const checkbox = useCheckbox() return (
                    Checkbox {checkbox.checked ? ( ) : ( )}
                    ) } ``` #### Solid ```tsx import { Checkbox, useCheckbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const RootProvider = () => { const checkbox = useCheckbox() return (
                    Checkbox {checkbox().checked ? ( ) : ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Checkbox {#if checkbox().checked} {:else} {/if}
                    ``` ### Disabled Use the `disabled` prop to make the checkbox non-interactive. **Example: disabled** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Disabled = () => ( Checkbox ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const Disabled = () => ( Checkbox ) ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### Indeterminate Use the `indeterminate` prop to create a checkbox in an indeterminate state (partially checked). **Example: indeterminate** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon, MinusIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Indeterminate = () => ( Checkbox ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon, MinusIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const Indeterminate = () => ( Checkbox ) ``` #### Vue ```vue ``` #### Svelte ```svelte Checkbox ``` ### Field The checkbox integrates smoothly with the `Field` component to handle form state, helper text, and error text for proper accessibility. **Example: with-field** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { Field } from '@ark-ui/react/field' import { CheckIcon, MinusIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import field from 'styles/field.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { Field } from '@ark-ui/solid/field' import { CheckIcon, MinusIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' import field from 'styles/field.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Additional Info Error Info ``` ### Form Pass the `name` and `value` props to the `Checkbox.Root` component to make the checkbox part of a form. The checkbox's value will be submitted with the form when the user submits it. **Example: with-form** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const WithForm = () => (
                    { e.preventDefault() const formData = new FormData(e.currentTarget) console.log('terms:', formData.get('terms')) }} > I agree to the terms and conditions
                    ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const WithForm = () => (
                    { e.preventDefault() const formData = new FormData(e.currentTarget) console.log('terms:', formData.get('terms')) }} > I agree to the terms and conditions
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    { e.preventDefault() const formData = new FormData(e.currentTarget) console.log('terms:', formData.get('terms')) }} > I agree to the terms and conditions
                    ``` ### Context Use the `Checkbox.Context` component to access the checkbox's state and methods. **Example: context** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Context = () => ( {(checkbox) => Checked: {String(checkbox.checked)}} ) ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' export const Context = () => ( {(checkbox) => Checked: {String(checkbox().checked)}} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(api)} Checked: {String(api().checked)} {/snippet} ``` ### 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. **Example: group** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const Group = () => ( {items.map((item) => ( {item.label} ))} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' export const Group = () => ( {(item) => ( {item.label} )} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.label} {/each} ``` ### Controlled Group Use the `value` and `onValueChange` props to programmatically control the checkbox group's state. This example demonstrates how to manage selected checkboxes in an array and display the current selection. **Example: group-controlled** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/checkbox.module.css' export const GroupControlled = () => { const [value, setValue] = useState(['react']) return (
                    value: {JSON.stringify(value)} {items.map((item) => ( {item.label} ))}
                    ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { createSignal, For } from 'solid-js' import styles from 'styles/checkbox.module.css' export const GroupControlled = () => { const [value, setValue] = createSignal(['react']) return (
                    value: {JSON.stringify(value())} {(item) => ( {item.label} )}
                    ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    value: {JSON.stringify(value)} {#each items as item (item.value)} {item.label} {/each}
                    ``` ### 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. **Example: group-provider** #### React ```tsx import { Checkbox, useCheckboxGroup } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const GroupProvider = () => { const group = useCheckboxGroup({ defaultValue: ['react'], name: 'framework', }) return ( {items.map((item) => ( {item.label} ))} ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox, useCheckboxGroup } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' export const GroupProvider = () => { const group = useCheckboxGroup({ defaultValue: ['react'], name: 'framework', }) return ( {(item) => ( {item.label} )} ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.label} {/each} ``` ### 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. **Example: group-with-invalid** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' export const GroupWithInvalid = () => ( {items.map((item) => ( {item.label} ))} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' export const GroupWithInvalid = () => ( {(item) => ( {item.label} )} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item (item.value)} {item.label} {/each} ``` ### 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. **Example: group-with-select-all** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon, MinusIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/checkbox.module.css' const CheckboxItem = (props: Checkbox.RootProps) => { return ( {props.children} ) } export const GroupWithSelectAll = () => { const [value, setValue] = useState([]) const handleSelectAll = (checked: boolean) => { setValue(checked ? items.map((item) => item.value) : []) } const allSelected = value.length === items.length const indeterminate = value.length > 0 && value.length < items.length return (
                    Selected: {JSON.stringify(value)} handleSelectAll(!!e.checked)} > JSX Frameworks {items.map((item) => ( {item.label} ))}
                    ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon, MinusIcon } from 'lucide-solid' import { For, createSignal, createMemo } from 'solid-js' import styles from 'styles/checkbox.module.css' const CheckboxItem = (props: Checkbox.RootProps) => ( {props.children} ) export const GroupWithSelectAll = () => { const [value, setValue] = createSignal([]) const handleSelectAll = (checked: boolean) => { setValue(checked ? items.map((item) => item.value) : []) } const allSelected = createMemo(() => value().length === items.length) const indeterminate = createMemo(() => value().length > 0 && value().length < items.length) return (
                    Selected: {JSON.stringify(value())} handleSelectAll(!!details.checked)} > JSX Frameworks {(item) => {item.label}}
                    ) } const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet CheckboxItem(item: (typeof items)[number])} {item.label} {/snippet}
                    Selected: {JSON.stringify(value)} handleSelectAll(!!e.checked)} > JSX Frameworks {#each items as item (item.value)} {@render CheckboxItem(item)} {/each}
                    ``` ### Group Form Use the `Checkbox.Group` component within a form to handle multiple checkbox values with form submission. The `name` prop ensures all selected values are collected as an array when the form is submitted using `FormData.getAll()`. **Example: group-with-form** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const GroupWithForm = () => (
                    { e.preventDefault() console.log(new FormData(e.currentTarget).getAll('framework')) }} > {items.map((item) => ( {item.label} ))}
                    ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' import button from 'styles/button.module.css' export const GroupWithForm = () => (
                    { e.preventDefault() console.log(new FormData(e.currentTarget).getAll('framework')) }} > {(item) => ( {item.label} )}
                    ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte
                    { e.preventDefault() console.log(new FormData(e.currentTarget).getAll('framework')) }} > {#each items as item (item.value)} {item.label} {/each}
                    ``` ### Fieldset Use the `Fieldset` component with `Checkbox.Group` to provide semantic grouping with legend, helper text, and error text support. **Example: group-with-fieldset** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { Fieldset } from '@ark-ui/react/fieldset' import { CheckIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import fieldset from 'styles/fieldset.module.css' export const GroupWithFieldset = () => ( Select frameworks Choose your preferred frameworks {items.map((item) => ( {item.label} ))} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { Fieldset } from '@ark-ui/solid/fieldset' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/checkbox.module.css' import fieldset from 'styles/fieldset.module.css' export const GroupWithFieldset = () => ( Select frameworks Choose your preferred frameworks {(item) => ( {item.label} )} ) const items = [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte Select frameworks Choose your preferred frameworks {#each items as item (item.value)} {item.label} {/each} ``` ## Guides ### asChild Behavior The `Checkbox.Root` element of the checkbox is a `label` element. This is because the checkbox is a form control and should be associated with a label to provide context and meaning to the user. Otherwise, the HTML and accessibility structure will be invalid. > If you need to use the `asChild` property, make sure that the `label` element is the direct child of the > `Checkbox.Root` component. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `CheckedState` | No | The controlled checked state of the checkbox | | `defaultChecked` | `CheckedState` | No | The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | | `disabled` | `boolean` | No | Whether the checkbox is disabled | | `form` | `string` | No | The id of the form that the checkbox belongs to. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | No | The ids of the elements in the checkbox. Useful for composition. | | `invalid` | `boolean` | No | Whether the checkbox is invalid | | `name` | `string` | No | The name of the input field in a checkbox. Useful for form submission. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | The callback invoked when the checked state changes. | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `required` | `boolean` | No | Whether the checkbox is required | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Group Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial value of `value` when uncontrolled | | `disabled` | `boolean` | No | If `true`, the checkbox group is disabled | | `invalid` | `boolean` | No | If `true`, the checkbox group is invalid | | `name` | `string` | No | The name of the input fields in the checkbox group (Useful for form submission). | | `onValueChange` | `(value: string[]) => void` | No | The callback to call when the value changes | | `readOnly` | `boolean` | No | If `true`, the checkbox group is read-only | | `value` | `string[]` | No | The controlled value of the checkbox group | **GroupProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxGroupContext` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indeterminate` | `boolean` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `CheckedState` | No | The controlled checked state of the checkbox | | `defaultChecked` | `CheckedState` | No | The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | | `disabled` | `boolean` | No | Whether the checkbox is disabled | | `form` | `string` | No | The id of the form that the checkbox belongs to. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | No | The ids of the elements in the checkbox. Useful for composition. | | `invalid` | `boolean` | No | Whether the checkbox is invalid | | `name` | `string` | No | The name of the input field in a checkbox. Useful for form submission. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | The callback invoked when the checked state changes. | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `required` | `boolean` | No | Whether the checkbox is required | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Group Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[] | Accessor` | No | The initial value of `value` when uncontrolled | | `disabled` | `boolean` | No | If `true`, the checkbox group is disabled | | `invalid` | `boolean` | No | If `true`, the checkbox group is invalid | | `name` | `string` | No | The name of the input fields in the checkbox group (Useful for form submission). | | `onValueChange` | `(value: string[]) => void` | No | The callback to call when the value changes | | `readOnly` | `boolean` | No | If `true`, the checkbox group is read-only | | `value` | `Accessor` | No | The controlled value of the checkbox group | **GroupProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxGroupContext` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indeterminate` | `boolean` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxReturn` | Yes | | | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `CheckedState` | No | The controlled checked state of the checkbox | | `defaultChecked` | `CheckedState` | No | The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | | `disabled` | `boolean` | No | Whether the checkbox is disabled | | `form` | `string` | No | The id of the form that the checkbox belongs to. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | No | The ids of the elements in the checkbox. Useful for composition. | | `invalid` | `boolean` | No | Whether the checkbox is invalid | | `name` | `string` | No | The name of the input field in a checkbox. Useful for form submission. | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `required` | `boolean` | No | Whether the checkbox is required | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Group Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial value of `value` when uncontrolled | | `disabled` | `boolean` | No | If `true`, the checkbox group is disabled | | `invalid` | `boolean` | No | If `true`, the checkbox group is invalid | | `modelValue` | `string[]` | No | The controlled value of the checkbox group | | `name` | `string` | No | The name of the input fields in the checkbox group (Useful for form submission). | | `readOnly` | `boolean` | No | If `true`, the checkbox group is read-only | **GroupProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ isChecked: (val: string | undefined) => boolean; value: string[]; name: string | undefined; disabled: boolean | undefined; readOnly: boolean | undefined; invalid: boolean | undefined; addValue: (val: string) => void; setValue: (value: string[]) => void; toggleValue: (val: string) => void; getItemProps: (itemProps:...` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indeterminate` | `boolean` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `CheckboxApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `CheckedState` | No | The controlled checked state of the checkbox | | `defaultChecked` | `CheckedState` | No | The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | | `disabled` | `boolean` | No | Whether the checkbox is disabled | | `form` | `string` | No | The id of the form that the checkbox belongs to. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | No | The ids of the elements in the checkbox. Useful for composition. | | `invalid` | `boolean` | No | Whether the checkbox is invalid | | `name` | `string` | No | The name of the input field in a checkbox. Useful for form submission. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | The callback invoked when the checked state changes. | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the checkbox is required | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseCheckboxReturn]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Group Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial value of `value` when uncontrolled | | `disabled` | `boolean` | No | If `true`, the checkbox group is disabled | | `invalid` | `boolean` | No | If `true`, the checkbox group is invalid | | `name` | `string` | No | The name of the input fields in the checkbox group (Useful for form submission). | | `onValueChange` | `(value: string[]) => void` | No | The callback to call when the value changes | | `readOnly` | `boolean` | No | If `true`, the checkbox group is read-only | | `ref` | `Element` | No | | | `value` | `string[]` | No | The controlled value of the checkbox group | **GroupProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `() => { isChecked: (val: string | undefined) => boolean; value: string[]; name: string | undefined; disabled: boolean; readOnly: boolean; invalid: boolean; setValue: (newValue: string[]) => void; addValue: (val: string) => void; toggleValue: (val: string) => void; getItemProps: (itemProps: CheckboxGroupItemProps) =>...` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indeterminate` | `boolean` | No | | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "indeterminate" | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCheckboxReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `checked` | `boolean` | Whether the checkbox is checked | | `disabled` | `boolean` | Whether the checkbox is disabled | | `indeterminate` | `boolean` | Whether the checkbox is indeterminate | | `focused` | `boolean` | Whether the checkbox is focused | | `checkedState` | `CheckedState` | The checked state of the checkbox | | `setChecked` | `(checked: CheckedState) => void` | Function to set the checked state of the checkbox | | `toggleChecked` | `VoidFunction` | Function to toggle the checked state of the checkbox | ## Accessibility Complies with the [Checkbox WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/). ### Keyboard Support **`Space`** Description: Toggle the checkbox --- # Clipboard (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import styles from 'styles/clipboard.module.css' export const Basic = () => { return ( Copy this link }> ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import styles from 'styles/clipboard.module.css' export const Basic = () => { return ( Copy this link }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Copy this link {#snippet copied()} {/snippet} ``` ### Controlled Control the clipboard value externally by managing the state yourself and using `onValueChange` to handle updates. **Example: controlled** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/clipboard.module.css' export const Controlled = () => { const [url, setUrl] = useState('https://ark-ui.com') return (
                    setUrl(details.value)}> Copy this link }>
                    ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/clipboard.module.css' export const Controlled = () => { const [url, setUrl] = createSignal('https://ark-ui.com') return (
                    setUrl(details.value)}> Copy this link }>
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Copy this link {#snippet copied()} {/snippet}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Clipboard, useClipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import styles from 'styles/clipboard.module.css' export const RootProvider = () => { const clipboard = useClipboard({ value: 'https://ark-ui.com' }) return (
                    value: {clipboard.value}, copied: {String(clipboard.copied)} Copy this link }>
                    ) } ``` #### Solid ```tsx import { Clipboard, useClipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import styles from 'styles/clipboard.module.css' export const RootProvider = () => { const clipboard = useClipboard({ value: 'https://ark-ui.com' }) return (
                    value: {clipboard().value}, copied: {String(clipboard().copied)} Copy this link }>
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    value: {clipboard().value}, copied: {String(clipboard().copied)} Copy this link {#snippet copied()} {/snippet}
                    ``` ### Context Access the clipboard state and methods using `Clipboard.Context`. This provides access to properties like `copied`, `value`, and `setValue` > Alternatively, you can use the `useClipboardContext` hook to access the clipboard context. **Example: context** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/clipboard.module.css' export const Context = () => { return ( Copy this link {(clipboard) => ( )} ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import { Show } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/clipboard.module.css' export const Context = () => { return ( Copy this link {(clipboard) => ( )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Copy this link {#snippet render(clipboard)} {/snippet} ``` ### 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. **Example: copy-status** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/clipboard.module.css' export const CopyStatus = () => { const [copyCount, setCopyCount] = useState(0) return ( { if (details.copied) setCopyCount((prev) => prev + 1) }} > }>

                    Copied {copyCount} times

                    ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/clipboard.module.css' export const CopyStatus = () => { const [copyCount, setCopyCount] = createSignal(0) return ( { if (details.copied) { setCopyCount((prev) => prev + 1) } }} > }>

                    Copied {copyCount()} times

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte { if (details.copied) { copyCount += 1 } }} > {#snippet copied()} {/snippet}

                    Copied {copyCount} times

                    ``` ### Timeout Configure the copy status timeout duration using the `timeout` prop. Default is 3000ms (3 seconds). **Example: timeout** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import styles from 'styles/clipboard.module.css' export const Timeout = () => { return ( Copy this link (5 second timeout) }> ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import styles from 'styles/clipboard.module.css' export const Timeout = () => { return ( Copy this link (5 second timeout) }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Copy this link (5 second timeout) {#snippet copied()} {/snippet} ``` ### Value Text Use `Clipboard.ValueText` to display the current clipboard value. **Example: value-text** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import styles from 'styles/clipboard.module.css' export const ValueText = () => { return ( }> ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import styles from 'styles/clipboard.module.css' export const ValueText = () => { return ( }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet copied()} {/snippet} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to be copied to the clipboard when rendered. Use when you don't need to control the value of the clipboard. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; input: string; label: string }>` | No | The ids of the elements in the clipboard. Useful for composition. | | `onStatusChange` | `(details: CopyStatusDetails) => void` | No | The function to be called when the value is copied to the clipboard | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The function to be called when the value changes | | `timeout` | `number` | No | The timeout for the copy operation | | `value` | `string` | No | The controlled value of the clipboard | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | root | | `[data-copied]` | Present when copied state is true | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | control | | `[data-copied]` | Present when copied state is true | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `copied` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | input | | `[data-copied]` | Present when copied state is true | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | label | | `[data-copied]` | Present when copied state is true | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseClipboardReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | trigger | | `[data-copied]` | Present when copied state is true | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to be copied to the clipboard when rendered. Use when you don't need to control the value of the clipboard. | | `ids` | `Partial<{ root: string; input: string; label: string }>` | No | The ids of the elements in the clipboard. Useful for composition. | | `onStatusChange` | `(details: CopyStatusDetails) => void` | No | The function to be called when the value is copied to the clipboard | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The function to be called when the value changes | | `timeout` | `number` | No | The timeout for the copy operation | | `value` | `string` | No | The controlled value of the clipboard | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | root | | `[data-copied]` | Present when copied state is true | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | control | | `[data-copied]` | Present when copied state is true | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `copied` | `number | boolean | Node | ArrayElement | (string & {})` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | input | | `[data-copied]` | Present when copied state is true | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | label | | `[data-copied]` | Present when copied state is true | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseClipboardReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | trigger | | `[data-copied]` | Present when copied state is true | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to be copied to the clipboard when rendered. Use when you don't need to control the value of the clipboard. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; input: string; label: string }>` | No | The ids of the elements in the clipboard. Useful for composition. | | `modelValue` | `string` | No | The v-model value of the clipboard | | `timeout` | `number` | No | The timeout for the copy operation | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | root | | `[data-copied]` | Present when copied state is true | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | control | | `[data-copied]` | Present when copied state is true | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | input | | `[data-copied]` | Present when copied state is true | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | label | | `[data-copied]` | Present when copied state is true | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ClipboardApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | trigger | | `[data-copied]` | Present when copied state is true | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to be copied to the clipboard when rendered. Use when you don't need to control the value of the clipboard. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; input: string; label: string }>` | No | The ids of the elements in the clipboard. Useful for composition. | | `onStatusChange` | `(details: CopyStatusDetails) => void` | No | The function to be called when the value is copied to the clipboard | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The function to be called when the value changes | | `ref` | `Element` | No | | | `timeout` | `number` | No | The timeout for the copy operation | | `value` | `string` | No | The controlled value of the clipboard | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | root | | `[data-copied]` | Present when copied state is true | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseClipboardContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | control | | `[data-copied]` | Present when copied state is true | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `copied` | `Snippet<[]>` | No | | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | input | | `[data-copied]` | Present when copied state is true | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | label | | `[data-copied]` | Present when copied state is true | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseClipboardReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | trigger | | `[data-copied]` | Present when copied state is true | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `copied` | `boolean` | Whether the value has been copied to the clipboard | | `value` | `string` | The value to be copied to the clipboard | | `setValue` | `(value: string) => void` | Set the value to be copied to the clipboard | | `copy` | `VoidFunction` | Copy the value to the clipboard | --- # Clipboard (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import styles from 'styles/clipboard.module.css' export const Basic = () => { return ( Copy this link }> ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import styles from 'styles/clipboard.module.css' export const Basic = () => { return ( Copy this link }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Copy this link {#snippet copied()} {/snippet} ``` ### Controlled Control the clipboard value externally by managing the state yourself and using `onValueChange` to handle updates. **Example: controlled** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/clipboard.module.css' export const Controlled = () => { const [url, setUrl] = useState('https://ark-ui.com') return (
                    setUrl(details.value)}> Copy this link }>
                    ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/clipboard.module.css' export const Controlled = () => { const [url, setUrl] = createSignal('https://ark-ui.com') return (
                    setUrl(details.value)}> Copy this link }>
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Copy this link {#snippet copied()} {/snippet}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Clipboard, useClipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import styles from 'styles/clipboard.module.css' export const RootProvider = () => { const clipboard = useClipboard({ value: 'https://ark-ui.com' }) return (
                    value: {clipboard.value}, copied: {String(clipboard.copied)} Copy this link }>
                    ) } ``` #### Solid ```tsx import { Clipboard, useClipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import styles from 'styles/clipboard.module.css' export const RootProvider = () => { const clipboard = useClipboard({ value: 'https://ark-ui.com' }) return (
                    value: {clipboard().value}, copied: {String(clipboard().copied)} Copy this link }>
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    value: {clipboard().value}, copied: {String(clipboard().copied)} Copy this link {#snippet copied()} {/snippet}
                    ``` ### Context Access the clipboard state and methods using `Clipboard.Context`. This provides access to properties like `copied`, `value`, and `setValue` > Alternatively, you can use the `useClipboardContext` hook to access the clipboard context. **Example: context** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/clipboard.module.css' export const Context = () => { return ( Copy this link {(clipboard) => ( )} ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import { Show } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/clipboard.module.css' export const Context = () => { return ( Copy this link {(clipboard) => ( )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Copy this link {#snippet render(clipboard)} {/snippet} ``` ### 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. **Example: copy-status** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/clipboard.module.css' export const CopyStatus = () => { const [copyCount, setCopyCount] = useState(0) return ( { if (details.copied) setCopyCount((prev) => prev + 1) }} > }>

                    Copied {copyCount} times

                    ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/clipboard.module.css' export const CopyStatus = () => { const [copyCount, setCopyCount] = createSignal(0) return ( { if (details.copied) { setCopyCount((prev) => prev + 1) } }} > }>

                    Copied {copyCount()} times

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte { if (details.copied) { copyCount += 1 } }} > {#snippet copied()} {/snippet}

                    Copied {copyCount} times

                    ``` ### Timeout Configure the copy status timeout duration using the `timeout` prop. Default is 3000ms (3 seconds). **Example: timeout** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import styles from 'styles/clipboard.module.css' export const Timeout = () => { return ( Copy this link (5 second timeout) }> ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import styles from 'styles/clipboard.module.css' export const Timeout = () => { return ( Copy this link (5 second timeout) }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Copy this link (5 second timeout) {#snippet copied()} {/snippet} ``` ### Value Text Use `Clipboard.ValueText` to display the current clipboard value. **Example: value-text** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import styles from 'styles/clipboard.module.css' export const ValueText = () => { return ( }> ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import styles from 'styles/clipboard.module.css' export const ValueText = () => { return ( }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet copied()} {/snippet} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to be copied to the clipboard when rendered. Use when you don't need to control the value of the clipboard. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; input: string; label: string }>` | No | The ids of the elements in the clipboard. Useful for composition. | | `onStatusChange` | `(details: CopyStatusDetails) => void` | No | The function to be called when the value is copied to the clipboard | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The function to be called when the value changes | | `timeout` | `number` | No | The timeout for the copy operation | | `value` | `string` | No | The controlled value of the clipboard | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | root | | `[data-copied]` | Present when copied state is true | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | control | | `[data-copied]` | Present when copied state is true | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `copied` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | input | | `[data-copied]` | Present when copied state is true | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | label | | `[data-copied]` | Present when copied state is true | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseClipboardReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | trigger | | `[data-copied]` | Present when copied state is true | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to be copied to the clipboard when rendered. Use when you don't need to control the value of the clipboard. | | `ids` | `Partial<{ root: string; input: string; label: string }>` | No | The ids of the elements in the clipboard. Useful for composition. | | `onStatusChange` | `(details: CopyStatusDetails) => void` | No | The function to be called when the value is copied to the clipboard | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The function to be called when the value changes | | `timeout` | `number` | No | The timeout for the copy operation | | `value` | `string` | No | The controlled value of the clipboard | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | root | | `[data-copied]` | Present when copied state is true | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | control | | `[data-copied]` | Present when copied state is true | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `copied` | `number | boolean | Node | ArrayElement | (string & {})` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | input | | `[data-copied]` | Present when copied state is true | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | label | | `[data-copied]` | Present when copied state is true | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseClipboardReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | trigger | | `[data-copied]` | Present when copied state is true | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to be copied to the clipboard when rendered. Use when you don't need to control the value of the clipboard. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; input: string; label: string }>` | No | The ids of the elements in the clipboard. Useful for composition. | | `modelValue` | `string` | No | The v-model value of the clipboard | | `timeout` | `number` | No | The timeout for the copy operation | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | root | | `[data-copied]` | Present when copied state is true | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | control | | `[data-copied]` | Present when copied state is true | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | input | | `[data-copied]` | Present when copied state is true | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | label | | `[data-copied]` | Present when copied state is true | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ClipboardApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | trigger | | `[data-copied]` | Present when copied state is true | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to be copied to the clipboard when rendered. Use when you don't need to control the value of the clipboard. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; input: string; label: string }>` | No | The ids of the elements in the clipboard. Useful for composition. | | `onStatusChange` | `(details: CopyStatusDetails) => void` | No | The function to be called when the value is copied to the clipboard | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The function to be called when the value changes | | `ref` | `Element` | No | | | `timeout` | `number` | No | The timeout for the copy operation | | `value` | `string` | No | The controlled value of the clipboard | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | root | | `[data-copied]` | Present when copied state is true | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseClipboardContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | control | | `[data-copied]` | Present when copied state is true | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `copied` | `Snippet<[]>` | No | | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | input | | `[data-copied]` | Present when copied state is true | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | label | | `[data-copied]` | Present when copied state is true | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseClipboardReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | trigger | | `[data-copied]` | Present when copied state is true | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `copied` | `boolean` | Whether the value has been copied to the clipboard | | `value` | `string` | The value to be copied to the clipboard | | `setValue` | `(value: string) => void` | Set the value to be copied to the clipboard | | `copy` | `VoidFunction` | Copy the value to the clipboard | --- # Clipboard (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import styles from 'styles/clipboard.module.css' export const Basic = () => { return ( Copy this link }> ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import styles from 'styles/clipboard.module.css' export const Basic = () => { return ( Copy this link }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Copy this link {#snippet copied()} {/snippet} ``` ### Controlled Control the clipboard value externally by managing the state yourself and using `onValueChange` to handle updates. **Example: controlled** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/clipboard.module.css' export const Controlled = () => { const [url, setUrl] = useState('https://ark-ui.com') return (
                    setUrl(details.value)}> Copy this link }>
                    ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/clipboard.module.css' export const Controlled = () => { const [url, setUrl] = createSignal('https://ark-ui.com') return (
                    setUrl(details.value)}> Copy this link }>
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Copy this link {#snippet copied()} {/snippet}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Clipboard, useClipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import styles from 'styles/clipboard.module.css' export const RootProvider = () => { const clipboard = useClipboard({ value: 'https://ark-ui.com' }) return (
                    value: {clipboard.value}, copied: {String(clipboard.copied)} Copy this link }>
                    ) } ``` #### Solid ```tsx import { Clipboard, useClipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import styles from 'styles/clipboard.module.css' export const RootProvider = () => { const clipboard = useClipboard({ value: 'https://ark-ui.com' }) return (
                    value: {clipboard().value}, copied: {String(clipboard().copied)} Copy this link }>
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    value: {clipboard().value}, copied: {String(clipboard().copied)} Copy this link {#snippet copied()} {/snippet}
                    ``` ### Context Access the clipboard state and methods using `Clipboard.Context`. This provides access to properties like `copied`, `value`, and `setValue` > Alternatively, you can use the `useClipboardContext` hook to access the clipboard context. **Example: context** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/clipboard.module.css' export const Context = () => { return ( Copy this link {(clipboard) => ( )} ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import { Show } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/clipboard.module.css' export const Context = () => { return ( Copy this link {(clipboard) => ( )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Copy this link {#snippet render(clipboard)} {/snippet} ``` ### 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. **Example: copy-status** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/clipboard.module.css' export const CopyStatus = () => { const [copyCount, setCopyCount] = useState(0) return ( { if (details.copied) setCopyCount((prev) => prev + 1) }} > }>

                    Copied {copyCount} times

                    ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/clipboard.module.css' export const CopyStatus = () => { const [copyCount, setCopyCount] = createSignal(0) return ( { if (details.copied) { setCopyCount((prev) => prev + 1) } }} > }>

                    Copied {copyCount()} times

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte { if (details.copied) { copyCount += 1 } }} > {#snippet copied()} {/snippet}

                    Copied {copyCount} times

                    ``` ### Timeout Configure the copy status timeout duration using the `timeout` prop. Default is 3000ms (3 seconds). **Example: timeout** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import styles from 'styles/clipboard.module.css' export const Timeout = () => { return ( Copy this link (5 second timeout) }> ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import styles from 'styles/clipboard.module.css' export const Timeout = () => { return ( Copy this link (5 second timeout) }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Copy this link (5 second timeout) {#snippet copied()} {/snippet} ``` ### Value Text Use `Clipboard.ValueText` to display the current clipboard value. **Example: value-text** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import styles from 'styles/clipboard.module.css' export const ValueText = () => { return ( }> ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import styles from 'styles/clipboard.module.css' export const ValueText = () => { return ( }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet copied()} {/snippet} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to be copied to the clipboard when rendered. Use when you don't need to control the value of the clipboard. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; input: string; label: string }>` | No | The ids of the elements in the clipboard. Useful for composition. | | `onStatusChange` | `(details: CopyStatusDetails) => void` | No | The function to be called when the value is copied to the clipboard | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The function to be called when the value changes | | `timeout` | `number` | No | The timeout for the copy operation | | `value` | `string` | No | The controlled value of the clipboard | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | root | | `[data-copied]` | Present when copied state is true | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | control | | `[data-copied]` | Present when copied state is true | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `copied` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | input | | `[data-copied]` | Present when copied state is true | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | label | | `[data-copied]` | Present when copied state is true | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseClipboardReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | trigger | | `[data-copied]` | Present when copied state is true | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to be copied to the clipboard when rendered. Use when you don't need to control the value of the clipboard. | | `ids` | `Partial<{ root: string; input: string; label: string }>` | No | The ids of the elements in the clipboard. Useful for composition. | | `onStatusChange` | `(details: CopyStatusDetails) => void` | No | The function to be called when the value is copied to the clipboard | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The function to be called when the value changes | | `timeout` | `number` | No | The timeout for the copy operation | | `value` | `string` | No | The controlled value of the clipboard | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | root | | `[data-copied]` | Present when copied state is true | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | control | | `[data-copied]` | Present when copied state is true | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `copied` | `number | boolean | Node | ArrayElement | (string & {})` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | input | | `[data-copied]` | Present when copied state is true | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | label | | `[data-copied]` | Present when copied state is true | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseClipboardReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | trigger | | `[data-copied]` | Present when copied state is true | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to be copied to the clipboard when rendered. Use when you don't need to control the value of the clipboard. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; input: string; label: string }>` | No | The ids of the elements in the clipboard. Useful for composition. | | `modelValue` | `string` | No | The v-model value of the clipboard | | `timeout` | `number` | No | The timeout for the copy operation | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | root | | `[data-copied]` | Present when copied state is true | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | control | | `[data-copied]` | Present when copied state is true | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | input | | `[data-copied]` | Present when copied state is true | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | label | | `[data-copied]` | Present when copied state is true | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ClipboardApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | trigger | | `[data-copied]` | Present when copied state is true | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to be copied to the clipboard when rendered. Use when you don't need to control the value of the clipboard. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; input: string; label: string }>` | No | The ids of the elements in the clipboard. Useful for composition. | | `onStatusChange` | `(details: CopyStatusDetails) => void` | No | The function to be called when the value is copied to the clipboard | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The function to be called when the value changes | | `ref` | `Element` | No | | | `timeout` | `number` | No | The timeout for the copy operation | | `value` | `string` | No | The controlled value of the clipboard | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | root | | `[data-copied]` | Present when copied state is true | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseClipboardContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | control | | `[data-copied]` | Present when copied state is true | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `copied` | `Snippet<[]>` | No | | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | input | | `[data-copied]` | Present when copied state is true | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | label | | `[data-copied]` | Present when copied state is true | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseClipboardReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | trigger | | `[data-copied]` | Present when copied state is true | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `copied` | `boolean` | Whether the value has been copied to the clipboard | | `value` | `string` | The value to be copied to the clipboard | | `setValue` | `(value: string) => void` | Set the value to be copied to the clipboard | | `copy` | `VoidFunction` | Copy the value to the clipboard | --- # Clipboard (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import styles from 'styles/clipboard.module.css' export const Basic = () => { return ( Copy this link }> ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import styles from 'styles/clipboard.module.css' export const Basic = () => { return ( Copy this link }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Copy this link {#snippet copied()} {/snippet} ``` ### Controlled Control the clipboard value externally by managing the state yourself and using `onValueChange` to handle updates. **Example: controlled** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/clipboard.module.css' export const Controlled = () => { const [url, setUrl] = useState('https://ark-ui.com') return (
                    setUrl(details.value)}> Copy this link }>
                    ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/clipboard.module.css' export const Controlled = () => { const [url, setUrl] = createSignal('https://ark-ui.com') return (
                    setUrl(details.value)}> Copy this link }>
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Copy this link {#snippet copied()} {/snippet}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Clipboard, useClipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import styles from 'styles/clipboard.module.css' export const RootProvider = () => { const clipboard = useClipboard({ value: 'https://ark-ui.com' }) return (
                    value: {clipboard.value}, copied: {String(clipboard.copied)} Copy this link }>
                    ) } ``` #### Solid ```tsx import { Clipboard, useClipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import styles from 'styles/clipboard.module.css' export const RootProvider = () => { const clipboard = useClipboard({ value: 'https://ark-ui.com' }) return (
                    value: {clipboard().value}, copied: {String(clipboard().copied)} Copy this link }>
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    value: {clipboard().value}, copied: {String(clipboard().copied)} Copy this link {#snippet copied()} {/snippet}
                    ``` ### Context Access the clipboard state and methods using `Clipboard.Context`. This provides access to properties like `copied`, `value`, and `setValue` > Alternatively, you can use the `useClipboardContext` hook to access the clipboard context. **Example: context** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/clipboard.module.css' export const Context = () => { return ( Copy this link {(clipboard) => ( )} ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import { Show } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/clipboard.module.css' export const Context = () => { return ( Copy this link {(clipboard) => ( )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Copy this link {#snippet render(clipboard)} {/snippet} ``` ### 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. **Example: copy-status** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/clipboard.module.css' export const CopyStatus = () => { const [copyCount, setCopyCount] = useState(0) return ( { if (details.copied) setCopyCount((prev) => prev + 1) }} > }>

                    Copied {copyCount} times

                    ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/clipboard.module.css' export const CopyStatus = () => { const [copyCount, setCopyCount] = createSignal(0) return ( { if (details.copied) { setCopyCount((prev) => prev + 1) } }} > }>

                    Copied {copyCount()} times

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte { if (details.copied) { copyCount += 1 } }} > {#snippet copied()} {/snippet}

                    Copied {copyCount} times

                    ``` ### Timeout Configure the copy status timeout duration using the `timeout` prop. Default is 3000ms (3 seconds). **Example: timeout** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import styles from 'styles/clipboard.module.css' export const Timeout = () => { return ( Copy this link (5 second timeout) }> ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import styles from 'styles/clipboard.module.css' export const Timeout = () => { return ( Copy this link (5 second timeout) }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Copy this link (5 second timeout) {#snippet copied()} {/snippet} ``` ### Value Text Use `Clipboard.ValueText` to display the current clipboard value. **Example: value-text** #### React ```tsx import { Clipboard } from '@ark-ui/react/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-react' import styles from 'styles/clipboard.module.css' export const ValueText = () => { return ( }> ) } ``` #### Solid ```tsx import { Clipboard } from '@ark-ui/solid/clipboard' import { CheckIcon, ClipboardCopyIcon } from 'lucide-solid' import styles from 'styles/clipboard.module.css' export const ValueText = () => { return ( }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet copied()} {/snippet} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to be copied to the clipboard when rendered. Use when you don't need to control the value of the clipboard. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; input: string; label: string }>` | No | The ids of the elements in the clipboard. Useful for composition. | | `onStatusChange` | `(details: CopyStatusDetails) => void` | No | The function to be called when the value is copied to the clipboard | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The function to be called when the value changes | | `timeout` | `number` | No | The timeout for the copy operation | | `value` | `string` | No | The controlled value of the clipboard | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | root | | `[data-copied]` | Present when copied state is true | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | control | | `[data-copied]` | Present when copied state is true | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `copied` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | input | | `[data-copied]` | Present when copied state is true | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | label | | `[data-copied]` | Present when copied state is true | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseClipboardReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | trigger | | `[data-copied]` | Present when copied state is true | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to be copied to the clipboard when rendered. Use when you don't need to control the value of the clipboard. | | `ids` | `Partial<{ root: string; input: string; label: string }>` | No | The ids of the elements in the clipboard. Useful for composition. | | `onStatusChange` | `(details: CopyStatusDetails) => void` | No | The function to be called when the value is copied to the clipboard | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The function to be called when the value changes | | `timeout` | `number` | No | The timeout for the copy operation | | `value` | `string` | No | The controlled value of the clipboard | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | root | | `[data-copied]` | Present when copied state is true | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | control | | `[data-copied]` | Present when copied state is true | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `copied` | `number | boolean | Node | ArrayElement | (string & {})` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | input | | `[data-copied]` | Present when copied state is true | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | label | | `[data-copied]` | Present when copied state is true | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseClipboardReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | trigger | | `[data-copied]` | Present when copied state is true | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to be copied to the clipboard when rendered. Use when you don't need to control the value of the clipboard. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; input: string; label: string }>` | No | The ids of the elements in the clipboard. Useful for composition. | | `modelValue` | `string` | No | The v-model value of the clipboard | | `timeout` | `number` | No | The timeout for the copy operation | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | root | | `[data-copied]` | Present when copied state is true | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | control | | `[data-copied]` | Present when copied state is true | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | input | | `[data-copied]` | Present when copied state is true | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | label | | `[data-copied]` | Present when copied state is true | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ClipboardApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | trigger | | `[data-copied]` | Present when copied state is true | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to be copied to the clipboard when rendered. Use when you don't need to control the value of the clipboard. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; input: string; label: string }>` | No | The ids of the elements in the clipboard. Useful for composition. | | `onStatusChange` | `(details: CopyStatusDetails) => void` | No | The function to be called when the value is copied to the clipboard | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The function to be called when the value changes | | `ref` | `Element` | No | | | `timeout` | `number` | No | The timeout for the copy operation | | `value` | `string` | No | The controlled value of the clipboard | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | root | | `[data-copied]` | Present when copied state is true | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseClipboardContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | control | | `[data-copied]` | Present when copied state is true | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `copied` | `Snippet<[]>` | No | | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | input | | `[data-copied]` | Present when copied state is true | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | label | | `[data-copied]` | Present when copied state is true | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseClipboardReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | clipboard | | `[data-part]` | trigger | | `[data-copied]` | Present when copied state is true | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `copied` | `boolean` | Whether the value has been copied to the clipboard | | `value` | `string` | The value to be copied to the clipboard | | `setValue` | `(value: string) => void` | Set the value to be copied to the clipboard | | `copy` | `VoidFunction` | Copy the value to the clipboard | --- # Collapsible (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const Basic = () => ( What is Ark UI?
                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte.
                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const Basic = () => ( What is Ark UI?
                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte What is Ark UI?
                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte.
                    ``` ### Disabled Use the `disabled` prop to disable the collapsible and prevent it from being toggled. **Example: disabled** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const Disabled = () => ( System Requirements
                    This section is currently unavailable.
                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const Disabled = () => ( System Requirements
                    This section is currently unavailable.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte System Requirements
                    This section is currently unavailable.
                    ``` ### 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. **Example: partial-collapse** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const PartialCollapse = () => ( Read More

                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte. It provides unstyled, fully accessible components that you can customize to match your design system.

                    Built on top of Zag.js state machines, Ark UI ensures consistent behavior across all frameworks while giving you complete control over styling. Each component follows WAI-ARIA patterns for accessibility out of the box.

                    Whether you're building a design system from scratch or need reliable primitives for your next project, Ark UI provides the foundation you need without imposing any visual constraints.

                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const PartialCollapse = () => ( Read More

                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte. It provides unstyled, fully accessible components that you can customize to match your design system.

                    Built on top of Zag.js state machines, Ark UI ensures consistent behavior across all frameworks while giving you complete control over styling. Each component follows WAI-ARIA patterns for accessibility out of the box.

                    Whether you're building a design system from scratch or need reliable primitives for your next project, Ark UI provides the foundation you need without imposing any visual constraints.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Read More

                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte. It provides unstyled, fully accessible components that you can customize to match your design system.

                    Built on top of Zag.js state machines, Ark UI ensures consistent behavior across all frameworks while giving you complete control over styling. Each component follows WAI-ARIA patterns for accessibility out of the box.

                    Whether you're building a design system from scratch or need reliable primitives for your next project, Ark UI provides the foundation you need without imposing any visual constraints.

                    ``` > Interactive elements (links, buttons, inputs) within the collapsed area automatically become `inert` to prevent > keyboard navigation to hidden content. ### Nested Collapsibles You can nest collapsibles within collapsibles to create hierarchical content structures. **Example: nested** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const Nested = () => ( Getting Started

                    Welcome to the Ark UI documentation. Here are some topics to explore:

                    Installation

                    Install Ark UI using your preferred package manager:

                    npm install @ark-ui/react
                    Styling

                    Ark UI components are unstyled by default. Use CSS modules, Tailwind, or any styling solution.

                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const Nested = () => ( Getting Started

                    Welcome to the Ark UI documentation. Here are some topics to explore:

                    Installation

                    Install Ark UI using your preferred package manager:

                    npm install @ark-ui/solid
                    Styling

                    Ark UI components are unstyled by default. Use CSS modules, Tailwind, or any styling solution.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Getting Started

                    Welcome to the Ark UI documentation. Here are some topics to explore:

                    Installation

                    Install Ark UI using your preferred package manager:

                    npm install @ark-ui/svelte
                    Styling

                    Ark UI components are unstyled by default. Use CSS modules, Tailwind, or any styling solution.

                    ``` ### 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. **Example: lazy-mount** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const LazyMount = () => ( Session Details
                    This content is lazily mounted when first opened and removed from the DOM when collapsed.
                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const LazyMount = () => ( Session Details
                    This content is lazily mounted when first opened and removed from the DOM when collapsed.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Session Details
                    This content is lazily mounted when first opened and removed from the DOM when collapsed.
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Collapsible, useCollapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const RootProvider = () => { const collapsible = useCollapsible() return (
                    collapsible: {String(collapsible.open)}, visible: {String(collapsible.visible)} Toggle Panel
                    This panel can be toggled by the button above, which uses the useCollapsible hook for state management.
                    ) } ``` #### Solid ```tsx import { Collapsible, useCollapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const RootProvider = () => { const collapsible = useCollapsible() return (
                    open: {String(collapsible().open)}, visible: {String(collapsible().visible)} Toggle Panel
                    This panel can be toggled by the button above, which uses the useCollapsible hook for state management.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    open: {String(collapsible().open)}, visible: {String(collapsible().visible)} Toggle Panel
                    This panel can be toggled by the button above, which uses the useCollapsible hook for state management.
                    ``` ## Guides ### Indicator Animation To rotate the indicator icon (such as a chevron) when the collapsible opens and closes, use CSS transforms with the `data-state` attribute: ```css [data-scope='collapsible'][data-part='indicator'] { transition: transform 200ms; &[data-state='open'] { transform: rotate(180deg); } } ``` ### Open vs Visible When using `useCollapsible` or `useCollapsibleContext`, you can access the `open` and `visible` state properties. They seem similar but serve different purposes: - **`open`**: Indicates the intended state of the collapsible. This is `true` when the collapsible should be expanded and `false` when it should be collapsed. This changes immediately when triggered. - **`visible`**: Indicates whether the content is currently visible in the DOM. This accounts for exit animations - the content remains `visible` while the closing animation plays, even though `open` is already `false`. Once the animation completes, `visible` becomes `false`. ### Content Animation Use the `--height` and/or `--width` CSS variables to animate the size of the content when it expands or closes. If you use `collapsedHeight` or `collapsedWidth`, update your CSS animations to use the `--collapsed-height` or `--collapsed-width` variables as the starting/ending point: ```css @keyframes expand { from { height: var(--collapsed-height, 0); } to { height: var(--height); } } @keyframes collapse { from { height: var(--height); } to { height: var(--collapsed-height, 0); } } [data-scope='collapsible'][data-part='content'] { &[data-state='open'] { animation: expand 250ms; } &[data-state='closed'] { animation: collapse 250ms; } } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered. Use when you don't need to control the open state of the collapsible. | | `disabled` | `boolean` | No | Whether the collapsible is disabled. | | `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | The callback invoked when the exit animation completes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | The callback invoked when the open state changes. | | `open` | `boolean` | No | The controlled open state of the collapsible. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | content | | `[data-collapsible]` | | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCollapsibleReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered. Use when you don't need to control the open state of the collapsible. | | `disabled` | `boolean` | No | Whether the collapsible is disabled. | | `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | The callback invoked when the exit animation completes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | The callback invoked when the open state changes. | | `open` | `boolean` | No | The controlled open state of the collapsible. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | content | | `[data-collapsible]` | | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCollapsibleReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered. Use when you don't need to control the open state of the collapsible. | | `disabled` | `boolean` | No | Whether the collapsible is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `open` | `boolean` | No | The controlled open state of the collapsible. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | content | | `[data-collapsible]` | | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `Collapsible` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered. Use when you don't need to control the open state of the collapsible. | | `disabled` | `boolean` | No | Whether the collapsible is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. | | `lazyMount` | `boolean` | No | Whether the content should be lazy mounted | | `onExitComplete` | `() => void` | No | Callback fired when the animation ends | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | The callback invoked when the open state changes. | | `open` | `boolean` | No | The controlled open state of the collapsible. | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether the content should be unmounted when collapsed | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | content | | `[data-collapsible]` | | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseCollapsibleContext]>` | No | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCollapsibleReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the collapsible is open. | | `visible` | `boolean` | Whether the collapsible is visible (open or closing) | | `disabled` | `boolean` | Whether the collapsible is disabled | | `setOpen` | `(open: boolean) => void` | Function to open or close the collapsible. | | `measureSize` | `VoidFunction` | Function to measure the size of the content. | ## Accessibility ### Keyboard Support **`Space`** Description: Opens/closes the collapsible. **`Enter`** Description: Opens/closes the collapsible. --- # Collapsible (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const Basic = () => ( What is Ark UI?
                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte.
                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const Basic = () => ( What is Ark UI?
                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte What is Ark UI?
                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte.
                    ``` ### Disabled Use the `disabled` prop to disable the collapsible and prevent it from being toggled. **Example: disabled** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const Disabled = () => ( System Requirements
                    This section is currently unavailable.
                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const Disabled = () => ( System Requirements
                    This section is currently unavailable.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte System Requirements
                    This section is currently unavailable.
                    ``` ### 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. **Example: partial-collapse** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const PartialCollapse = () => ( Read More

                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte. It provides unstyled, fully accessible components that you can customize to match your design system.

                    Built on top of Zag.js state machines, Ark UI ensures consistent behavior across all frameworks while giving you complete control over styling. Each component follows WAI-ARIA patterns for accessibility out of the box.

                    Whether you're building a design system from scratch or need reliable primitives for your next project, Ark UI provides the foundation you need without imposing any visual constraints.

                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const PartialCollapse = () => ( Read More

                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte. It provides unstyled, fully accessible components that you can customize to match your design system.

                    Built on top of Zag.js state machines, Ark UI ensures consistent behavior across all frameworks while giving you complete control over styling. Each component follows WAI-ARIA patterns for accessibility out of the box.

                    Whether you're building a design system from scratch or need reliable primitives for your next project, Ark UI provides the foundation you need without imposing any visual constraints.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Read More

                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte. It provides unstyled, fully accessible components that you can customize to match your design system.

                    Built on top of Zag.js state machines, Ark UI ensures consistent behavior across all frameworks while giving you complete control over styling. Each component follows WAI-ARIA patterns for accessibility out of the box.

                    Whether you're building a design system from scratch or need reliable primitives for your next project, Ark UI provides the foundation you need without imposing any visual constraints.

                    ``` > Interactive elements (links, buttons, inputs) within the collapsed area automatically become `inert` to prevent > keyboard navigation to hidden content. ### Nested Collapsibles You can nest collapsibles within collapsibles to create hierarchical content structures. **Example: nested** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const Nested = () => ( Getting Started

                    Welcome to the Ark UI documentation. Here are some topics to explore:

                    Installation

                    Install Ark UI using your preferred package manager:

                    npm install @ark-ui/react
                    Styling

                    Ark UI components are unstyled by default. Use CSS modules, Tailwind, or any styling solution.

                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const Nested = () => ( Getting Started

                    Welcome to the Ark UI documentation. Here are some topics to explore:

                    Installation

                    Install Ark UI using your preferred package manager:

                    npm install @ark-ui/solid
                    Styling

                    Ark UI components are unstyled by default. Use CSS modules, Tailwind, or any styling solution.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Getting Started

                    Welcome to the Ark UI documentation. Here are some topics to explore:

                    Installation

                    Install Ark UI using your preferred package manager:

                    npm install @ark-ui/svelte
                    Styling

                    Ark UI components are unstyled by default. Use CSS modules, Tailwind, or any styling solution.

                    ``` ### 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. **Example: lazy-mount** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const LazyMount = () => ( Session Details
                    This content is lazily mounted when first opened and removed from the DOM when collapsed.
                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const LazyMount = () => ( Session Details
                    This content is lazily mounted when first opened and removed from the DOM when collapsed.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Session Details
                    This content is lazily mounted when first opened and removed from the DOM when collapsed.
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Collapsible, useCollapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const RootProvider = () => { const collapsible = useCollapsible() return (
                    collapsible: {String(collapsible.open)}, visible: {String(collapsible.visible)} Toggle Panel
                    This panel can be toggled by the button above, which uses the useCollapsible hook for state management.
                    ) } ``` #### Solid ```tsx import { Collapsible, useCollapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const RootProvider = () => { const collapsible = useCollapsible() return (
                    open: {String(collapsible().open)}, visible: {String(collapsible().visible)} Toggle Panel
                    This panel can be toggled by the button above, which uses the useCollapsible hook for state management.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    open: {String(collapsible().open)}, visible: {String(collapsible().visible)} Toggle Panel
                    This panel can be toggled by the button above, which uses the useCollapsible hook for state management.
                    ``` ## Guides ### Indicator Animation To rotate the indicator icon (such as a chevron) when the collapsible opens and closes, use CSS transforms with the `data-state` attribute: ```css [data-scope='collapsible'][data-part='indicator'] { transition: transform 200ms; &[data-state='open'] { transform: rotate(180deg); } } ``` ### Open vs Visible When using `useCollapsible` or `useCollapsibleContext`, you can access the `open` and `visible` state properties. They seem similar but serve different purposes: - **`open`**: Indicates the intended state of the collapsible. This is `true` when the collapsible should be expanded and `false` when it should be collapsed. This changes immediately when triggered. - **`visible`**: Indicates whether the content is currently visible in the DOM. This accounts for exit animations - the content remains `visible` while the closing animation plays, even though `open` is already `false`. Once the animation completes, `visible` becomes `false`. ### Content Animation Use the `--height` and/or `--width` CSS variables to animate the size of the content when it expands or closes. If you use `collapsedHeight` or `collapsedWidth`, update your CSS animations to use the `--collapsed-height` or `--collapsed-width` variables as the starting/ending point: ```css @keyframes expand { from { height: var(--collapsed-height, 0); } to { height: var(--height); } } @keyframes collapse { from { height: var(--height); } to { height: var(--collapsed-height, 0); } } [data-scope='collapsible'][data-part='content'] { &[data-state='open'] { animation: expand 250ms; } &[data-state='closed'] { animation: collapse 250ms; } } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered. Use when you don't need to control the open state of the collapsible. | | `disabled` | `boolean` | No | Whether the collapsible is disabled. | | `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | The callback invoked when the exit animation completes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | The callback invoked when the open state changes. | | `open` | `boolean` | No | The controlled open state of the collapsible. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | content | | `[data-collapsible]` | | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCollapsibleReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered. Use when you don't need to control the open state of the collapsible. | | `disabled` | `boolean` | No | Whether the collapsible is disabled. | | `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | The callback invoked when the exit animation completes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | The callback invoked when the open state changes. | | `open` | `boolean` | No | The controlled open state of the collapsible. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | content | | `[data-collapsible]` | | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCollapsibleReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered. Use when you don't need to control the open state of the collapsible. | | `disabled` | `boolean` | No | Whether the collapsible is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `open` | `boolean` | No | The controlled open state of the collapsible. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | content | | `[data-collapsible]` | | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `Collapsible` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered. Use when you don't need to control the open state of the collapsible. | | `disabled` | `boolean` | No | Whether the collapsible is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. | | `lazyMount` | `boolean` | No | Whether the content should be lazy mounted | | `onExitComplete` | `() => void` | No | Callback fired when the animation ends | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | The callback invoked when the open state changes. | | `open` | `boolean` | No | The controlled open state of the collapsible. | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether the content should be unmounted when collapsed | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | content | | `[data-collapsible]` | | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseCollapsibleContext]>` | No | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCollapsibleReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the collapsible is open. | | `visible` | `boolean` | Whether the collapsible is visible (open or closing) | | `disabled` | `boolean` | Whether the collapsible is disabled | | `setOpen` | `(open: boolean) => void` | Function to open or close the collapsible. | | `measureSize` | `VoidFunction` | Function to measure the size of the content. | ## Accessibility ### Keyboard Support **`Space`** Description: Opens/closes the collapsible. **`Enter`** Description: Opens/closes the collapsible. --- # Collapsible (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const Basic = () => ( What is Ark UI?
                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte.
                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const Basic = () => ( What is Ark UI?
                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte What is Ark UI?
                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte.
                    ``` ### Disabled Use the `disabled` prop to disable the collapsible and prevent it from being toggled. **Example: disabled** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const Disabled = () => ( System Requirements
                    This section is currently unavailable.
                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const Disabled = () => ( System Requirements
                    This section is currently unavailable.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte System Requirements
                    This section is currently unavailable.
                    ``` ### 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. **Example: partial-collapse** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const PartialCollapse = () => ( Read More

                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte. It provides unstyled, fully accessible components that you can customize to match your design system.

                    Built on top of Zag.js state machines, Ark UI ensures consistent behavior across all frameworks while giving you complete control over styling. Each component follows WAI-ARIA patterns for accessibility out of the box.

                    Whether you're building a design system from scratch or need reliable primitives for your next project, Ark UI provides the foundation you need without imposing any visual constraints.

                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const PartialCollapse = () => ( Read More

                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte. It provides unstyled, fully accessible components that you can customize to match your design system.

                    Built on top of Zag.js state machines, Ark UI ensures consistent behavior across all frameworks while giving you complete control over styling. Each component follows WAI-ARIA patterns for accessibility out of the box.

                    Whether you're building a design system from scratch or need reliable primitives for your next project, Ark UI provides the foundation you need without imposing any visual constraints.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Read More

                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte. It provides unstyled, fully accessible components that you can customize to match your design system.

                    Built on top of Zag.js state machines, Ark UI ensures consistent behavior across all frameworks while giving you complete control over styling. Each component follows WAI-ARIA patterns for accessibility out of the box.

                    Whether you're building a design system from scratch or need reliable primitives for your next project, Ark UI provides the foundation you need without imposing any visual constraints.

                    ``` > Interactive elements (links, buttons, inputs) within the collapsed area automatically become `inert` to prevent > keyboard navigation to hidden content. ### Nested Collapsibles You can nest collapsibles within collapsibles to create hierarchical content structures. **Example: nested** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const Nested = () => ( Getting Started

                    Welcome to the Ark UI documentation. Here are some topics to explore:

                    Installation

                    Install Ark UI using your preferred package manager:

                    npm install @ark-ui/react
                    Styling

                    Ark UI components are unstyled by default. Use CSS modules, Tailwind, or any styling solution.

                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const Nested = () => ( Getting Started

                    Welcome to the Ark UI documentation. Here are some topics to explore:

                    Installation

                    Install Ark UI using your preferred package manager:

                    npm install @ark-ui/solid
                    Styling

                    Ark UI components are unstyled by default. Use CSS modules, Tailwind, or any styling solution.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Getting Started

                    Welcome to the Ark UI documentation. Here are some topics to explore:

                    Installation

                    Install Ark UI using your preferred package manager:

                    npm install @ark-ui/svelte
                    Styling

                    Ark UI components are unstyled by default. Use CSS modules, Tailwind, or any styling solution.

                    ``` ### 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. **Example: lazy-mount** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const LazyMount = () => ( Session Details
                    This content is lazily mounted when first opened and removed from the DOM when collapsed.
                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const LazyMount = () => ( Session Details
                    This content is lazily mounted when first opened and removed from the DOM when collapsed.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Session Details
                    This content is lazily mounted when first opened and removed from the DOM when collapsed.
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Collapsible, useCollapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const RootProvider = () => { const collapsible = useCollapsible() return (
                    collapsible: {String(collapsible.open)}, visible: {String(collapsible.visible)} Toggle Panel
                    This panel can be toggled by the button above, which uses the useCollapsible hook for state management.
                    ) } ``` #### Solid ```tsx import { Collapsible, useCollapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const RootProvider = () => { const collapsible = useCollapsible() return (
                    open: {String(collapsible().open)}, visible: {String(collapsible().visible)} Toggle Panel
                    This panel can be toggled by the button above, which uses the useCollapsible hook for state management.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    open: {String(collapsible().open)}, visible: {String(collapsible().visible)} Toggle Panel
                    This panel can be toggled by the button above, which uses the useCollapsible hook for state management.
                    ``` ## Guides ### Indicator Animation To rotate the indicator icon (such as a chevron) when the collapsible opens and closes, use CSS transforms with the `data-state` attribute: ```css [data-scope='collapsible'][data-part='indicator'] { transition: transform 200ms; &[data-state='open'] { transform: rotate(180deg); } } ``` ### Open vs Visible When using `useCollapsible` or `useCollapsibleContext`, you can access the `open` and `visible` state properties. They seem similar but serve different purposes: - **`open`**: Indicates the intended state of the collapsible. This is `true` when the collapsible should be expanded and `false` when it should be collapsed. This changes immediately when triggered. - **`visible`**: Indicates whether the content is currently visible in the DOM. This accounts for exit animations - the content remains `visible` while the closing animation plays, even though `open` is already `false`. Once the animation completes, `visible` becomes `false`. ### Content Animation Use the `--height` and/or `--width` CSS variables to animate the size of the content when it expands or closes. If you use `collapsedHeight` or `collapsedWidth`, update your CSS animations to use the `--collapsed-height` or `--collapsed-width` variables as the starting/ending point: ```css @keyframes expand { from { height: var(--collapsed-height, 0); } to { height: var(--height); } } @keyframes collapse { from { height: var(--height); } to { height: var(--collapsed-height, 0); } } [data-scope='collapsible'][data-part='content'] { &[data-state='open'] { animation: expand 250ms; } &[data-state='closed'] { animation: collapse 250ms; } } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered. Use when you don't need to control the open state of the collapsible. | | `disabled` | `boolean` | No | Whether the collapsible is disabled. | | `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | The callback invoked when the exit animation completes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | The callback invoked when the open state changes. | | `open` | `boolean` | No | The controlled open state of the collapsible. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | content | | `[data-collapsible]` | | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCollapsibleReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered. Use when you don't need to control the open state of the collapsible. | | `disabled` | `boolean` | No | Whether the collapsible is disabled. | | `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | The callback invoked when the exit animation completes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | The callback invoked when the open state changes. | | `open` | `boolean` | No | The controlled open state of the collapsible. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | content | | `[data-collapsible]` | | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCollapsibleReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered. Use when you don't need to control the open state of the collapsible. | | `disabled` | `boolean` | No | Whether the collapsible is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `open` | `boolean` | No | The controlled open state of the collapsible. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | content | | `[data-collapsible]` | | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `Collapsible` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered. Use when you don't need to control the open state of the collapsible. | | `disabled` | `boolean` | No | Whether the collapsible is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. | | `lazyMount` | `boolean` | No | Whether the content should be lazy mounted | | `onExitComplete` | `() => void` | No | Callback fired when the animation ends | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | The callback invoked when the open state changes. | | `open` | `boolean` | No | The controlled open state of the collapsible. | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether the content should be unmounted when collapsed | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | content | | `[data-collapsible]` | | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseCollapsibleContext]>` | No | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCollapsibleReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the collapsible is open. | | `visible` | `boolean` | Whether the collapsible is visible (open or closing) | | `disabled` | `boolean` | Whether the collapsible is disabled | | `setOpen` | `(open: boolean) => void` | Function to open or close the collapsible. | | `measureSize` | `VoidFunction` | Function to measure the size of the content. | ## Accessibility ### Keyboard Support **`Space`** Description: Opens/closes the collapsible. **`Enter`** Description: Opens/closes the collapsible. --- # Collapsible (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const Basic = () => ( What is Ark UI?
                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte.
                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const Basic = () => ( What is Ark UI?
                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte What is Ark UI?
                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte.
                    ``` ### Disabled Use the `disabled` prop to disable the collapsible and prevent it from being toggled. **Example: disabled** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const Disabled = () => ( System Requirements
                    This section is currently unavailable.
                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const Disabled = () => ( System Requirements
                    This section is currently unavailable.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte System Requirements
                    This section is currently unavailable.
                    ``` ### 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. **Example: partial-collapse** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const PartialCollapse = () => ( Read More

                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte. It provides unstyled, fully accessible components that you can customize to match your design system.

                    Built on top of Zag.js state machines, Ark UI ensures consistent behavior across all frameworks while giving you complete control over styling. Each component follows WAI-ARIA patterns for accessibility out of the box.

                    Whether you're building a design system from scratch or need reliable primitives for your next project, Ark UI provides the foundation you need without imposing any visual constraints.

                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const PartialCollapse = () => ( Read More

                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte. It provides unstyled, fully accessible components that you can customize to match your design system.

                    Built on top of Zag.js state machines, Ark UI ensures consistent behavior across all frameworks while giving you complete control over styling. Each component follows WAI-ARIA patterns for accessibility out of the box.

                    Whether you're building a design system from scratch or need reliable primitives for your next project, Ark UI provides the foundation you need without imposing any visual constraints.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Read More

                    Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte. It provides unstyled, fully accessible components that you can customize to match your design system.

                    Built on top of Zag.js state machines, Ark UI ensures consistent behavior across all frameworks while giving you complete control over styling. Each component follows WAI-ARIA patterns for accessibility out of the box.

                    Whether you're building a design system from scratch or need reliable primitives for your next project, Ark UI provides the foundation you need without imposing any visual constraints.

                    ``` > Interactive elements (links, buttons, inputs) within the collapsed area automatically become `inert` to prevent > keyboard navigation to hidden content. ### Nested Collapsibles You can nest collapsibles within collapsibles to create hierarchical content structures. **Example: nested** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const Nested = () => ( Getting Started

                    Welcome to the Ark UI documentation. Here are some topics to explore:

                    Installation

                    Install Ark UI using your preferred package manager:

                    npm install @ark-ui/react
                    Styling

                    Ark UI components are unstyled by default. Use CSS modules, Tailwind, or any styling solution.

                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const Nested = () => ( Getting Started

                    Welcome to the Ark UI documentation. Here are some topics to explore:

                    Installation

                    Install Ark UI using your preferred package manager:

                    npm install @ark-ui/solid
                    Styling

                    Ark UI components are unstyled by default. Use CSS modules, Tailwind, or any styling solution.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Getting Started

                    Welcome to the Ark UI documentation. Here are some topics to explore:

                    Installation

                    Install Ark UI using your preferred package manager:

                    npm install @ark-ui/svelte
                    Styling

                    Ark UI components are unstyled by default. Use CSS modules, Tailwind, or any styling solution.

                    ``` ### 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. **Example: lazy-mount** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const LazyMount = () => ( Session Details
                    This content is lazily mounted when first opened and removed from the DOM when collapsed.
                    ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const LazyMount = () => ( Session Details
                    This content is lazily mounted when first opened and removed from the DOM when collapsed.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Session Details
                    This content is lazily mounted when first opened and removed from the DOM when collapsed.
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Collapsible, useCollapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const RootProvider = () => { const collapsible = useCollapsible() return (
                    collapsible: {String(collapsible.open)}, visible: {String(collapsible.visible)} Toggle Panel
                    This panel can be toggled by the button above, which uses the useCollapsible hook for state management.
                    ) } ``` #### Solid ```tsx import { Collapsible, useCollapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const RootProvider = () => { const collapsible = useCollapsible() return (
                    open: {String(collapsible().open)}, visible: {String(collapsible().visible)} Toggle Panel
                    This panel can be toggled by the button above, which uses the useCollapsible hook for state management.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    open: {String(collapsible().open)}, visible: {String(collapsible().visible)} Toggle Panel
                    This panel can be toggled by the button above, which uses the useCollapsible hook for state management.
                    ``` ## Guides ### Indicator Animation To rotate the indicator icon (such as a chevron) when the collapsible opens and closes, use CSS transforms with the `data-state` attribute: ```css [data-scope='collapsible'][data-part='indicator'] { transition: transform 200ms; &[data-state='open'] { transform: rotate(180deg); } } ``` ### Open vs Visible When using `useCollapsible` or `useCollapsibleContext`, you can access the `open` and `visible` state properties. They seem similar but serve different purposes: - **`open`**: Indicates the intended state of the collapsible. This is `true` when the collapsible should be expanded and `false` when it should be collapsed. This changes immediately when triggered. - **`visible`**: Indicates whether the content is currently visible in the DOM. This accounts for exit animations - the content remains `visible` while the closing animation plays, even though `open` is already `false`. Once the animation completes, `visible` becomes `false`. ### Content Animation Use the `--height` and/or `--width` CSS variables to animate the size of the content when it expands or closes. If you use `collapsedHeight` or `collapsedWidth`, update your CSS animations to use the `--collapsed-height` or `--collapsed-width` variables as the starting/ending point: ```css @keyframes expand { from { height: var(--collapsed-height, 0); } to { height: var(--height); } } @keyframes collapse { from { height: var(--height); } to { height: var(--collapsed-height, 0); } } [data-scope='collapsible'][data-part='content'] { &[data-state='open'] { animation: expand 250ms; } &[data-state='closed'] { animation: collapse 250ms; } } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered. Use when you don't need to control the open state of the collapsible. | | `disabled` | `boolean` | No | Whether the collapsible is disabled. | | `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | The callback invoked when the exit animation completes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | The callback invoked when the open state changes. | | `open` | `boolean` | No | The controlled open state of the collapsible. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | content | | `[data-collapsible]` | | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCollapsibleReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered. Use when you don't need to control the open state of the collapsible. | | `disabled` | `boolean` | No | Whether the collapsible is disabled. | | `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | The callback invoked when the exit animation completes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | The callback invoked when the open state changes. | | `open` | `boolean` | No | The controlled open state of the collapsible. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | content | | `[data-collapsible]` | | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCollapsibleReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered. Use when you don't need to control the open state of the collapsible. | | `disabled` | `boolean` | No | Whether the collapsible is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `open` | `boolean` | No | The controlled open state of the collapsible. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | content | | `[data-collapsible]` | | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `Collapsible` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered. Use when you don't need to control the open state of the collapsible. | | `disabled` | `boolean` | No | Whether the collapsible is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. | | `lazyMount` | `boolean` | No | Whether the content should be lazy mounted | | `onExitComplete` | `() => void` | No | Callback fired when the animation ends | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | The callback invoked when the open state changes. | | `open` | `boolean` | No | The controlled open state of the collapsible. | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether the content should be unmounted when collapsed | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | content | | `[data-collapsible]` | | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseCollapsibleContext]>` | No | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseCollapsibleReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | collapsible | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the collapsible is open. | | `visible` | `boolean` | Whether the collapsible is visible (open or closing) | | `disabled` | `boolean` | Whether the collapsible is disabled | | `setOpen` | `(open: boolean) => void` | Function to open or close the collapsible. | | `measureSize` | `VoidFunction` | Function to measure the size of the content. | ## Accessibility ### Keyboard Support **`Space`** Description: Opens/closes the collapsible. **`Enter`** Description: Opens/closes the collapsible. --- # Color Picker (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' export const Basic = () => { return ( Color
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Pipette } from 'lucide-solid' import styles from 'styles/color-picker.module.css' export const Basic = () => { return ( Color
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Color
                    ``` ### Controlled Use the `value` and `onValueChange` props to programatically control the color picker's state. **Example: controlled** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/color-picker.module.css' export const Controlled = () => { const [color, setColor] = useState(() => parseColor('hsl(20, 100%, 50%)')) return (
                    Selected color: {color.toString('hex')} setColor(e.value)}> Color
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Pipette } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/color-picker.module.css' export const Controlled = () => { const [color, setColor] = createSignal(parseColor('hsl(20, 100%, 50%)')) return (
                    Selected color: {color().toString('hex')} setColor(e.value)}> Color
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Selected color: {value.toString('hex')} Color
                    ``` ### Open Controlled Control the open state of the color picker popover programmatically using the `open` and `onOpenChange` props. **Example: open-controlled** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/color-picker.module.css' export const OpenControlled = () => { const [open, setOpen] = useState(false) return (
                    setOpen(e.open)} defaultValue={parseColor('#eb5e41')} > Color
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Pipette } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/color-picker.module.css' export const OpenControlled = () => { const [open, setOpen] = createSignal(false) return (
                    setOpen(e.open)} defaultValue={parseColor('#eb5e41')} > Color
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Color
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { ColorPicker, parseColor, useColorPicker } from '@ark-ui/react/color-picker' import { CheckIcon, PipetteIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const RootProvider = () => { const colorPicker = useColorPicker({ defaultValue: parseColor('#eb5e41') }) return (
                    Color: {colorPicker.valueAsString} Color
                    {swatches.map((color) => ( ))}
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor, useColorPicker } from '@ark-ui/solid/color-picker' import { Check, Pipette } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const RootProvider = () => { const colorPicker = useColorPicker({ defaultValue: parseColor('#eb5e41') }) return (
                    Color: {colorPicker().valueAsString} Color
                    {(color) => ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Color: {colorPicker().valueAsString} Color
                    {#each swatches as color} {/each}
                    ``` ### Disabled Use the `disabled` prop to disable the color picker. **Example: disabled** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import styles from 'styles/color-picker.module.css' export const Disabled = () => { return ( Color
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import styles from 'styles/color-picker.module.css' export const Disabled = () => { return ( Color
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Color
                    ``` ### Inline Render the color picker inline without a popover by using the `inline` prop. **Example: inline** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { CheckIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const Inline = () => { return ( {swatches.map((color) => ( ))} ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Check } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const Inline = () => { return ( {(color) => ( )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each swatches as color} {/each} ``` ### Input Only A minimal color picker with just an input field, value swatch, and eye dropper trigger. **Example: input-only** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' export const InputOnly = () => { return ( Color ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Pipette } from 'lucide-solid' import styles from 'styles/color-picker.module.css' export const InputOnly = () => { return ( Color ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Color ``` ### Slider Only Display only the channel sliders for RGB color selection. **Example: slider-only** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import styles from 'styles/color-picker.module.css' export const SliderOnly = () => { return (
                    R
                    G
                    B
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import styles from 'styles/color-picker.module.css' export const SliderOnly = () => { return (
                    R
                    G
                    B
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    R
                    G
                    B
                    ``` ### Swatch Only A simple color picker with only preset color swatches. **Example: swatch-only** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { CheckIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'pink', 'orange', 'purple'] export const SwatchOnly = () => { return ( Selected color: {swatches.map((color) => ( ))} ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Check } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'pink', 'orange', 'purple'] export const SwatchOnly = () => { return ( Selected color: {(color) => ( )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Selected color: {#each swatches as color} {/each} ``` ### Swatches Include preset color swatches in the color picker content for quick color selection. **Example: swatches** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { CheckIcon, PipetteIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const Swatches = () => { return ( Color
                    {swatches.map((color) => ( ))}
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Check, Pipette } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const Swatches = () => { return ( Color
                    {(color) => ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Color
                    {#each swatches as color} {/each}
                    ``` ### Value Swatch Display the current color value as a swatch alongside the color area and sliders. **Example: value-swatch** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import styles from 'styles/color-picker.module.css' export const ValueSwatch = () => { return (
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import styles from 'styles/color-picker.module.css' export const ValueSwatch = () => { return (
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    ``` ### 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. **Example: with-field** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { Field } from '@ark-ui/react/field' import field from 'styles/field.module.css' import styles from 'styles/color-picker.module.css' export const WithField = () => ( Label
                    Additional Info Error Info
                    ) ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Field } from '@ark-ui/solid/field' import field from 'styles/field.module.css' import styles from 'styles/color-picker.module.css' export const WithField = () => ( Label
                    Additional Info Error Info
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    Additional Info Error Info
                    ``` ### Form Usage Integrate the color picker with form libraries like React Hook Form using the `HiddenInput` component. **Example: form-usage** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import { useForm } from 'react-hook-form' import button from 'styles/button.module.css' import styles from 'styles/color-picker.module.css' interface FieldValues { color: string } export const FormUsage = () => { const { register, handleSubmit } = useForm() const onSubmit = (data: FieldValues) => { alert(data) } return (
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { createForm, setValue } from '@modular-forms/solid' import { Pipette } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/color-picker.module.css' export const FormUsage = () => { const [formStore, { Form, Field }] = createForm<{ color: string }>() return (
                    { window.alert(JSON.stringify(data)) }} > {(field) => ( setValue(formStore, 'color', details.valueAsString)} >
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    { e.preventDefault() form.handleSubmit() }} > {#snippet children(field)} field.handleChange(details.valueAsString)} >
                    {/snippet}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the color picker when a swatch is selected | | `defaultFormat` | `ColorFormat` | No | The initial color format when rendered. Use when you don't need to control the color format of the color picker. | | `defaultOpen` | `boolean` | No | The initial open state of the color picker when rendered. Use when you don't need to control the open state of the color picker. | | `defaultValue` | `Color` | No | The initial color value when rendered. Use when you don't need to control the color value of the color picker. | | `disabled` | `boolean` | No | Whether the color picker is disabled | | `format` | `ColorFormat` | No | The controlled color format to use | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; trigger: string; label: string; input: string; hiddenInput: string; content: string; area: string; areaGradient: string; positioner: string; formatSelect: string; areaThumb: string; channelInput: (id: string) => string; channelSliderTrack: (id: ColorChannel) => string; channe...` | No | The ids of the elements in the color picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The initial focus element when the color picker is opened. | | `inline` | `boolean` | No | Whether to render the color picker inline | | `invalid` | `boolean` | No | Whether the color picker is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `name` | `string` | No | The name for the form input | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onFormatChange` | `(details: FormatChangeDetails) => void` | No | Function called when the color format changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Handler that is called when the user opens or closes the color picker. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the value changes, as the user drags. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the user stops dragging. | | `open` | `boolean` | No | The controlled open state of the color picker | | `openAutoFocus` | `boolean` | No | Whether to auto focus the color picker when it is opened | | `positioning` | `PositioningOptions` | No | The positioning options for the color picker | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the color picker is read-only | | `required` | `boolean` | No | Whether the color picker is required | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `Color` | No | The controlled color value of the color picker | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **AreaBackground Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaBackground Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-background | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `xChannel` | `ColorChannel` | No | | | `yChannel` | `ColorChannel` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **AreaThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **AreaThumb CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **ChannelInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ExtendedColorChannel` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelInput Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-input | | `[data-channel]` | The color channel of the channelinput | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ChannelSliderLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderLabel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-label | | `[data-channel]` | The color channel of the channelsliderlabel | **ChannelSlider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ColorChannel` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelSlider Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider | | `[data-channel]` | The color channel of the channelslider | | `[data-orientation]` | The orientation of the channelslider | **ChannelSliderThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-thumb | | `[data-channel]` | The color channel of the channelsliderthumb | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the channelsliderthumb | **ChannelSliderTrack Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderTrack Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-track | | `[data-channel]` | The color channel of the channelslidertrack | | `[data-orientation]` | The orientation of the channelslidertrack | **ChannelSliderValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-value-text | | `[data-channel]` | The color channel of the channelslidervaluetext | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | content | | `[data-placement]` | The placement of the content | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-state]` | "open" | "closed" | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested color-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **EyeDropperTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EyeDropperTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | eye-dropper-trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **FormatSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **FormatTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseColorPickerReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **SwatchGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SwatchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Swatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **Swatch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | **Swatch CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **SwatchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the swatch trigger is disabled | **SwatchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch-trigger | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **SwatchTrigger CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **TransparencyGrid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `size` | `string` | No | | **TransparencyGrid CSS Variables:** | Variable | Description | |----------|-------------| | `--size` | The size (width and height) of the element | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **ValueSwatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `format` | `ColorStringFormat` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `format` | `ColorFormat` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the color picker when a swatch is selected | | `defaultFormat` | `ColorFormat` | No | The initial color format when rendered. Use when you don't need to control the color format of the color picker. | | `defaultOpen` | `boolean` | No | The initial open state of the color picker when rendered. Use when you don't need to control the open state of the color picker. | | `defaultValue` | `Color` | No | The initial color value when rendered. Use when you don't need to control the color value of the color picker. | | `disabled` | `boolean` | No | Whether the color picker is disabled | | `format` | `ColorFormat` | No | The controlled color format to use | | `ids` | `Partial<{ root: string; control: string; trigger: string; label: string; input: string; hiddenInput: string; content: string; area: string; areaGradient: string; positioner: string; formatSelect: string; areaThumb: string; channelInput: (id: string) => string; channelSliderTrack: (id: ColorChannel) => string; channe...` | No | The ids of the elements in the color picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The initial focus element when the color picker is opened. | | `inline` | `boolean` | No | Whether to render the color picker inline | | `invalid` | `boolean` | No | Whether the color picker is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `name` | `string` | No | The name for the form input | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onFormatChange` | `(details: FormatChangeDetails) => void` | No | Function called when the color format changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Handler that is called when the user opens or closes the color picker. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the value changes, as the user drags. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the user stops dragging. | | `open` | `boolean` | No | The controlled open state of the color picker | | `openAutoFocus` | `boolean` | No | Whether to auto focus the color picker when it is opened | | `positioning` | `PositioningOptions` | No | The positioning options for the color picker | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the color picker is read-only | | `required` | `boolean` | No | Whether the color picker is required | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `Color` | No | The controlled color value of the color picker | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **AreaBackground Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaBackground Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-background | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `xChannel` | `ColorChannel` | No | | | `yChannel` | `ColorChannel` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **AreaThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **AreaThumb CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **ChannelInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ExtendedColorChannel` | Yes | | | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelInput Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-input | | `[data-channel]` | The color channel of the channelinput | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ChannelSliderLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderLabel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-label | | `[data-channel]` | The color channel of the channelsliderlabel | **ChannelSlider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ColorChannel` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelSlider Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider | | `[data-channel]` | The color channel of the channelslider | | `[data-orientation]` | The orientation of the channelslider | **ChannelSliderThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-thumb | | `[data-channel]` | The color channel of the channelsliderthumb | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the channelsliderthumb | **ChannelSliderTrack Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderTrack Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-track | | `[data-channel]` | The color channel of the channelslidertrack | | `[data-orientation]` | The orientation of the channelslidertrack | **ChannelSliderValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-value-text | | `[data-channel]` | The color channel of the channelslidervaluetext | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | content | | `[data-placement]` | The placement of the content | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-state]` | "open" | "closed" | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested color-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **EyeDropperTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EyeDropperTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | eye-dropper-trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **FormatSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **FormatTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseColorPickerReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **SwatchGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SwatchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Swatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **Swatch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | **Swatch CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **SwatchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the swatch trigger is disabled | **SwatchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch-trigger | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **SwatchTrigger CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **TransparencyGrid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `size` | `string` | No | | **TransparencyGrid CSS Variables:** | Variable | Description | |----------|-------------| | `--size` | The size (width and height) of the element | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **ValueSwatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `format` | `ColorStringFormat` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `format` | `ColorFormat` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the color picker when a swatch is selected | | `defaultFormat` | `ColorFormat` | No | The initial color format when rendered. Use when you don't need to control the color format of the color picker. | | `defaultOpen` | `boolean` | No | The initial open state of the color picker when rendered. Use when you don't need to control the open state of the color picker. | | `defaultValue` | `Color` | No | The initial color value when rendered. Use when you don't need to control the color value of the color picker. | | `disabled` | `boolean` | No | Whether the color picker is disabled | | `format` | `ColorFormat` | No | The controlled color format to use | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; trigger: string; label: string; input: string; hiddenInput: string; content: string; area: string; areaGradient: string; positioner: string; formatSelect: string; areaThumb: string; channelInput(id: string): string; channelSliderTrack(id: ColorChannel): string; channelSliderT...` | No | The ids of the elements in the color picker. Useful for composition. | | `initialFocusEl` | `() => HTMLElement | null` | No | The initial focus element when the color picker is opened. | | `inline` | `boolean` | No | Whether the color picker is inline | | `invalid` | `boolean` | No | Whether the color picker is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modelValue` | `Color` | No | The v-model value of the color picker | | `name` | `string` | No | The name for the form input | | `open` | `boolean` | No | The controlled open state of the color picker | | `openAutoFocus` | `boolean` | No | Whether to auto focus the color picker when it is opened | | `positioning` | `PositioningOptions` | No | The positioning options for the color picker | | `readOnly` | `boolean` | No | Whether the color picker is read-only | | `required` | `boolean` | No | Whether the color picker is required | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **AreaBackground Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaBackground Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-background | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `xChannel` | `ColorChannel` | No | | | `yChannel` | `ColorChannel` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **AreaThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **AreaThumb CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **ChannelInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ExtendedColorChannel` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelInput Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-input | | `[data-channel]` | The color channel of the channelinput | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ChannelSliderLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderLabel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-label | | `[data-channel]` | The color channel of the channelsliderlabel | **ChannelSlider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ColorChannel` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelSlider Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider | | `[data-channel]` | The color channel of the channelslider | | `[data-orientation]` | The orientation of the channelslider | **ChannelSliderThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-thumb | | `[data-channel]` | The color channel of the channelsliderthumb | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the channelsliderthumb | **ChannelSliderTrack Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderTrack Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-track | | `[data-channel]` | The color channel of the channelslidertrack | | `[data-orientation]` | The orientation of the channelslidertrack | **ChannelSliderValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-value-text | | `[data-channel]` | The color channel of the channelslidervaluetext | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | content | | `[data-placement]` | The placement of the content | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-state]` | "open" | "closed" | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested color-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **EyeDropperTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EyeDropperTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | eye-dropper-trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **FormatSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **FormatTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ColorPickerApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **SwatchGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SwatchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Swatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **Swatch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | **Swatch CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **SwatchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the swatch trigger is disabled | **SwatchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch-trigger | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **SwatchTrigger CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **TransparencyGrid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `size` | `string` | No | | **TransparencyGrid CSS Variables:** | Variable | Description | |----------|-------------| | `--size` | The size (width and height) of the element | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **ValueSwatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `format` | `ColorStringFormat` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `format` | `ColorFormat` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the color picker when a swatch is selected | | `defaultFormat` | `ColorFormat` | No | The initial color format when rendered. Use when you don't need to control the color format of the color picker. | | `defaultOpen` | `boolean` | No | The initial open state of the color picker when rendered. Use when you don't need to control the open state of the color picker. | | `defaultValue` | `Color` | No | The initial color value when rendered. Use when you don't need to control the color value of the color picker. | | `disabled` | `boolean` | No | Whether the color picker is disabled | | `format` | `ColorFormat` | No | The controlled color format to use | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; trigger: string; label: string; input: string; hiddenInput: string; content: string; area: string; areaGradient: string; positioner: string; formatSelect: string; areaThumb: string; channelInput: (id: string) => string; channelSliderTrack: (id: ColorChannel) => string; channe...` | No | The ids of the elements in the color picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The initial focus element when the color picker is opened. | | `inline` | `boolean` | No | Whether to render the color picker inline | | `invalid` | `boolean` | No | Whether the color picker is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `name` | `string` | No | The name for the form input | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onFormatChange` | `(details: FormatChangeDetails) => void` | No | Function called when the color format changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Handler that is called when the user opens or closes the color picker. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the value changes, as the user drags. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the user stops dragging. | | `open` | `boolean` | No | The controlled open state of the color picker | | `openAutoFocus` | `boolean` | No | Whether to auto focus the color picker when it is opened | | `positioning` | `PositioningOptions` | No | The positioning options for the color picker | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the color picker is read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the color picker is required | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `Color` | No | The controlled color value of the color picker | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **AreaBackground Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **AreaBackground Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-background | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `xChannel` | `ColorChannel` | No | | | `yChannel` | `ColorChannel` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **AreaThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **AreaThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **AreaThumb CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **ChannelInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ExtendedColorChannel` | Yes | | | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | | `ref` | `Element` | No | | **ChannelInput Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-input | | `[data-channel]` | The color channel of the channelinput | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ChannelSliderLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ChannelSliderLabel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-label | | `[data-channel]` | The color channel of the channelsliderlabel | **ChannelSlider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ColorChannel` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | | `ref` | `Element` | No | | **ChannelSlider Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider | | `[data-channel]` | The color channel of the channelslider | | `[data-orientation]` | The orientation of the channelslider | **ChannelSliderThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ChannelSliderThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-thumb | | `[data-channel]` | The color channel of the channelsliderthumb | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the channelsliderthumb | **ChannelSliderTrack Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ChannelSliderTrack Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-track | | `[data-channel]` | The color channel of the channelslidertrack | | `[data-orientation]` | The orientation of the channelslidertrack | **ChannelSliderValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ChannelSliderValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-value-text | | `[data-channel]` | The color channel of the channelslidervaluetext | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | content | | `[data-placement]` | The placement of the content | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-state]` | "open" | "closed" | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested color-pickers | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseColorPickerContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **EyeDropperTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **EyeDropperTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | eye-dropper-trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **FormatSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **FormatTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseColorPickerReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `ref` | `Element` | No | | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **SwatchGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **SwatchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Swatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **Swatch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | **Swatch CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **SwatchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the swatch trigger is disabled | | `ref` | `Element` | No | | **SwatchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch-trigger | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **SwatchTrigger CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **TransparencyGrid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `size` | `string` | No | | **TransparencyGrid CSS Variables:** | Variable | Description | |----------|-------------| | `--size` | The size (width and height) of the element | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **ValueSwatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `format` | `ColorStringFormat` | No | | | `ref` | `Element` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `format` | `ColorFormat` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `dragging` | `boolean` | Whether the color picker is being dragged | | `open` | `boolean` | Whether the color picker is open | | `inline` | `boolean` | Whether the color picker is rendered inline | | `value` | `Color` | The current color value (as a string) | | `valueAsString` | `string` | The current color value (as a Color object) | | `setValue` | `(value: string | Color) => void` | Function to set the color value | | `getChannelValue` | `(channel: ColorChannel) => string` | Function to set the color value | | `getChannelValueText` | `(channel: ColorChannel, locale: string) => string` | Function to get the formatted and localized value of a specific channel | | `setChannelValue` | `(channel: ColorChannel, value: number) => void` | Function to set the color value of a specific channel | | `format` | `ColorFormat` | The current color format | | `setFormat` | `(format: ColorFormat) => void` | Function to set the color format | | `alpha` | `number` | The alpha value of the color | | `setAlpha` | `(value: number) => void` | Function to set the color alpha | | `setOpen` | `(open: boolean) => void` | Function to open or close the color picker | ## Accessibility ### Keyboard Support **`Enter`** Description: When focus is on the trigger, opens the color picker
                    When focus is on a trigger of a swatch, selects the color (and closes the color picker)
                    When focus is on the input or channel inputs, selects the color
                    **`ArrowLeft`** Description: When focus is on the color area, decreases the hue value of the color
                    When focus is on the channel sliders, decreases the value of the channel
                    **`ArrowRight`** Description: When focus is on the color area, increases the hue value of the color
                    When focus is on the channel sliders, increases the value of the channel
                    **`ArrowUp`** Description: When focus is on the color area, increases the saturation value of the color
                    When focus is on the channel sliders, increases the value of the channel
                    **`ArrowDown`** Description: When focus is on the color area, decreases the saturation value of the color
                    When focus is on the channel sliders, decreases the value of the channel
                    **`Esc`** Description: Closes the color picker and moves focus to the trigger --- # Color Picker (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' export const Basic = () => { return ( Color
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Pipette } from 'lucide-solid' import styles from 'styles/color-picker.module.css' export const Basic = () => { return ( Color
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Color
                    ``` ### Controlled Use the `value` and `onValueChange` props to programatically control the color picker's state. **Example: controlled** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/color-picker.module.css' export const Controlled = () => { const [color, setColor] = useState(() => parseColor('hsl(20, 100%, 50%)')) return (
                    Selected color: {color.toString('hex')} setColor(e.value)}> Color
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Pipette } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/color-picker.module.css' export const Controlled = () => { const [color, setColor] = createSignal(parseColor('hsl(20, 100%, 50%)')) return (
                    Selected color: {color().toString('hex')} setColor(e.value)}> Color
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Selected color: {value.toString('hex')} Color
                    ``` ### Open Controlled Control the open state of the color picker popover programmatically using the `open` and `onOpenChange` props. **Example: open-controlled** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/color-picker.module.css' export const OpenControlled = () => { const [open, setOpen] = useState(false) return (
                    setOpen(e.open)} defaultValue={parseColor('#eb5e41')} > Color
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Pipette } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/color-picker.module.css' export const OpenControlled = () => { const [open, setOpen] = createSignal(false) return (
                    setOpen(e.open)} defaultValue={parseColor('#eb5e41')} > Color
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Color
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { ColorPicker, parseColor, useColorPicker } from '@ark-ui/react/color-picker' import { CheckIcon, PipetteIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const RootProvider = () => { const colorPicker = useColorPicker({ defaultValue: parseColor('#eb5e41') }) return (
                    Color: {colorPicker.valueAsString} Color
                    {swatches.map((color) => ( ))}
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor, useColorPicker } from '@ark-ui/solid/color-picker' import { Check, Pipette } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const RootProvider = () => { const colorPicker = useColorPicker({ defaultValue: parseColor('#eb5e41') }) return (
                    Color: {colorPicker().valueAsString} Color
                    {(color) => ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Color: {colorPicker().valueAsString} Color
                    {#each swatches as color} {/each}
                    ``` ### Disabled Use the `disabled` prop to disable the color picker. **Example: disabled** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import styles from 'styles/color-picker.module.css' export const Disabled = () => { return ( Color
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import styles from 'styles/color-picker.module.css' export const Disabled = () => { return ( Color
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Color
                    ``` ### Inline Render the color picker inline without a popover by using the `inline` prop. **Example: inline** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { CheckIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const Inline = () => { return ( {swatches.map((color) => ( ))} ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Check } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const Inline = () => { return ( {(color) => ( )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each swatches as color} {/each} ``` ### Input Only A minimal color picker with just an input field, value swatch, and eye dropper trigger. **Example: input-only** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' export const InputOnly = () => { return ( Color ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Pipette } from 'lucide-solid' import styles from 'styles/color-picker.module.css' export const InputOnly = () => { return ( Color ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Color ``` ### Slider Only Display only the channel sliders for RGB color selection. **Example: slider-only** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import styles from 'styles/color-picker.module.css' export const SliderOnly = () => { return (
                    R
                    G
                    B
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import styles from 'styles/color-picker.module.css' export const SliderOnly = () => { return (
                    R
                    G
                    B
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    R
                    G
                    B
                    ``` ### Swatch Only A simple color picker with only preset color swatches. **Example: swatch-only** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { CheckIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'pink', 'orange', 'purple'] export const SwatchOnly = () => { return ( Selected color: {swatches.map((color) => ( ))} ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Check } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'pink', 'orange', 'purple'] export const SwatchOnly = () => { return ( Selected color: {(color) => ( )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Selected color: {#each swatches as color} {/each} ``` ### Swatches Include preset color swatches in the color picker content for quick color selection. **Example: swatches** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { CheckIcon, PipetteIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const Swatches = () => { return ( Color
                    {swatches.map((color) => ( ))}
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Check, Pipette } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const Swatches = () => { return ( Color
                    {(color) => ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Color
                    {#each swatches as color} {/each}
                    ``` ### Value Swatch Display the current color value as a swatch alongside the color area and sliders. **Example: value-swatch** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import styles from 'styles/color-picker.module.css' export const ValueSwatch = () => { return (
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import styles from 'styles/color-picker.module.css' export const ValueSwatch = () => { return (
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    ``` ### 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. **Example: with-field** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { Field } from '@ark-ui/react/field' import field from 'styles/field.module.css' import styles from 'styles/color-picker.module.css' export const WithField = () => ( Label
                    Additional Info Error Info
                    ) ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Field } from '@ark-ui/solid/field' import field from 'styles/field.module.css' import styles from 'styles/color-picker.module.css' export const WithField = () => ( Label
                    Additional Info Error Info
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    Additional Info Error Info
                    ``` ### Form Usage Integrate the color picker with form libraries like React Hook Form using the `HiddenInput` component. **Example: form-usage** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import { useForm } from 'react-hook-form' import button from 'styles/button.module.css' import styles from 'styles/color-picker.module.css' interface FieldValues { color: string } export const FormUsage = () => { const { register, handleSubmit } = useForm() const onSubmit = (data: FieldValues) => { alert(data) } return (
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { createForm, setValue } from '@modular-forms/solid' import { Pipette } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/color-picker.module.css' export const FormUsage = () => { const [formStore, { Form, Field }] = createForm<{ color: string }>() return (
                    { window.alert(JSON.stringify(data)) }} > {(field) => ( setValue(formStore, 'color', details.valueAsString)} >
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    { e.preventDefault() form.handleSubmit() }} > {#snippet children(field)} field.handleChange(details.valueAsString)} >
                    {/snippet}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the color picker when a swatch is selected | | `defaultFormat` | `ColorFormat` | No | The initial color format when rendered. Use when you don't need to control the color format of the color picker. | | `defaultOpen` | `boolean` | No | The initial open state of the color picker when rendered. Use when you don't need to control the open state of the color picker. | | `defaultValue` | `Color` | No | The initial color value when rendered. Use when you don't need to control the color value of the color picker. | | `disabled` | `boolean` | No | Whether the color picker is disabled | | `format` | `ColorFormat` | No | The controlled color format to use | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; trigger: string; label: string; input: string; hiddenInput: string; content: string; area: string; areaGradient: string; positioner: string; formatSelect: string; areaThumb: string; channelInput: (id: string) => string; channelSliderTrack: (id: ColorChannel) => string; channe...` | No | The ids of the elements in the color picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The initial focus element when the color picker is opened. | | `inline` | `boolean` | No | Whether to render the color picker inline | | `invalid` | `boolean` | No | Whether the color picker is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `name` | `string` | No | The name for the form input | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onFormatChange` | `(details: FormatChangeDetails) => void` | No | Function called when the color format changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Handler that is called when the user opens or closes the color picker. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the value changes, as the user drags. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the user stops dragging. | | `open` | `boolean` | No | The controlled open state of the color picker | | `openAutoFocus` | `boolean` | No | Whether to auto focus the color picker when it is opened | | `positioning` | `PositioningOptions` | No | The positioning options for the color picker | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the color picker is read-only | | `required` | `boolean` | No | Whether the color picker is required | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `Color` | No | The controlled color value of the color picker | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **AreaBackground Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaBackground Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-background | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `xChannel` | `ColorChannel` | No | | | `yChannel` | `ColorChannel` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **AreaThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **AreaThumb CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **ChannelInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ExtendedColorChannel` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelInput Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-input | | `[data-channel]` | The color channel of the channelinput | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ChannelSliderLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderLabel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-label | | `[data-channel]` | The color channel of the channelsliderlabel | **ChannelSlider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ColorChannel` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelSlider Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider | | `[data-channel]` | The color channel of the channelslider | | `[data-orientation]` | The orientation of the channelslider | **ChannelSliderThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-thumb | | `[data-channel]` | The color channel of the channelsliderthumb | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the channelsliderthumb | **ChannelSliderTrack Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderTrack Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-track | | `[data-channel]` | The color channel of the channelslidertrack | | `[data-orientation]` | The orientation of the channelslidertrack | **ChannelSliderValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-value-text | | `[data-channel]` | The color channel of the channelslidervaluetext | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | content | | `[data-placement]` | The placement of the content | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-state]` | "open" | "closed" | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested color-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **EyeDropperTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EyeDropperTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | eye-dropper-trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **FormatSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **FormatTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseColorPickerReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **SwatchGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SwatchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Swatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **Swatch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | **Swatch CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **SwatchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the swatch trigger is disabled | **SwatchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch-trigger | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **SwatchTrigger CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **TransparencyGrid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `size` | `string` | No | | **TransparencyGrid CSS Variables:** | Variable | Description | |----------|-------------| | `--size` | The size (width and height) of the element | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **ValueSwatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `format` | `ColorStringFormat` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `format` | `ColorFormat` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the color picker when a swatch is selected | | `defaultFormat` | `ColorFormat` | No | The initial color format when rendered. Use when you don't need to control the color format of the color picker. | | `defaultOpen` | `boolean` | No | The initial open state of the color picker when rendered. Use when you don't need to control the open state of the color picker. | | `defaultValue` | `Color` | No | The initial color value when rendered. Use when you don't need to control the color value of the color picker. | | `disabled` | `boolean` | No | Whether the color picker is disabled | | `format` | `ColorFormat` | No | The controlled color format to use | | `ids` | `Partial<{ root: string; control: string; trigger: string; label: string; input: string; hiddenInput: string; content: string; area: string; areaGradient: string; positioner: string; formatSelect: string; areaThumb: string; channelInput: (id: string) => string; channelSliderTrack: (id: ColorChannel) => string; channe...` | No | The ids of the elements in the color picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The initial focus element when the color picker is opened. | | `inline` | `boolean` | No | Whether to render the color picker inline | | `invalid` | `boolean` | No | Whether the color picker is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `name` | `string` | No | The name for the form input | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onFormatChange` | `(details: FormatChangeDetails) => void` | No | Function called when the color format changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Handler that is called when the user opens or closes the color picker. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the value changes, as the user drags. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the user stops dragging. | | `open` | `boolean` | No | The controlled open state of the color picker | | `openAutoFocus` | `boolean` | No | Whether to auto focus the color picker when it is opened | | `positioning` | `PositioningOptions` | No | The positioning options for the color picker | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the color picker is read-only | | `required` | `boolean` | No | Whether the color picker is required | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `Color` | No | The controlled color value of the color picker | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **AreaBackground Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaBackground Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-background | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `xChannel` | `ColorChannel` | No | | | `yChannel` | `ColorChannel` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **AreaThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **AreaThumb CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **ChannelInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ExtendedColorChannel` | Yes | | | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelInput Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-input | | `[data-channel]` | The color channel of the channelinput | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ChannelSliderLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderLabel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-label | | `[data-channel]` | The color channel of the channelsliderlabel | **ChannelSlider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ColorChannel` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelSlider Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider | | `[data-channel]` | The color channel of the channelslider | | `[data-orientation]` | The orientation of the channelslider | **ChannelSliderThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-thumb | | `[data-channel]` | The color channel of the channelsliderthumb | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the channelsliderthumb | **ChannelSliderTrack Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderTrack Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-track | | `[data-channel]` | The color channel of the channelslidertrack | | `[data-orientation]` | The orientation of the channelslidertrack | **ChannelSliderValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-value-text | | `[data-channel]` | The color channel of the channelslidervaluetext | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | content | | `[data-placement]` | The placement of the content | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-state]` | "open" | "closed" | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested color-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **EyeDropperTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EyeDropperTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | eye-dropper-trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **FormatSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **FormatTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseColorPickerReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **SwatchGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SwatchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Swatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **Swatch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | **Swatch CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **SwatchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the swatch trigger is disabled | **SwatchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch-trigger | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **SwatchTrigger CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **TransparencyGrid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `size` | `string` | No | | **TransparencyGrid CSS Variables:** | Variable | Description | |----------|-------------| | `--size` | The size (width and height) of the element | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **ValueSwatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `format` | `ColorStringFormat` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `format` | `ColorFormat` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the color picker when a swatch is selected | | `defaultFormat` | `ColorFormat` | No | The initial color format when rendered. Use when you don't need to control the color format of the color picker. | | `defaultOpen` | `boolean` | No | The initial open state of the color picker when rendered. Use when you don't need to control the open state of the color picker. | | `defaultValue` | `Color` | No | The initial color value when rendered. Use when you don't need to control the color value of the color picker. | | `disabled` | `boolean` | No | Whether the color picker is disabled | | `format` | `ColorFormat` | No | The controlled color format to use | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; trigger: string; label: string; input: string; hiddenInput: string; content: string; area: string; areaGradient: string; positioner: string; formatSelect: string; areaThumb: string; channelInput(id: string): string; channelSliderTrack(id: ColorChannel): string; channelSliderT...` | No | The ids of the elements in the color picker. Useful for composition. | | `initialFocusEl` | `() => HTMLElement | null` | No | The initial focus element when the color picker is opened. | | `inline` | `boolean` | No | Whether the color picker is inline | | `invalid` | `boolean` | No | Whether the color picker is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modelValue` | `Color` | No | The v-model value of the color picker | | `name` | `string` | No | The name for the form input | | `open` | `boolean` | No | The controlled open state of the color picker | | `openAutoFocus` | `boolean` | No | Whether to auto focus the color picker when it is opened | | `positioning` | `PositioningOptions` | No | The positioning options for the color picker | | `readOnly` | `boolean` | No | Whether the color picker is read-only | | `required` | `boolean` | No | Whether the color picker is required | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **AreaBackground Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaBackground Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-background | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `xChannel` | `ColorChannel` | No | | | `yChannel` | `ColorChannel` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **AreaThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **AreaThumb CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **ChannelInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ExtendedColorChannel` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelInput Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-input | | `[data-channel]` | The color channel of the channelinput | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ChannelSliderLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderLabel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-label | | `[data-channel]` | The color channel of the channelsliderlabel | **ChannelSlider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ColorChannel` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelSlider Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider | | `[data-channel]` | The color channel of the channelslider | | `[data-orientation]` | The orientation of the channelslider | **ChannelSliderThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-thumb | | `[data-channel]` | The color channel of the channelsliderthumb | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the channelsliderthumb | **ChannelSliderTrack Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderTrack Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-track | | `[data-channel]` | The color channel of the channelslidertrack | | `[data-orientation]` | The orientation of the channelslidertrack | **ChannelSliderValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-value-text | | `[data-channel]` | The color channel of the channelslidervaluetext | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | content | | `[data-placement]` | The placement of the content | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-state]` | "open" | "closed" | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested color-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **EyeDropperTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EyeDropperTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | eye-dropper-trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **FormatSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **FormatTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ColorPickerApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **SwatchGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SwatchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Swatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **Swatch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | **Swatch CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **SwatchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the swatch trigger is disabled | **SwatchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch-trigger | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **SwatchTrigger CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **TransparencyGrid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `size` | `string` | No | | **TransparencyGrid CSS Variables:** | Variable | Description | |----------|-------------| | `--size` | The size (width and height) of the element | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **ValueSwatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `format` | `ColorStringFormat` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `format` | `ColorFormat` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the color picker when a swatch is selected | | `defaultFormat` | `ColorFormat` | No | The initial color format when rendered. Use when you don't need to control the color format of the color picker. | | `defaultOpen` | `boolean` | No | The initial open state of the color picker when rendered. Use when you don't need to control the open state of the color picker. | | `defaultValue` | `Color` | No | The initial color value when rendered. Use when you don't need to control the color value of the color picker. | | `disabled` | `boolean` | No | Whether the color picker is disabled | | `format` | `ColorFormat` | No | The controlled color format to use | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; trigger: string; label: string; input: string; hiddenInput: string; content: string; area: string; areaGradient: string; positioner: string; formatSelect: string; areaThumb: string; channelInput: (id: string) => string; channelSliderTrack: (id: ColorChannel) => string; channe...` | No | The ids of the elements in the color picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The initial focus element when the color picker is opened. | | `inline` | `boolean` | No | Whether to render the color picker inline | | `invalid` | `boolean` | No | Whether the color picker is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `name` | `string` | No | The name for the form input | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onFormatChange` | `(details: FormatChangeDetails) => void` | No | Function called when the color format changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Handler that is called when the user opens or closes the color picker. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the value changes, as the user drags. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the user stops dragging. | | `open` | `boolean` | No | The controlled open state of the color picker | | `openAutoFocus` | `boolean` | No | Whether to auto focus the color picker when it is opened | | `positioning` | `PositioningOptions` | No | The positioning options for the color picker | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the color picker is read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the color picker is required | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `Color` | No | The controlled color value of the color picker | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **AreaBackground Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **AreaBackground Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-background | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `xChannel` | `ColorChannel` | No | | | `yChannel` | `ColorChannel` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **AreaThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **AreaThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **AreaThumb CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **ChannelInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ExtendedColorChannel` | Yes | | | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | | `ref` | `Element` | No | | **ChannelInput Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-input | | `[data-channel]` | The color channel of the channelinput | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ChannelSliderLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ChannelSliderLabel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-label | | `[data-channel]` | The color channel of the channelsliderlabel | **ChannelSlider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ColorChannel` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | | `ref` | `Element` | No | | **ChannelSlider Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider | | `[data-channel]` | The color channel of the channelslider | | `[data-orientation]` | The orientation of the channelslider | **ChannelSliderThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ChannelSliderThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-thumb | | `[data-channel]` | The color channel of the channelsliderthumb | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the channelsliderthumb | **ChannelSliderTrack Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ChannelSliderTrack Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-track | | `[data-channel]` | The color channel of the channelslidertrack | | `[data-orientation]` | The orientation of the channelslidertrack | **ChannelSliderValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ChannelSliderValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-value-text | | `[data-channel]` | The color channel of the channelslidervaluetext | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | content | | `[data-placement]` | The placement of the content | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-state]` | "open" | "closed" | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested color-pickers | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseColorPickerContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **EyeDropperTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **EyeDropperTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | eye-dropper-trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **FormatSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **FormatTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseColorPickerReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `ref` | `Element` | No | | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **SwatchGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **SwatchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Swatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **Swatch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | **Swatch CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **SwatchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the swatch trigger is disabled | | `ref` | `Element` | No | | **SwatchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch-trigger | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **SwatchTrigger CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **TransparencyGrid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `size` | `string` | No | | **TransparencyGrid CSS Variables:** | Variable | Description | |----------|-------------| | `--size` | The size (width and height) of the element | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **ValueSwatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `format` | `ColorStringFormat` | No | | | `ref` | `Element` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `format` | `ColorFormat` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `dragging` | `boolean` | Whether the color picker is being dragged | | `open` | `boolean` | Whether the color picker is open | | `inline` | `boolean` | Whether the color picker is rendered inline | | `value` | `Color` | The current color value (as a string) | | `valueAsString` | `string` | The current color value (as a Color object) | | `setValue` | `(value: string | Color) => void` | Function to set the color value | | `getChannelValue` | `(channel: ColorChannel) => string` | Function to set the color value | | `getChannelValueText` | `(channel: ColorChannel, locale: string) => string` | Function to get the formatted and localized value of a specific channel | | `setChannelValue` | `(channel: ColorChannel, value: number) => void` | Function to set the color value of a specific channel | | `format` | `ColorFormat` | The current color format | | `setFormat` | `(format: ColorFormat) => void` | Function to set the color format | | `alpha` | `number` | The alpha value of the color | | `setAlpha` | `(value: number) => void` | Function to set the color alpha | | `setOpen` | `(open: boolean) => void` | Function to open or close the color picker | ## Accessibility ### Keyboard Support **`Enter`** Description: When focus is on the trigger, opens the color picker
                    When focus is on a trigger of a swatch, selects the color (and closes the color picker)
                    When focus is on the input or channel inputs, selects the color
                    **`ArrowLeft`** Description: When focus is on the color area, decreases the hue value of the color
                    When focus is on the channel sliders, decreases the value of the channel
                    **`ArrowRight`** Description: When focus is on the color area, increases the hue value of the color
                    When focus is on the channel sliders, increases the value of the channel
                    **`ArrowUp`** Description: When focus is on the color area, increases the saturation value of the color
                    When focus is on the channel sliders, increases the value of the channel
                    **`ArrowDown`** Description: When focus is on the color area, decreases the saturation value of the color
                    When focus is on the channel sliders, decreases the value of the channel
                    **`Esc`** Description: Closes the color picker and moves focus to the trigger --- # Color Picker (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' export const Basic = () => { return ( Color
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Pipette } from 'lucide-solid' import styles from 'styles/color-picker.module.css' export const Basic = () => { return ( Color
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Color
                    ``` ### Controlled Use the `value` and `onValueChange` props to programatically control the color picker's state. **Example: controlled** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/color-picker.module.css' export const Controlled = () => { const [color, setColor] = useState(() => parseColor('hsl(20, 100%, 50%)')) return (
                    Selected color: {color.toString('hex')} setColor(e.value)}> Color
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Pipette } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/color-picker.module.css' export const Controlled = () => { const [color, setColor] = createSignal(parseColor('hsl(20, 100%, 50%)')) return (
                    Selected color: {color().toString('hex')} setColor(e.value)}> Color
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Selected color: {value.toString('hex')} Color
                    ``` ### Open Controlled Control the open state of the color picker popover programmatically using the `open` and `onOpenChange` props. **Example: open-controlled** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/color-picker.module.css' export const OpenControlled = () => { const [open, setOpen] = useState(false) return (
                    setOpen(e.open)} defaultValue={parseColor('#eb5e41')} > Color
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Pipette } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/color-picker.module.css' export const OpenControlled = () => { const [open, setOpen] = createSignal(false) return (
                    setOpen(e.open)} defaultValue={parseColor('#eb5e41')} > Color
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Color
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { ColorPicker, parseColor, useColorPicker } from '@ark-ui/react/color-picker' import { CheckIcon, PipetteIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const RootProvider = () => { const colorPicker = useColorPicker({ defaultValue: parseColor('#eb5e41') }) return (
                    Color: {colorPicker.valueAsString} Color
                    {swatches.map((color) => ( ))}
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor, useColorPicker } from '@ark-ui/solid/color-picker' import { Check, Pipette } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const RootProvider = () => { const colorPicker = useColorPicker({ defaultValue: parseColor('#eb5e41') }) return (
                    Color: {colorPicker().valueAsString} Color
                    {(color) => ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Color: {colorPicker().valueAsString} Color
                    {#each swatches as color} {/each}
                    ``` ### Disabled Use the `disabled` prop to disable the color picker. **Example: disabled** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import styles from 'styles/color-picker.module.css' export const Disabled = () => { return ( Color
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import styles from 'styles/color-picker.module.css' export const Disabled = () => { return ( Color
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Color
                    ``` ### Inline Render the color picker inline without a popover by using the `inline` prop. **Example: inline** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { CheckIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const Inline = () => { return ( {swatches.map((color) => ( ))} ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Check } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const Inline = () => { return ( {(color) => ( )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each swatches as color} {/each} ``` ### Input Only A minimal color picker with just an input field, value swatch, and eye dropper trigger. **Example: input-only** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' export const InputOnly = () => { return ( Color ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Pipette } from 'lucide-solid' import styles from 'styles/color-picker.module.css' export const InputOnly = () => { return ( Color ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Color ``` ### Slider Only Display only the channel sliders for RGB color selection. **Example: slider-only** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import styles from 'styles/color-picker.module.css' export const SliderOnly = () => { return (
                    R
                    G
                    B
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import styles from 'styles/color-picker.module.css' export const SliderOnly = () => { return (
                    R
                    G
                    B
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    R
                    G
                    B
                    ``` ### Swatch Only A simple color picker with only preset color swatches. **Example: swatch-only** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { CheckIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'pink', 'orange', 'purple'] export const SwatchOnly = () => { return ( Selected color: {swatches.map((color) => ( ))} ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Check } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'pink', 'orange', 'purple'] export const SwatchOnly = () => { return ( Selected color: {(color) => ( )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Selected color: {#each swatches as color} {/each} ``` ### Swatches Include preset color swatches in the color picker content for quick color selection. **Example: swatches** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { CheckIcon, PipetteIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const Swatches = () => { return ( Color
                    {swatches.map((color) => ( ))}
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Check, Pipette } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const Swatches = () => { return ( Color
                    {(color) => ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Color
                    {#each swatches as color} {/each}
                    ``` ### Value Swatch Display the current color value as a swatch alongside the color area and sliders. **Example: value-swatch** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import styles from 'styles/color-picker.module.css' export const ValueSwatch = () => { return (
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import styles from 'styles/color-picker.module.css' export const ValueSwatch = () => { return (
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    ``` ### 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. **Example: with-field** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { Field } from '@ark-ui/react/field' import field from 'styles/field.module.css' import styles from 'styles/color-picker.module.css' export const WithField = () => ( Label
                    Additional Info Error Info
                    ) ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Field } from '@ark-ui/solid/field' import field from 'styles/field.module.css' import styles from 'styles/color-picker.module.css' export const WithField = () => ( Label
                    Additional Info Error Info
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    Additional Info Error Info
                    ``` ### Form Usage Integrate the color picker with form libraries like React Hook Form using the `HiddenInput` component. **Example: form-usage** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import { useForm } from 'react-hook-form' import button from 'styles/button.module.css' import styles from 'styles/color-picker.module.css' interface FieldValues { color: string } export const FormUsage = () => { const { register, handleSubmit } = useForm() const onSubmit = (data: FieldValues) => { alert(data) } return (
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { createForm, setValue } from '@modular-forms/solid' import { Pipette } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/color-picker.module.css' export const FormUsage = () => { const [formStore, { Form, Field }] = createForm<{ color: string }>() return (
                    { window.alert(JSON.stringify(data)) }} > {(field) => ( setValue(formStore, 'color', details.valueAsString)} >
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    { e.preventDefault() form.handleSubmit() }} > {#snippet children(field)} field.handleChange(details.valueAsString)} >
                    {/snippet}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the color picker when a swatch is selected | | `defaultFormat` | `ColorFormat` | No | The initial color format when rendered. Use when you don't need to control the color format of the color picker. | | `defaultOpen` | `boolean` | No | The initial open state of the color picker when rendered. Use when you don't need to control the open state of the color picker. | | `defaultValue` | `Color` | No | The initial color value when rendered. Use when you don't need to control the color value of the color picker. | | `disabled` | `boolean` | No | Whether the color picker is disabled | | `format` | `ColorFormat` | No | The controlled color format to use | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; trigger: string; label: string; input: string; hiddenInput: string; content: string; area: string; areaGradient: string; positioner: string; formatSelect: string; areaThumb: string; channelInput: (id: string) => string; channelSliderTrack: (id: ColorChannel) => string; channe...` | No | The ids of the elements in the color picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The initial focus element when the color picker is opened. | | `inline` | `boolean` | No | Whether to render the color picker inline | | `invalid` | `boolean` | No | Whether the color picker is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `name` | `string` | No | The name for the form input | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onFormatChange` | `(details: FormatChangeDetails) => void` | No | Function called when the color format changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Handler that is called when the user opens or closes the color picker. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the value changes, as the user drags. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the user stops dragging. | | `open` | `boolean` | No | The controlled open state of the color picker | | `openAutoFocus` | `boolean` | No | Whether to auto focus the color picker when it is opened | | `positioning` | `PositioningOptions` | No | The positioning options for the color picker | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the color picker is read-only | | `required` | `boolean` | No | Whether the color picker is required | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `Color` | No | The controlled color value of the color picker | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **AreaBackground Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaBackground Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-background | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `xChannel` | `ColorChannel` | No | | | `yChannel` | `ColorChannel` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **AreaThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **AreaThumb CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **ChannelInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ExtendedColorChannel` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelInput Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-input | | `[data-channel]` | The color channel of the channelinput | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ChannelSliderLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderLabel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-label | | `[data-channel]` | The color channel of the channelsliderlabel | **ChannelSlider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ColorChannel` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelSlider Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider | | `[data-channel]` | The color channel of the channelslider | | `[data-orientation]` | The orientation of the channelslider | **ChannelSliderThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-thumb | | `[data-channel]` | The color channel of the channelsliderthumb | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the channelsliderthumb | **ChannelSliderTrack Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderTrack Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-track | | `[data-channel]` | The color channel of the channelslidertrack | | `[data-orientation]` | The orientation of the channelslidertrack | **ChannelSliderValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-value-text | | `[data-channel]` | The color channel of the channelslidervaluetext | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | content | | `[data-placement]` | The placement of the content | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-state]` | "open" | "closed" | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested color-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **EyeDropperTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EyeDropperTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | eye-dropper-trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **FormatSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **FormatTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseColorPickerReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **SwatchGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SwatchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Swatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **Swatch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | **Swatch CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **SwatchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the swatch trigger is disabled | **SwatchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch-trigger | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **SwatchTrigger CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **TransparencyGrid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `size` | `string` | No | | **TransparencyGrid CSS Variables:** | Variable | Description | |----------|-------------| | `--size` | The size (width and height) of the element | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **ValueSwatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `format` | `ColorStringFormat` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `format` | `ColorFormat` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the color picker when a swatch is selected | | `defaultFormat` | `ColorFormat` | No | The initial color format when rendered. Use when you don't need to control the color format of the color picker. | | `defaultOpen` | `boolean` | No | The initial open state of the color picker when rendered. Use when you don't need to control the open state of the color picker. | | `defaultValue` | `Color` | No | The initial color value when rendered. Use when you don't need to control the color value of the color picker. | | `disabled` | `boolean` | No | Whether the color picker is disabled | | `format` | `ColorFormat` | No | The controlled color format to use | | `ids` | `Partial<{ root: string; control: string; trigger: string; label: string; input: string; hiddenInput: string; content: string; area: string; areaGradient: string; positioner: string; formatSelect: string; areaThumb: string; channelInput: (id: string) => string; channelSliderTrack: (id: ColorChannel) => string; channe...` | No | The ids of the elements in the color picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The initial focus element when the color picker is opened. | | `inline` | `boolean` | No | Whether to render the color picker inline | | `invalid` | `boolean` | No | Whether the color picker is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `name` | `string` | No | The name for the form input | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onFormatChange` | `(details: FormatChangeDetails) => void` | No | Function called when the color format changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Handler that is called when the user opens or closes the color picker. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the value changes, as the user drags. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the user stops dragging. | | `open` | `boolean` | No | The controlled open state of the color picker | | `openAutoFocus` | `boolean` | No | Whether to auto focus the color picker when it is opened | | `positioning` | `PositioningOptions` | No | The positioning options for the color picker | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the color picker is read-only | | `required` | `boolean` | No | Whether the color picker is required | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `Color` | No | The controlled color value of the color picker | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **AreaBackground Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaBackground Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-background | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `xChannel` | `ColorChannel` | No | | | `yChannel` | `ColorChannel` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **AreaThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **AreaThumb CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **ChannelInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ExtendedColorChannel` | Yes | | | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelInput Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-input | | `[data-channel]` | The color channel of the channelinput | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ChannelSliderLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderLabel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-label | | `[data-channel]` | The color channel of the channelsliderlabel | **ChannelSlider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ColorChannel` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelSlider Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider | | `[data-channel]` | The color channel of the channelslider | | `[data-orientation]` | The orientation of the channelslider | **ChannelSliderThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-thumb | | `[data-channel]` | The color channel of the channelsliderthumb | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the channelsliderthumb | **ChannelSliderTrack Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderTrack Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-track | | `[data-channel]` | The color channel of the channelslidertrack | | `[data-orientation]` | The orientation of the channelslidertrack | **ChannelSliderValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-value-text | | `[data-channel]` | The color channel of the channelslidervaluetext | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | content | | `[data-placement]` | The placement of the content | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-state]` | "open" | "closed" | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested color-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **EyeDropperTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EyeDropperTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | eye-dropper-trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **FormatSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **FormatTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseColorPickerReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **SwatchGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SwatchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Swatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **Swatch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | **Swatch CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **SwatchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the swatch trigger is disabled | **SwatchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch-trigger | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **SwatchTrigger CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **TransparencyGrid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `size` | `string` | No | | **TransparencyGrid CSS Variables:** | Variable | Description | |----------|-------------| | `--size` | The size (width and height) of the element | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **ValueSwatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `format` | `ColorStringFormat` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `format` | `ColorFormat` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the color picker when a swatch is selected | | `defaultFormat` | `ColorFormat` | No | The initial color format when rendered. Use when you don't need to control the color format of the color picker. | | `defaultOpen` | `boolean` | No | The initial open state of the color picker when rendered. Use when you don't need to control the open state of the color picker. | | `defaultValue` | `Color` | No | The initial color value when rendered. Use when you don't need to control the color value of the color picker. | | `disabled` | `boolean` | No | Whether the color picker is disabled | | `format` | `ColorFormat` | No | The controlled color format to use | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; trigger: string; label: string; input: string; hiddenInput: string; content: string; area: string; areaGradient: string; positioner: string; formatSelect: string; areaThumb: string; channelInput(id: string): string; channelSliderTrack(id: ColorChannel): string; channelSliderT...` | No | The ids of the elements in the color picker. Useful for composition. | | `initialFocusEl` | `() => HTMLElement | null` | No | The initial focus element when the color picker is opened. | | `inline` | `boolean` | No | Whether the color picker is inline | | `invalid` | `boolean` | No | Whether the color picker is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modelValue` | `Color` | No | The v-model value of the color picker | | `name` | `string` | No | The name for the form input | | `open` | `boolean` | No | The controlled open state of the color picker | | `openAutoFocus` | `boolean` | No | Whether to auto focus the color picker when it is opened | | `positioning` | `PositioningOptions` | No | The positioning options for the color picker | | `readOnly` | `boolean` | No | Whether the color picker is read-only | | `required` | `boolean` | No | Whether the color picker is required | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **AreaBackground Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaBackground Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-background | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `xChannel` | `ColorChannel` | No | | | `yChannel` | `ColorChannel` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **AreaThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **AreaThumb CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **ChannelInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ExtendedColorChannel` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelInput Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-input | | `[data-channel]` | The color channel of the channelinput | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ChannelSliderLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderLabel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-label | | `[data-channel]` | The color channel of the channelsliderlabel | **ChannelSlider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ColorChannel` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelSlider Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider | | `[data-channel]` | The color channel of the channelslider | | `[data-orientation]` | The orientation of the channelslider | **ChannelSliderThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-thumb | | `[data-channel]` | The color channel of the channelsliderthumb | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the channelsliderthumb | **ChannelSliderTrack Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderTrack Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-track | | `[data-channel]` | The color channel of the channelslidertrack | | `[data-orientation]` | The orientation of the channelslidertrack | **ChannelSliderValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-value-text | | `[data-channel]` | The color channel of the channelslidervaluetext | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | content | | `[data-placement]` | The placement of the content | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-state]` | "open" | "closed" | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested color-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **EyeDropperTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EyeDropperTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | eye-dropper-trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **FormatSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **FormatTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ColorPickerApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **SwatchGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SwatchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Swatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **Swatch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | **Swatch CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **SwatchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the swatch trigger is disabled | **SwatchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch-trigger | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **SwatchTrigger CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **TransparencyGrid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `size` | `string` | No | | **TransparencyGrid CSS Variables:** | Variable | Description | |----------|-------------| | `--size` | The size (width and height) of the element | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **ValueSwatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `format` | `ColorStringFormat` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `format` | `ColorFormat` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the color picker when a swatch is selected | | `defaultFormat` | `ColorFormat` | No | The initial color format when rendered. Use when you don't need to control the color format of the color picker. | | `defaultOpen` | `boolean` | No | The initial open state of the color picker when rendered. Use when you don't need to control the open state of the color picker. | | `defaultValue` | `Color` | No | The initial color value when rendered. Use when you don't need to control the color value of the color picker. | | `disabled` | `boolean` | No | Whether the color picker is disabled | | `format` | `ColorFormat` | No | The controlled color format to use | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; trigger: string; label: string; input: string; hiddenInput: string; content: string; area: string; areaGradient: string; positioner: string; formatSelect: string; areaThumb: string; channelInput: (id: string) => string; channelSliderTrack: (id: ColorChannel) => string; channe...` | No | The ids of the elements in the color picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The initial focus element when the color picker is opened. | | `inline` | `boolean` | No | Whether to render the color picker inline | | `invalid` | `boolean` | No | Whether the color picker is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `name` | `string` | No | The name for the form input | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onFormatChange` | `(details: FormatChangeDetails) => void` | No | Function called when the color format changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Handler that is called when the user opens or closes the color picker. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the value changes, as the user drags. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the user stops dragging. | | `open` | `boolean` | No | The controlled open state of the color picker | | `openAutoFocus` | `boolean` | No | Whether to auto focus the color picker when it is opened | | `positioning` | `PositioningOptions` | No | The positioning options for the color picker | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the color picker is read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the color picker is required | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `Color` | No | The controlled color value of the color picker | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **AreaBackground Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **AreaBackground Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-background | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `xChannel` | `ColorChannel` | No | | | `yChannel` | `ColorChannel` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **AreaThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **AreaThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **AreaThumb CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **ChannelInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ExtendedColorChannel` | Yes | | | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | | `ref` | `Element` | No | | **ChannelInput Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-input | | `[data-channel]` | The color channel of the channelinput | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ChannelSliderLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ChannelSliderLabel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-label | | `[data-channel]` | The color channel of the channelsliderlabel | **ChannelSlider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ColorChannel` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | | `ref` | `Element` | No | | **ChannelSlider Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider | | `[data-channel]` | The color channel of the channelslider | | `[data-orientation]` | The orientation of the channelslider | **ChannelSliderThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ChannelSliderThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-thumb | | `[data-channel]` | The color channel of the channelsliderthumb | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the channelsliderthumb | **ChannelSliderTrack Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ChannelSliderTrack Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-track | | `[data-channel]` | The color channel of the channelslidertrack | | `[data-orientation]` | The orientation of the channelslidertrack | **ChannelSliderValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ChannelSliderValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-value-text | | `[data-channel]` | The color channel of the channelslidervaluetext | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | content | | `[data-placement]` | The placement of the content | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-state]` | "open" | "closed" | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested color-pickers | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseColorPickerContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **EyeDropperTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **EyeDropperTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | eye-dropper-trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **FormatSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **FormatTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseColorPickerReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `ref` | `Element` | No | | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **SwatchGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **SwatchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Swatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **Swatch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | **Swatch CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **SwatchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the swatch trigger is disabled | | `ref` | `Element` | No | | **SwatchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch-trigger | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **SwatchTrigger CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **TransparencyGrid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `size` | `string` | No | | **TransparencyGrid CSS Variables:** | Variable | Description | |----------|-------------| | `--size` | The size (width and height) of the element | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **ValueSwatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `format` | `ColorStringFormat` | No | | | `ref` | `Element` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `format` | `ColorFormat` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `dragging` | `boolean` | Whether the color picker is being dragged | | `open` | `boolean` | Whether the color picker is open | | `inline` | `boolean` | Whether the color picker is rendered inline | | `value` | `Color` | The current color value (as a string) | | `valueAsString` | `string` | The current color value (as a Color object) | | `setValue` | `(value: string | Color) => void` | Function to set the color value | | `getChannelValue` | `(channel: ColorChannel) => string` | Function to set the color value | | `getChannelValueText` | `(channel: ColorChannel, locale: string) => string` | Function to get the formatted and localized value of a specific channel | | `setChannelValue` | `(channel: ColorChannel, value: number) => void` | Function to set the color value of a specific channel | | `format` | `ColorFormat` | The current color format | | `setFormat` | `(format: ColorFormat) => void` | Function to set the color format | | `alpha` | `number` | The alpha value of the color | | `setAlpha` | `(value: number) => void` | Function to set the color alpha | | `setOpen` | `(open: boolean) => void` | Function to open or close the color picker | ## Accessibility ### Keyboard Support **`Enter`** Description: When focus is on the trigger, opens the color picker
                    When focus is on a trigger of a swatch, selects the color (and closes the color picker)
                    When focus is on the input or channel inputs, selects the color
                    **`ArrowLeft`** Description: When focus is on the color area, decreases the hue value of the color
                    When focus is on the channel sliders, decreases the value of the channel
                    **`ArrowRight`** Description: When focus is on the color area, increases the hue value of the color
                    When focus is on the channel sliders, increases the value of the channel
                    **`ArrowUp`** Description: When focus is on the color area, increases the saturation value of the color
                    When focus is on the channel sliders, increases the value of the channel
                    **`ArrowDown`** Description: When focus is on the color area, decreases the saturation value of the color
                    When focus is on the channel sliders, decreases the value of the channel
                    **`Esc`** Description: Closes the color picker and moves focus to the trigger --- # Color Picker (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' export const Basic = () => { return ( Color
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Pipette } from 'lucide-solid' import styles from 'styles/color-picker.module.css' export const Basic = () => { return ( Color
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Color
                    ``` ### Controlled Use the `value` and `onValueChange` props to programatically control the color picker's state. **Example: controlled** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/color-picker.module.css' export const Controlled = () => { const [color, setColor] = useState(() => parseColor('hsl(20, 100%, 50%)')) return (
                    Selected color: {color.toString('hex')} setColor(e.value)}> Color
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Pipette } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/color-picker.module.css' export const Controlled = () => { const [color, setColor] = createSignal(parseColor('hsl(20, 100%, 50%)')) return (
                    Selected color: {color().toString('hex')} setColor(e.value)}> Color
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Selected color: {value.toString('hex')} Color
                    ``` ### Open Controlled Control the open state of the color picker popover programmatically using the `open` and `onOpenChange` props. **Example: open-controlled** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/color-picker.module.css' export const OpenControlled = () => { const [open, setOpen] = useState(false) return (
                    setOpen(e.open)} defaultValue={parseColor('#eb5e41')} > Color
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Pipette } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/color-picker.module.css' export const OpenControlled = () => { const [open, setOpen] = createSignal(false) return (
                    setOpen(e.open)} defaultValue={parseColor('#eb5e41')} > Color
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Color
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { ColorPicker, parseColor, useColorPicker } from '@ark-ui/react/color-picker' import { CheckIcon, PipetteIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const RootProvider = () => { const colorPicker = useColorPicker({ defaultValue: parseColor('#eb5e41') }) return (
                    Color: {colorPicker.valueAsString} Color
                    {swatches.map((color) => ( ))}
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor, useColorPicker } from '@ark-ui/solid/color-picker' import { Check, Pipette } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const RootProvider = () => { const colorPicker = useColorPicker({ defaultValue: parseColor('#eb5e41') }) return (
                    Color: {colorPicker().valueAsString} Color
                    {(color) => ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Color: {colorPicker().valueAsString} Color
                    {#each swatches as color} {/each}
                    ``` ### Disabled Use the `disabled` prop to disable the color picker. **Example: disabled** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import styles from 'styles/color-picker.module.css' export const Disabled = () => { return ( Color
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import styles from 'styles/color-picker.module.css' export const Disabled = () => { return ( Color
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Color
                    ``` ### Inline Render the color picker inline without a popover by using the `inline` prop. **Example: inline** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { CheckIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const Inline = () => { return ( {swatches.map((color) => ( ))} ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Check } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const Inline = () => { return ( {(color) => ( )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each swatches as color} {/each} ``` ### Input Only A minimal color picker with just an input field, value swatch, and eye dropper trigger. **Example: input-only** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' export const InputOnly = () => { return ( Color ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Pipette } from 'lucide-solid' import styles from 'styles/color-picker.module.css' export const InputOnly = () => { return ( Color ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Color ``` ### Slider Only Display only the channel sliders for RGB color selection. **Example: slider-only** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import styles from 'styles/color-picker.module.css' export const SliderOnly = () => { return (
                    R
                    G
                    B
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import styles from 'styles/color-picker.module.css' export const SliderOnly = () => { return (
                    R
                    G
                    B
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    R
                    G
                    B
                    ``` ### Swatch Only A simple color picker with only preset color swatches. **Example: swatch-only** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { CheckIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'pink', 'orange', 'purple'] export const SwatchOnly = () => { return ( Selected color: {swatches.map((color) => ( ))} ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Check } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'pink', 'orange', 'purple'] export const SwatchOnly = () => { return ( Selected color: {(color) => ( )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Selected color: {#each swatches as color} {/each} ``` ### Swatches Include preset color swatches in the color picker content for quick color selection. **Example: swatches** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { CheckIcon, PipetteIcon } from 'lucide-react' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const Swatches = () => { return ( Color
                    {swatches.map((color) => ( ))}
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Check, Pipette } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/color-picker.module.css' const swatches = ['red', 'blue', 'green', 'orange'] export const Swatches = () => { return ( Color
                    {(color) => ( )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Color
                    {#each swatches as color} {/each}
                    ``` ### Value Swatch Display the current color value as a swatch alongside the color area and sliders. **Example: value-swatch** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import styles from 'styles/color-picker.module.css' export const ValueSwatch = () => { return (
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import styles from 'styles/color-picker.module.css' export const ValueSwatch = () => { return (
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    ``` ### 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. **Example: with-field** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { Field } from '@ark-ui/react/field' import field from 'styles/field.module.css' import styles from 'styles/color-picker.module.css' export const WithField = () => ( Label
                    Additional Info Error Info
                    ) ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { Field } from '@ark-ui/solid/field' import field from 'styles/field.module.css' import styles from 'styles/color-picker.module.css' export const WithField = () => ( Label
                    Additional Info Error Info
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    Additional Info Error Info
                    ``` ### Form Usage Integrate the color picker with form libraries like React Hook Form using the `HiddenInput` component. **Example: form-usage** #### React ```tsx import { ColorPicker, parseColor } from '@ark-ui/react/color-picker' import { PipetteIcon } from 'lucide-react' import { useForm } from 'react-hook-form' import button from 'styles/button.module.css' import styles from 'styles/color-picker.module.css' interface FieldValues { color: string } export const FormUsage = () => { const { register, handleSubmit } = useForm() const onSubmit = (data: FieldValues) => { alert(data) } return (
                    ) } ``` #### Solid ```tsx import { ColorPicker, parseColor } from '@ark-ui/solid/color-picker' import { createForm, setValue } from '@modular-forms/solid' import { Pipette } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/color-picker.module.css' export const FormUsage = () => { const [formStore, { Form, Field }] = createForm<{ color: string }>() return (
                    { window.alert(JSON.stringify(data)) }} > {(field) => ( setValue(formStore, 'color', details.valueAsString)} >
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    { e.preventDefault() form.handleSubmit() }} > {#snippet children(field)} field.handleChange(details.valueAsString)} >
                    {/snippet}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the color picker when a swatch is selected | | `defaultFormat` | `ColorFormat` | No | The initial color format when rendered. Use when you don't need to control the color format of the color picker. | | `defaultOpen` | `boolean` | No | The initial open state of the color picker when rendered. Use when you don't need to control the open state of the color picker. | | `defaultValue` | `Color` | No | The initial color value when rendered. Use when you don't need to control the color value of the color picker. | | `disabled` | `boolean` | No | Whether the color picker is disabled | | `format` | `ColorFormat` | No | The controlled color format to use | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; trigger: string; label: string; input: string; hiddenInput: string; content: string; area: string; areaGradient: string; positioner: string; formatSelect: string; areaThumb: string; channelInput: (id: string) => string; channelSliderTrack: (id: ColorChannel) => string; channe...` | No | The ids of the elements in the color picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The initial focus element when the color picker is opened. | | `inline` | `boolean` | No | Whether to render the color picker inline | | `invalid` | `boolean` | No | Whether the color picker is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `name` | `string` | No | The name for the form input | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onFormatChange` | `(details: FormatChangeDetails) => void` | No | Function called when the color format changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Handler that is called when the user opens or closes the color picker. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the value changes, as the user drags. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the user stops dragging. | | `open` | `boolean` | No | The controlled open state of the color picker | | `openAutoFocus` | `boolean` | No | Whether to auto focus the color picker when it is opened | | `positioning` | `PositioningOptions` | No | The positioning options for the color picker | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the color picker is read-only | | `required` | `boolean` | No | Whether the color picker is required | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `Color` | No | The controlled color value of the color picker | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **AreaBackground Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaBackground Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-background | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `xChannel` | `ColorChannel` | No | | | `yChannel` | `ColorChannel` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **AreaThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **AreaThumb CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **ChannelInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ExtendedColorChannel` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelInput Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-input | | `[data-channel]` | The color channel of the channelinput | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ChannelSliderLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderLabel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-label | | `[data-channel]` | The color channel of the channelsliderlabel | **ChannelSlider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ColorChannel` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelSlider Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider | | `[data-channel]` | The color channel of the channelslider | | `[data-orientation]` | The orientation of the channelslider | **ChannelSliderThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-thumb | | `[data-channel]` | The color channel of the channelsliderthumb | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the channelsliderthumb | **ChannelSliderTrack Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderTrack Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-track | | `[data-channel]` | The color channel of the channelslidertrack | | `[data-orientation]` | The orientation of the channelslidertrack | **ChannelSliderValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-value-text | | `[data-channel]` | The color channel of the channelslidervaluetext | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | content | | `[data-placement]` | The placement of the content | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-state]` | "open" | "closed" | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested color-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **EyeDropperTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EyeDropperTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | eye-dropper-trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **FormatSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **FormatTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseColorPickerReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **SwatchGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SwatchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Swatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **Swatch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | **Swatch CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **SwatchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the swatch trigger is disabled | **SwatchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch-trigger | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **SwatchTrigger CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **TransparencyGrid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `size` | `string` | No | | **TransparencyGrid CSS Variables:** | Variable | Description | |----------|-------------| | `--size` | The size (width and height) of the element | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **ValueSwatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `format` | `ColorStringFormat` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `format` | `ColorFormat` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the color picker when a swatch is selected | | `defaultFormat` | `ColorFormat` | No | The initial color format when rendered. Use when you don't need to control the color format of the color picker. | | `defaultOpen` | `boolean` | No | The initial open state of the color picker when rendered. Use when you don't need to control the open state of the color picker. | | `defaultValue` | `Color` | No | The initial color value when rendered. Use when you don't need to control the color value of the color picker. | | `disabled` | `boolean` | No | Whether the color picker is disabled | | `format` | `ColorFormat` | No | The controlled color format to use | | `ids` | `Partial<{ root: string; control: string; trigger: string; label: string; input: string; hiddenInput: string; content: string; area: string; areaGradient: string; positioner: string; formatSelect: string; areaThumb: string; channelInput: (id: string) => string; channelSliderTrack: (id: ColorChannel) => string; channe...` | No | The ids of the elements in the color picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The initial focus element when the color picker is opened. | | `inline` | `boolean` | No | Whether to render the color picker inline | | `invalid` | `boolean` | No | Whether the color picker is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `name` | `string` | No | The name for the form input | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onFormatChange` | `(details: FormatChangeDetails) => void` | No | Function called when the color format changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Handler that is called when the user opens or closes the color picker. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the value changes, as the user drags. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the user stops dragging. | | `open` | `boolean` | No | The controlled open state of the color picker | | `openAutoFocus` | `boolean` | No | Whether to auto focus the color picker when it is opened | | `positioning` | `PositioningOptions` | No | The positioning options for the color picker | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the color picker is read-only | | `required` | `boolean` | No | Whether the color picker is required | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `Color` | No | The controlled color value of the color picker | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **AreaBackground Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaBackground Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-background | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `xChannel` | `ColorChannel` | No | | | `yChannel` | `ColorChannel` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **AreaThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **AreaThumb CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **ChannelInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ExtendedColorChannel` | Yes | | | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelInput Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-input | | `[data-channel]` | The color channel of the channelinput | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ChannelSliderLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderLabel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-label | | `[data-channel]` | The color channel of the channelsliderlabel | **ChannelSlider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ColorChannel` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelSlider Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider | | `[data-channel]` | The color channel of the channelslider | | `[data-orientation]` | The orientation of the channelslider | **ChannelSliderThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-thumb | | `[data-channel]` | The color channel of the channelsliderthumb | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the channelsliderthumb | **ChannelSliderTrack Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderTrack Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-track | | `[data-channel]` | The color channel of the channelslidertrack | | `[data-orientation]` | The orientation of the channelslidertrack | **ChannelSliderValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-value-text | | `[data-channel]` | The color channel of the channelslidervaluetext | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | content | | `[data-placement]` | The placement of the content | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-state]` | "open" | "closed" | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested color-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **EyeDropperTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EyeDropperTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | eye-dropper-trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **FormatSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **FormatTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseColorPickerReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **SwatchGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SwatchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Swatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **Swatch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | **Swatch CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **SwatchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the swatch trigger is disabled | **SwatchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch-trigger | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **SwatchTrigger CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **TransparencyGrid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `size` | `string` | No | | **TransparencyGrid CSS Variables:** | Variable | Description | |----------|-------------| | `--size` | The size (width and height) of the element | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **ValueSwatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `format` | `ColorStringFormat` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `format` | `ColorFormat` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the color picker when a swatch is selected | | `defaultFormat` | `ColorFormat` | No | The initial color format when rendered. Use when you don't need to control the color format of the color picker. | | `defaultOpen` | `boolean` | No | The initial open state of the color picker when rendered. Use when you don't need to control the open state of the color picker. | | `defaultValue` | `Color` | No | The initial color value when rendered. Use when you don't need to control the color value of the color picker. | | `disabled` | `boolean` | No | Whether the color picker is disabled | | `format` | `ColorFormat` | No | The controlled color format to use | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; trigger: string; label: string; input: string; hiddenInput: string; content: string; area: string; areaGradient: string; positioner: string; formatSelect: string; areaThumb: string; channelInput(id: string): string; channelSliderTrack(id: ColorChannel): string; channelSliderT...` | No | The ids of the elements in the color picker. Useful for composition. | | `initialFocusEl` | `() => HTMLElement | null` | No | The initial focus element when the color picker is opened. | | `inline` | `boolean` | No | Whether the color picker is inline | | `invalid` | `boolean` | No | Whether the color picker is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modelValue` | `Color` | No | The v-model value of the color picker | | `name` | `string` | No | The name for the form input | | `open` | `boolean` | No | The controlled open state of the color picker | | `openAutoFocus` | `boolean` | No | Whether to auto focus the color picker when it is opened | | `positioning` | `PositioningOptions` | No | The positioning options for the color picker | | `readOnly` | `boolean` | No | Whether the color picker is read-only | | `required` | `boolean` | No | Whether the color picker is required | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **AreaBackground Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaBackground Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-background | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `xChannel` | `ColorChannel` | No | | | `yChannel` | `ColorChannel` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **AreaThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **AreaThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **AreaThumb CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **ChannelInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ExtendedColorChannel` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelInput Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-input | | `[data-channel]` | The color channel of the channelinput | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ChannelSliderLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderLabel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-label | | `[data-channel]` | The color channel of the channelsliderlabel | **ChannelSlider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ColorChannel` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **ChannelSlider Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider | | `[data-channel]` | The color channel of the channelslider | | `[data-orientation]` | The orientation of the channelslider | **ChannelSliderThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-thumb | | `[data-channel]` | The color channel of the channelsliderthumb | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the channelsliderthumb | **ChannelSliderTrack Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderTrack Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-track | | `[data-channel]` | The color channel of the channelslidertrack | | `[data-orientation]` | The orientation of the channelslidertrack | **ChannelSliderValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ChannelSliderValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-value-text | | `[data-channel]` | The color channel of the channelslidervaluetext | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | content | | `[data-placement]` | The placement of the content | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-state]` | "open" | "closed" | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested color-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **EyeDropperTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EyeDropperTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | eye-dropper-trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **FormatSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **FormatTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ColorPickerApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **SwatchGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SwatchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Swatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **Swatch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | **Swatch CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **SwatchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the swatch trigger is disabled | **SwatchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch-trigger | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **SwatchTrigger CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **TransparencyGrid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `size` | `string` | No | | **TransparencyGrid CSS Variables:** | Variable | Description | |----------|-------------| | `--size` | The size (width and height) of the element | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **ValueSwatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `format` | `ColorStringFormat` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `format` | `ColorFormat` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the color picker when a swatch is selected | | `defaultFormat` | `ColorFormat` | No | The initial color format when rendered. Use when you don't need to control the color format of the color picker. | | `defaultOpen` | `boolean` | No | The initial open state of the color picker when rendered. Use when you don't need to control the open state of the color picker. | | `defaultValue` | `Color` | No | The initial color value when rendered. Use when you don't need to control the color value of the color picker. | | `disabled` | `boolean` | No | Whether the color picker is disabled | | `format` | `ColorFormat` | No | The controlled color format to use | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; trigger: string; label: string; input: string; hiddenInput: string; content: string; area: string; areaGradient: string; positioner: string; formatSelect: string; areaThumb: string; channelInput: (id: string) => string; channelSliderTrack: (id: ColorChannel) => string; channe...` | No | The ids of the elements in the color picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The initial focus element when the color picker is opened. | | `inline` | `boolean` | No | Whether to render the color picker inline | | `invalid` | `boolean` | No | Whether the color picker is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `name` | `string` | No | The name for the form input | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onFormatChange` | `(details: FormatChangeDetails) => void` | No | Function called when the color format changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Handler that is called when the user opens or closes the color picker. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the value changes, as the user drags. | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Handler that is called when the user stops dragging. | | `open` | `boolean` | No | The controlled open state of the color picker | | `openAutoFocus` | `boolean` | No | Whether to auto focus the color picker when it is opened | | `positioning` | `PositioningOptions` | No | The positioning options for the color picker | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the color picker is read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the color picker is required | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `Color` | No | The controlled color value of the color picker | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **AreaBackground Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **AreaBackground Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-background | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `xChannel` | `ColorChannel` | No | | | `yChannel` | `ColorChannel` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **AreaThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **AreaThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | area-thumb | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **AreaThumb CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **ChannelInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ExtendedColorChannel` | Yes | | | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | | `ref` | `Element` | No | | **ChannelInput Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-input | | `[data-channel]` | The color channel of the channelinput | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ChannelSliderLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ChannelSliderLabel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-label | | `[data-channel]` | The color channel of the channelsliderlabel | **ChannelSlider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `channel` | `ColorChannel` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | | `ref` | `Element` | No | | **ChannelSlider Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider | | `[data-channel]` | The color channel of the channelslider | | `[data-orientation]` | The orientation of the channelslider | **ChannelSliderThumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ChannelSliderThumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-thumb | | `[data-channel]` | The color channel of the channelsliderthumb | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the channelsliderthumb | **ChannelSliderTrack Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ChannelSliderTrack Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-track | | `[data-channel]` | The color channel of the channelslidertrack | | `[data-orientation]` | The orientation of the channelslidertrack | **ChannelSliderValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ChannelSliderValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | channel-slider-value-text | | `[data-channel]` | The color channel of the channelslidervaluetext | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | content | | `[data-placement]` | The placement of the content | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-state]` | "open" | "closed" | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested color-pickers | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseColorPickerContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **EyeDropperTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **EyeDropperTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | eye-dropper-trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **FormatSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **FormatTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseColorPickerReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `ref` | `Element` | No | | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **SwatchGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **SwatchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Swatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **Swatch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | **Swatch CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **SwatchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string | Color` | Yes | The color value | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the swatch trigger is disabled | | `ref` | `Element` | No | | **SwatchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | swatch-trigger | | `[data-state]` | "checked" | "unchecked" | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **SwatchTrigger CSS Variables:** | Variable | Description | |----------|-------------| | `--color` | The text color | **TransparencyGrid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `size` | `string` | No | | **TransparencyGrid CSS Variables:** | Variable | Description | |----------|-------------| | `--size` | The size (width and height) of the element | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | **ValueSwatch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `respectAlpha` | `boolean` | No | Whether to include the alpha channel in the color | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `format` | `ColorStringFormat` | No | | | `ref` | `Element` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | color-picker | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `format` | `ColorFormat` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `dragging` | `boolean` | Whether the color picker is being dragged | | `open` | `boolean` | Whether the color picker is open | | `inline` | `boolean` | Whether the color picker is rendered inline | | `value` | `Color` | The current color value (as a string) | | `valueAsString` | `string` | The current color value (as a Color object) | | `setValue` | `(value: string | Color) => void` | Function to set the color value | | `getChannelValue` | `(channel: ColorChannel) => string` | Function to set the color value | | `getChannelValueText` | `(channel: ColorChannel, locale: string) => string` | Function to get the formatted and localized value of a specific channel | | `setChannelValue` | `(channel: ColorChannel, value: number) => void` | Function to set the color value of a specific channel | | `format` | `ColorFormat` | The current color format | | `setFormat` | `(format: ColorFormat) => void` | Function to set the color format | | `alpha` | `number` | The alpha value of the color | | `setAlpha` | `(value: number) => void` | Function to set the color alpha | | `setOpen` | `(open: boolean) => void` | Function to open or close the color picker | ## Accessibility ### Keyboard Support **`Enter`** Description: When focus is on the trigger, opens the color picker
                    When focus is on a trigger of a swatch, selects the color (and closes the color picker)
                    When focus is on the input or channel inputs, selects the color
                    **`ArrowLeft`** Description: When focus is on the color area, decreases the hue value of the color
                    When focus is on the channel sliders, decreases the value of the channel
                    **`ArrowRight`** Description: When focus is on the color area, increases the hue value of the color
                    When focus is on the channel sliders, increases the value of the channel
                    **`ArrowUp`** Description: When focus is on the color area, increases the saturation value of the color
                    When focus is on the channel sliders, increases the value of the channel
                    **`ArrowDown`** Description: When focus is on the color area, decreases the saturation value of the color
                    When focus is on the channel sliders, decreases the value of the channel
                    **`Esc`** Description: Closes the color picker and moves focus to the trigger --- # Combobox (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const Basic = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }, { label: 'Orange', value: 'orange' }, { label: 'Mango', value: 'mango' }, { label: 'Pineapple', value: 'pineapple' }, { label: 'Strawberry', value: 'strawberry' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Favorite Fruit
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const Basic = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }, { label: 'Orange', value: 'orange' }, { label: 'Mango', value: 'mango' }, { label: 'Pineapple', value: 'pineapple' }, { label: 'Strawberry', value: 'strawberry' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Favorite Fruit
                    {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Fruit
                    Clear Open
                    No results found {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Auto Highlight Automatically highlight the first matching item as the user types by setting `inputBehavior="autohighlight"`. **Example: auto-highlight** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const AutoHighlight = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Engineering', value: 'engineering' }, { label: 'Marketing', value: 'marketing' }, { label: 'Sales', value: 'sales' }, { label: 'Finance', value: 'finance' }, { label: 'Human Resources', value: 'hr' }, { label: 'Operations', value: 'operations' }, { label: 'Product', value: 'product' }, { label: 'Customer Success', value: 'customer-success' }, { label: 'Legal', value: 'legal' }, { label: 'Information Technology', value: 'information-technology' }, { label: 'Design', value: 'design' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Department
                    No results found {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const AutoHighlight = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Engineering', value: 'engineering' }, { label: 'Marketing', value: 'marketing' }, { label: 'Sales', value: 'sales' }, { label: 'Finance', value: 'finance' }, { label: 'Human Resources', value: 'hr' }, { label: 'Operations', value: 'operations' }, { label: 'Product', value: 'product' }, { label: 'Customer Success', value: 'customer-success' }, { label: 'Legal', value: 'legal' }, { label: 'Information Technology', value: 'information-technology' }, { label: 'Design', value: 'design' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Department
                    Clear Open
                    No results found {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Department
                    Clear Open
                    No results found {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Inline Autocomplete Complete the input value with the first matching item by setting `inputBehavior="autocomplete"`. Use with `startsWith` filter for best results. **Example: inline-autocomplete** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const InlineAutocomplete = () => { const { startsWith } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Whale', value: 'whale' }, { label: 'Dolphin', value: 'dolphin' }, { label: 'Shark', value: 'shark' }, { label: 'Octopus', value: 'octopus' }, { label: 'Jellyfish', value: 'jellyfish' }, { label: 'Seahorse', value: 'seahorse' }, ], filter: startsWith, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Sea Creature
                    No results found {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const InlineAutocomplete = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Whale', value: 'whale' }, { label: 'Dolphin', value: 'dolphin' }, { label: 'Shark', value: 'shark' }, { label: 'Octopus', value: 'octopus' }, { label: 'Jellyfish', value: 'jellyfish' }, { label: 'Seahorse', value: 'seahorse' }, ], filter: filterFn().startsWith, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Sea Creature
                    Clear Open
                    No results found {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Sea Creature
                    Clear Open
                    No results found {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Grouping To group related combobox items, use the `groupBy` prop on the collection and `collection.group()` to iterate the groups. **Example: grouping** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const Grouping = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: contains, groupBy: (item) => item.continent, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {collection.group().map(([continent, group]) => ( {continent} {group.map((item) => ( {item.label} ))} ))}
                    ) } const initialItems = [ { label: 'Canada', value: 'ca', continent: 'North America' }, { label: 'United States', value: 'us', continent: 'North America' }, { label: 'Mexico', value: 'mx', continent: 'North America' }, { label: 'United Kingdom', value: 'uk', continent: 'Europe' }, { label: 'Germany', value: 'de', continent: 'Europe' }, { label: 'France', value: 'fr', continent: 'Europe' }, { label: 'Japan', value: 'jp', continent: 'Asia' }, { label: 'South Korea', value: 'kr', continent: 'Asia' }, { label: 'China', value: 'cn', continent: 'Asia' }, ] ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' const initialItems = [ { label: 'Canada', value: 'ca', continent: 'North America' }, { label: 'United States', value: 'us', continent: 'North America' }, { label: 'Mexico', value: 'mx', continent: 'North America' }, { label: 'United Kingdom', value: 'uk', continent: 'Europe' }, { label: 'Germany', value: 'de', continent: 'Europe' }, { label: 'France', value: 'fr', continent: 'Europe' }, { label: 'Japan', value: 'jp', continent: 'Asia' }, { label: 'South Korea', value: 'kr', continent: 'Asia' }, { label: 'China', value: 'cn', continent: 'Asia' }, ] export const Grouping = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: filterFn().contains, groupBy: (item) => item.continent, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {([continent, group]) => ( {continent} {(item) => ( {item.label} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Country
                    Clear Open
                    {#each collection().group() as [continent, group]} {continent} {#each group as item} {item.label} {/each} {/each}
                    ``` ### Field The `Field` component helps manage form-related state and accessibility attributes of a combobox. It includes handling ARIA labels, helper text, and error text to ensure proper accessibility. **Example: with-field** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { Field } from '@ark-ui/react/field' import { useFilter } from '@ark-ui/react/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' import field from 'styles/field.module.css' export const WithField = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Department
                    {collection.items.map((item) => ( {item.label} ))}
                    Select your primary department Department is required
                    ) } const initialItems = [ { label: 'Engineering', value: 'engineering' }, { label: 'Design', value: 'design' }, { label: 'Marketing', value: 'marketing' }, { label: 'Sales', value: 'sales' }, { label: 'Human Resources', value: 'hr' }, { label: 'Finance', value: 'finance' }, ] ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { Field } from '@ark-ui/solid/field' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import styles from 'styles/combobox.module.css' import field from 'styles/field.module.css' const initialItems = [ { label: 'Engineering', value: 'engineering' }, { label: 'Design', value: 'design' }, { label: 'Marketing', value: 'marketing' }, { label: 'Sales', value: 'sales' }, { label: 'Human Resources', value: 'hr' }, { label: 'Finance', value: 'finance' }, ] export const WithField = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Department
                    Clear Open
                    {(item) => ( {item.label} )}
                    Select your primary department Department is required
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Department
                    Clear Open
                    {#each collection().items as item (item.value)} {item.label} {/each}
                    Select your primary department Department is required
                    ``` ### Context Use the `Combobox.Context` component to access the combobox state and display information like the selected value. **Example: context** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const Context = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Small', value: 'sm' }, { label: 'Medium', value: 'md' }, { label: 'Large', value: 'lg' }, { label: 'Extra Large', value: 'xl' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( {(combobox) =>

                    Selected: {combobox.valueAsString || 'None'}

                    }
                    Size
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const Context = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Small', value: 'sm' }, { label: 'Medium', value: 'md' }, { label: 'Large', value: 'lg' }, { label: 'Extra Large', value: 'xl' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( {(context) =>

                    Selected: {context().valueAsString || 'None'}

                    }
                    Size
                    {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(combobox)}

                    Selected: {combobox().valueAsString || 'None'}

                    {/snippet}
                    Size
                    Clear Open
                    {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Root Provider An alternative way to control the combobox is to use the `RootProvider` component and the `useCombobox` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { Combobox, useCombobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/combobox.module.css' const initialItems = [ { label: 'Designer', value: 'designer' }, { label: 'Developer', value: 'developer' }, { label: 'Product Manager', value: 'pm' }, { label: 'Data Scientist', value: 'data-scientist' }, { label: 'DevOps Engineer', value: 'devops' }, { label: 'Marketing Lead', value: 'marketing' }, ] export const RootProvider = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: contains, }) const combobox = useCombobox({ collection, onInputValueChange(details) { filter(details.inputValue) }, }) return (
                    Job Title
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useCombobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/combobox.module.css' const initialItems = [ { label: 'Designer', value: 'designer' }, { label: 'Developer', value: 'developer' }, { label: 'Product Manager', value: 'pm' }, { label: 'Data Scientist', value: 'data-scientist' }, { label: 'DevOps Engineer', value: 'devops' }, { label: 'Marketing Lead', value: 'marketing' }, ] export const RootProvider = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: filterFn().contains, }) const combobox = useCombobox({ get collection() { return collection() }, onInputValueChange(details) { filter(details.inputValue) }, }) return (
                    Job Title
                    {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Job Title
                    Clear Open
                    {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Links Use the `asChild` prop to render the combobox items as links. **Example: links** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const Links = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Developer Resources
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } const initialItems = [ { label: 'GitHub', href: 'https://github.com', value: 'github' }, { label: 'Stack Overflow', href: 'https://stackoverflow.com', value: 'stackoverflow' }, { label: 'MDN Web Docs', href: 'https://developer.mozilla.org', value: 'mdn' }, { label: 'npm', href: 'https://www.npmjs.com', value: 'npm' }, { label: 'TypeScript', href: 'https://www.typescriptlang.org', value: 'typescript' }, { label: 'React', href: 'https://react.dev', value: 'react' }, ] ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' const initialItems = [ { label: 'GitHub', href: 'https://github.com', value: 'github' }, { label: 'Stack Overflow', href: 'https://stackoverflow.com', value: 'stackoverflow' }, { label: 'MDN Web Docs', href: 'https://developer.mozilla.org', value: 'mdn' }, { label: 'npm', href: 'https://www.npmjs.com', value: 'npm' }, { label: 'TypeScript', href: 'https://www.typescriptlang.org', value: 'typescript' }, { label: 'React', href: 'https://react.dev', value: 'react' }, ] export const Links = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Developer Resources
                    {(item) => ( }> {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Developer Resources
                    Open
                    {#each collection().items as item (item.value)} {#snippet asChild(props)}
                    {item.label} {/snippet} {/each} ``` ### Rehydrate When a combobox has a `defaultValue` or `value` but the `collection` is not loaded yet, you can rehydrate the value to populate the input. **Example: rehydrate-value** #### React ```tsx import { Combobox, useCombobox, useComboboxContext, useListCollection } from '@ark-ui/react/combobox' import { Portal } from '@ark-ui/react/portal' import { CheckIcon } from 'lucide-react' import { useRef, useState } from 'react' import { useAsync } from 'react-use' import styles from 'styles/combobox.module.css' function ComboboxRehydrateValue() { const combobox = useComboboxContext() const hydrated = useRef(false) if (combobox.value.length && combobox.collection.size && !hydrated.current) { combobox.syncSelectedItems() hydrated.current = true } return null } export const RehydrateValue = () => { const [inputValue, setInputValue] = useState('') const { collection, set } = useListCollection({ initialItems: [], itemToString: (item) => item.name, itemToValue: (item) => item.name, }) const combobox = useCombobox({ collection, defaultValue: ['C-3PO'], placeholder: 'Example: Dexter', inputValue, onInputValueChange: (e) => setInputValue(e.inputValue), }) const state = useAsync(async () => { const response = await fetch(`https://swapi.py4e.com/api/people/?search=${inputValue}`) const data = await response.json() set(data.results) }, [inputValue, set]) return ( Search Star Wars Characters {state.loading ? ( Loading... ) : state.error ? ( {state.error.message} ) : ( collection.items.map((item) => ( {item.name} - {item.height}cm / {item.mass}kg )) )} ) } interface Character { name: string height: string mass: string created: string edited: string url: string } ``` #### Solid ```tsx import { Combobox, useCombobox, useComboboxContext, useListCollection } from '@ark-ui/solid/combobox' import { For, createEffect, createRenderEffect, createSignal, on } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' import { useAsync } from './use-async' function ComboboxRehydrateValue() { const combobox = useComboboxContext() let hydrated = false createRenderEffect(() => { if (combobox().value.length && combobox().collection.size && !hydrated) { combobox().syncSelectedItems() hydrated = true } }) return null } export const RehydrateValue = () => { const [inputValue, setInputValue] = createSignal('') const { collection, set } = useListCollection({ initialItems: [], itemToString: (item) => item.name, itemToValue: (item) => item.name, }) const combobox = useCombobox(() => ({ collection: collection(), defaultValue: ['C-3PO'], placeholder: 'Example: Dexter', inputValue: inputValue(), onInputValueChange: (e) => setInputValue(e.inputValue), })) const state = useAsync(async (signal) => { const response = await fetch(`https://swapi.py4e.com/api/people/?search=${inputValue()}`, { signal }) const data = await response.json() set(data.results) }) createEffect(on(inputValue, () => state.load())) return ( Search Star Wars Characters {state.loading() ? ( Loading... ) : state.error() ? ( {state.error()?.message} ) : ( {(item) => ( {item.name} - {item.height}cm / {item.mass}kg )} )} ) } interface Character { name: string height: string mass: string created: string edited: string url: string } ``` #### Vue ```vue ``` #### Svelte ```svelte Search Star Wars Characters {#if _state.loading()} Loading... {:else if _state.error()} {_state.error()?.message} {:else} {#each collection().items as item (item.name)} {item.name} - {item.height}cm / {item.mass}kg {/each} {/if} ``` ### Highlight Text Highlight the matching search text in combobox items based on the user's input. **Example: highlight-matching-text** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { Highlight } from '@ark-ui/react/highlight' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const HighlightMatchingText = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'John Smith', value: 'john-smith' }, { label: 'Jane Doe', value: 'jane-doe' }, { label: 'Bob Johnson', value: 'bob-johnson' }, { label: 'Alice Williams', value: 'alice-williams' }, { label: 'Charlie Brown', value: 'charlie-brown' }, { label: 'Diana Ross', value: 'diana-ross' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Assignee
                    {collection.items.map((item) => ( {(context) => } ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { Highlight } from '@ark-ui/solid/highlight' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const HighlightMatchingText = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'John Smith', value: 'john-smith' }, { label: 'Jane Doe', value: 'jane-doe' }, { label: 'Bob Johnson', value: 'bob-johnson' }, { label: 'Alice Williams', value: 'alice-williams' }, { label: 'Charlie Brown', value: 'charlie-brown' }, { label: 'Diana Ross', value: 'diana-ross' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Assignee
                    Clear Open
                    {(item) => ( {(context) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Assignee
                    Clear Open
                    {#each collection().items as item (item.value)} {#snippet render(context)} {/snippet} {/each}
                    ``` ### Dynamic Generate combobox items dynamically based on user input. This is useful for creating suggestions or autocomplete functionality. **Example: dynamic** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' const suggestList = ['gmail.com', 'yahoo.com', 'ark-ui.com'] export const Dynamic = () => { const { collection, set } = useListCollection({ initialItems: [], }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { if (details.reason === 'input-change') { const items = suggestList.map((item) => `${details.inputValue}@${item}`) set(items) } } return ( Email
                    {collection.items.map((item) => ( {item} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' const suggestList = ['gmail.com', 'yahoo.com', 'ark-ui.com'] export const Dynamic = () => { const { collection, set } = useListCollection({ initialItems: [], }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { if (details.reason === 'input-change') { const items = suggestList.map((item) => `${details.inputValue}@${item}`) set(items) } } return ( Email
                    Open
                    {(item) => ( {item} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Email
                    Open
                    {#each collection().items as item (item)} {item} {/each}
                    ``` ### 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. **Example: creatable** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import { flushSync } from 'react-dom' import styles from 'styles/combobox.module.css' interface Item { label: string value: string __new__?: boolean } const NEW_OPTION_VALUE = '[[new]]' const createNewOption = (value: string): Item => ({ label: value, value: NEW_OPTION_VALUE }) const isNewOptionValue = (value: string) => value === NEW_OPTION_VALUE const replaceNewOptionValue = (values: string[], value: string) => values.map((v) => (v === NEW_OPTION_VALUE ? value : v)) const getNewOptionData = (inputValue: string): Item => ({ label: inputValue, value: inputValue, __new__: true }) export const Creatable = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter, upsert, update, remove } = useListCollection({ initialItems: [ { label: 'Bug', value: 'bug' }, { label: 'Feature', value: 'feature' }, { label: 'Enhancement', value: 'enhancement' }, { label: 'Documentation', value: 'docs' }, ], filter: contains, }) const isValidNewOption = (inputValue: string) => { const exactOptionMatch = collection.filter((item) => item.toLowerCase() === inputValue.toLowerCase()).size > 0 return !exactOptionMatch && inputValue.trim().length > 0 } const [selectedValue, setSelectedValue] = useState([]) const [inputValue, setInputValue] = useState('') const handleInputChange = ({ inputValue, reason }: Combobox.InputValueChangeDetails) => { if (reason === 'input-change' || reason === 'item-select') { flushSync(() => { if (isValidNewOption(inputValue)) { upsert(NEW_OPTION_VALUE, createNewOption(inputValue)) } else if (inputValue.trim().length === 0) { remove(NEW_OPTION_VALUE) } }) filter(inputValue) } setInputValue(inputValue) } const handleOpenChange = ({ reason }: Combobox.OpenChangeDetails) => { if (reason === 'trigger-click') { filter('') } } const handleValueChange = ({ value }: Combobox.ValueChangeDetails) => { setSelectedValue(replaceNewOptionValue(value, inputValue)) if (value.includes(NEW_OPTION_VALUE)) { console.log('New Option Created', inputValue) update(NEW_OPTION_VALUE, getNewOptionData(inputValue)) } } return ( Label
                    {collection.items.map((item) => ( {isNewOptionValue(item.value) ? ( + Create "{item.label}" ) : ( {item.label} {item.__new__ ? '(new)' : ''} )} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { createSignal, For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' interface Item { label: string value: string __new__?: boolean } const NEW_OPTION_VALUE = '[[new]]' const createNewOption = (value: string): Item => ({ label: value, value: NEW_OPTION_VALUE }) const isNewOptionValue = (value: string) => value === NEW_OPTION_VALUE const replaceNewOptionValue = (values: string[], value: string) => values.map((v) => (v === NEW_OPTION_VALUE ? value : v)) const getNewOptionData = (inputValue: string): Item => ({ label: inputValue, value: inputValue, __new__: true }) export const Creatable = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter, upsert, update, remove } = useListCollection({ initialItems: [ { label: 'Bug', value: 'bug' }, { label: 'Feature', value: 'feature' }, { label: 'Enhancement', value: 'enhancement' }, { label: 'Documentation', value: 'docs' }, ], filter: filterFn().contains, }) const isValidNewOption = (inputValue: string) => { const exactOptionMatch = collection().items.filter((item) => item.label.toLowerCase() === inputValue.toLowerCase()).length > 0 return !exactOptionMatch && inputValue.trim().length > 0 } const [selectedValue, setSelectedValue] = createSignal([]) const [inputValue, setInputValue] = createSignal('') const handleInputChange = ({ inputValue: newInputValue, reason }: Combobox.InputValueChangeDetails) => { if (reason === 'input-change' || reason === 'item-select') { if (isValidNewOption(newInputValue)) { upsert(NEW_OPTION_VALUE, createNewOption(newInputValue)) } else if (newInputValue.trim().length === 0) { remove(NEW_OPTION_VALUE) } filter(newInputValue) } setInputValue(newInputValue) } const handleOpenChange = ({ reason }: Combobox.OpenChangeDetails) => { if (reason === 'trigger-click') { filter('') } } const handleValueChange = ({ value }: Combobox.ValueChangeDetails) => { setSelectedValue(replaceNewOptionValue(value, inputValue())) if (value.includes(NEW_OPTION_VALUE)) { console.log('New Option Created', inputValue()) update(NEW_OPTION_VALUE, getNewOptionData(inputValue())) } } return ( Label
                    Clear Open
                    {(item) => ( {isNewOptionValue(item.value) ? ( + Create "{item.label}" ) : ( {item.label} {item.__new__ ? '(new)' : ''} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    Clear Open
                    {#each collection().items as item (item.value)} {#if isNewOptionValue(item.value)} + Create "{item.label}" {:else} {item.label} {item.__new__ ? '(new)' : ''} {/if} {/each}
                    ``` ### Multiple Selection Enable multiple selection by setting the `multiple` prop. Selected items can be displayed as tags above the input. **Example: multiple** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import { useRef } from 'react' import styles from 'styles/combobox.module.css' export const Multiple = () => { const { contains } = useFilter({ sensitivity: 'base' }) const selectedValue = useRef([]) const { collection, filter, remove } = useListCollection({ initialItems: [ { label: 'JavaScript', value: 'js' }, { label: 'TypeScript', value: 'ts' }, { label: 'Python', value: 'python' }, { label: 'Go', value: 'go' }, { label: 'Rust', value: 'rust' }, { label: 'Java', value: 'java' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } const handleValueChange = (details: Combobox.ValueChangeDetails) => { selectedValue.current = details.value remove(...details.value) } return ( Skills {(combobox) => (
                    {combobox.selectedItems.length === 0 && None selected} {combobox.selectedItems.map((item: any) => ( {item.label} ))}
                    )}
                    No skills found {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const Multiple = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter, remove } = useListCollection({ initialItems: [ { label: 'JavaScript', value: 'js' }, { label: 'TypeScript', value: 'ts' }, { label: 'Python', value: 'python' }, { label: 'Go', value: 'go' }, { label: 'Rust', value: 'rust' }, { label: 'Java', value: 'java' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } const handleValueChange = (details: Combobox.ValueChangeDetails) => { remove(...details.value) } return ( Skills {(context) => (
                    {context().selectedItems.length === 0 && None selected} {(item: any) => {item.label}}
                    )}
                    No skills found {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Skills
                    {#if selectedItems.length === 0} None selected {/if} {#each selectedItems as item (item.value)} {item.label} {/each}
                    Open
                    No skills found {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### 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. **Example: async-search** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { Combobox, createListCollection } from '@ark-ui/react/combobox' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, LoaderIcon, XIcon } from 'lucide-react' import { startTransition } from 'react' import styles from 'styles/combobox.module.css' interface Movie { id: string title: string year: number director: string genre: string } export const AsyncSearch = () => { const list = useAsyncList({ async load({ filterText, signal }) { if (!filterText) return { items: [] } await new Promise((resolve) => setTimeout(resolve, 300)) if (signal?.aborted) return { items: [] } const items = allMovies.filter( (movie) => movie.title.toLowerCase().includes(filterText.toLowerCase()) || movie.director.toLowerCase().includes(filterText.toLowerCase()) || movie.genre.toLowerCase().includes(filterText.toLowerCase()), ) return { items } }, }) const collection = createListCollection({ items: list.items, itemToString: (item) => item.title, itemToValue: (item) => item.id, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { if (details.reason === 'input-change') { startTransition(() => { list.setFilterText(details.inputValue) }) } } return ( Movie
                    {list.loading ? (
                    Searching...
                    ) : list.error ? (
                    {list.error.message}
                    ) : list.items.length === 0 ? (
                    {list.filterText ? 'No results found' : 'Start typing to search movies...'}
                    ) : ( collection.items.map((movie) => ( {movie.title} {movie.year} · {movie.director} )) )}
                    ) } const allMovies: Movie[] = [ { id: 'inception', title: 'Inception', year: 2010, director: 'Christopher Nolan', genre: 'Sci-Fi' }, { id: 'the-dark-knight', title: 'The Dark Knight', year: 2008, director: 'Christopher Nolan', genre: 'Action' }, { id: 'pulp-fiction', title: 'Pulp Fiction', year: 1994, director: 'Quentin Tarantino', genre: 'Crime' }, { id: 'the-godfather', title: 'The Godfather', year: 1972, director: 'Francis Ford Coppola', genre: 'Crime' }, { id: 'forrest-gump', title: 'Forrest Gump', year: 1994, director: 'Robert Zemeckis', genre: 'Drama' }, { id: 'the-matrix', title: 'The Matrix', year: 1999, director: 'The Wachowskis', genre: 'Sci-Fi' }, { id: 'interstellar', title: 'Interstellar', year: 2014, director: 'Christopher Nolan', genre: 'Sci-Fi' }, { id: 'parasite', title: 'Parasite', year: 2019, director: 'Bong Joon-ho', genre: 'Thriller' }, { id: 'the-shawshank-redemption', title: 'The Shawshank Redemption', year: 1994, director: 'Frank Darabont', genre: 'Drama', }, { id: 'fight-club', title: 'Fight Club', year: 1999, director: 'David Fincher', genre: 'Drama' }, { id: 'goodfellas', title: 'Goodfellas', year: 1990, director: 'Martin Scorsese', genre: 'Crime' }, { id: 'the-silence-of-the-lambs', title: 'The Silence of the Lambs', year: 1991, director: 'Jonathan Demme', genre: 'Thriller', }, ] ``` ### 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. **Example: virtualized** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { useVirtualizer } from '@tanstack/react-virtual' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import { useRef } from 'react' import { flushSync } from 'react-dom' import styles from 'styles/combobox.module.css' export const Virtualized = () => { const contentRef = useRef(null) const { startsWith } = useFilter({ sensitivity: 'base' }) const { collection, filter, reset } = useListCollection({ initialItems: countries, filter: startsWith, }) const virtualizer = useVirtualizer({ count: collection.size, getScrollElement: () => contentRef.current, estimateSize: () => 32, overscan: 10, }) const handleScrollToIndex: Combobox.RootProps['scrollToIndexFn'] = (details) => { flushSync(() => { virtualizer.scrollToIndex(details.index, { align: 'center', behavior: 'auto', }) }) } const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {virtualizer.getVirtualItems().map((virtualItem) => { const item = collection.items[virtualItem.index] return ( {item.emoji} {item.label} ) })}
                    ) } interface Country { value: string label: string emoji: string } const countries: Country[] = [ { value: 'AD', label: 'Andorra', emoji: '🇦🇩' }, { value: 'AE', label: 'United Arab Emirates', emoji: '🇦🇪' }, { value: 'AF', label: 'Afghanistan', emoji: '🇦🇫' }, { value: 'AG', label: 'Antigua and Barbuda', emoji: '🇦🇬' }, { value: 'AI', label: 'Anguilla', emoji: '🇦🇮' }, { value: 'AL', label: 'Albania', emoji: '🇦🇱' }, { value: 'AM', label: 'Armenia', emoji: '🇦🇲' }, { value: 'AO', label: 'Angola', emoji: '🇦🇴' }, { value: 'AQ', label: 'Antarctica', emoji: '🇦🇶' }, { value: 'AR', label: 'Argentina', emoji: '🇦🇷' }, { value: 'AS', label: 'American Samoa', emoji: '🇦🇸' }, { value: 'AT', label: 'Austria', emoji: '🇦🇹' }, { value: 'AU', label: 'Australia', emoji: '🇦🇺' }, { value: 'AW', label: 'Aruba', emoji: '🇦🇼' }, { value: 'AX', label: 'Åland Islands', emoji: '🇦🇽' }, { value: 'AZ', label: 'Azerbaijan', emoji: '🇦🇿' }, { value: 'BA', label: 'Bosnia and Herzegovina', emoji: '🇧🇦' }, { value: 'BB', label: 'Barbados', emoji: '🇧🇧' }, { value: 'BD', label: 'Bangladesh', emoji: '🇧🇩' }, { value: 'BE', label: 'Belgium', emoji: '🇧🇪' }, { value: 'BF', label: 'Burkina Faso', emoji: '🇧🇫' }, { value: 'BG', label: 'Bulgaria', emoji: '🇧🇬' }, { value: 'BH', label: 'Bahrain', emoji: '🇧🇭' }, { value: 'BI', label: 'Burundi', emoji: '🇧🇮' }, { value: 'BJ', label: 'Benin', emoji: '🇧🇯' }, { value: 'BL', label: 'Saint Barthélemy', emoji: '🇧🇱' }, { value: 'BM', label: 'Bermuda', emoji: '🇧🇲' }, { value: 'BN', label: 'Brunei', emoji: '🇧🇳' }, { value: 'BO', label: 'Bolivia', emoji: '🇧🇴' }, { value: 'BR', label: 'Brazil', emoji: '🇧🇷' }, { value: 'BS', label: 'Bahamas', emoji: '🇧🇸' }, { value: 'BT', label: 'Bhutan', emoji: '🇧🇹' }, { value: 'BW', label: 'Botswana', emoji: '🇧🇼' }, { value: 'BY', label: 'Belarus', emoji: '🇧🇾' }, { value: 'BZ', label: 'Belize', emoji: '🇧🇿' }, { value: 'CA', label: 'Canada', emoji: '🇨🇦' }, { value: 'CD', label: 'Congo', emoji: '🇨🇩' }, { value: 'CF', label: 'Central African Republic', emoji: '🇨🇫' }, { value: 'CH', label: 'Switzerland', emoji: '🇨🇭' }, { value: 'CI', label: "Côte d'Ivoire", emoji: '🇨🇮' }, { value: 'CK', label: 'Cook Islands', emoji: '🇨🇰' }, { value: 'CL', label: 'Chile', emoji: '🇨🇱' }, { value: 'CM', label: 'Cameroon', emoji: '🇨🇲' }, { value: 'CN', label: 'China', emoji: '🇨🇳' }, { value: 'CO', label: 'Colombia', emoji: '🇨🇴' }, { value: 'CR', label: 'Costa Rica', emoji: '🇨🇷' }, { value: 'CU', label: 'Cuba', emoji: '🇨🇺' }, { value: 'CV', label: 'Cabo Verde', emoji: '🇨🇻' }, { value: 'CY', label: 'Cyprus', emoji: '🇨🇾' }, { value: 'CZ', label: 'Czech Republic', emoji: '🇨🇿' }, { value: 'DE', label: 'Germany', emoji: '🇩🇪' }, { value: 'DJ', label: 'Djibouti', emoji: '🇩🇯' }, { value: 'DK', label: 'Denmark', emoji: '🇩🇰' }, { value: 'DM', label: 'Dominica', emoji: '🇩🇲' }, { value: 'DO', label: 'Dominican Republic', emoji: '🇩🇴' }, { value: 'DZ', label: 'Algeria', emoji: '🇩🇿' }, { value: 'EC', label: 'Ecuador', emoji: '🇪🇨' }, { value: 'EE', label: 'Estonia', emoji: '🇪🇪' }, { value: 'EG', label: 'Egypt', emoji: '🇪🇬' }, { value: 'ER', label: 'Eritrea', emoji: '🇪🇷' }, { value: 'ES', label: 'Spain', emoji: '🇪🇸' }, { value: 'ET', label: 'Ethiopia', emoji: '🇪🇹' }, { value: 'FI', label: 'Finland', emoji: '🇫🇮' }, { value: 'FJ', label: 'Fiji', emoji: '🇫🇯' }, { value: 'FK', label: 'Falkland Islands', emoji: '🇫🇰' }, { value: 'FM', label: 'Micronesia', emoji: '🇫🇲' }, { value: 'FO', label: 'Faroe Islands', emoji: '🇫🇴' }, { value: 'FR', label: 'France', emoji: '🇫🇷' }, { value: 'GA', label: 'Gabon', emoji: '🇬🇦' }, { value: 'GB', label: 'United Kingdom', emoji: '🇬🇧' }, { value: 'GD', label: 'Grenada', emoji: '🇬🇩' }, { value: 'GE', label: 'Georgia', emoji: '🇬🇪' }, { value: 'GH', label: 'Ghana', emoji: '🇬🇭' }, { value: 'GI', label: 'Gibraltar', emoji: '🇬🇮' }, { value: 'GL', label: 'Greenland', emoji: '🇬🇱' }, { value: 'GM', label: 'Gambia', emoji: '🇬🇲' }, { value: 'GN', label: 'Guinea', emoji: '🇬🇳' }, { value: 'GQ', label: 'Equatorial Guinea', emoji: '🇬🇶' }, { value: 'GR', label: 'Greece', emoji: '🇬🇷' }, { value: 'GT', label: 'Guatemala', emoji: '🇬🇹' }, { value: 'GU', label: 'Guam', emoji: '🇬🇺' }, { value: 'GW', label: 'Guinea-Bissau', emoji: '🇬🇼' }, { value: 'GY', label: 'Guyana', emoji: '🇬🇾' }, { value: 'HK', label: 'Hong Kong', emoji: '🇭🇰' }, { value: 'HN', label: 'Honduras', emoji: '🇭🇳' }, { value: 'HR', label: 'Croatia', emoji: '🇭🇷' }, { value: 'HT', label: 'Haiti', emoji: '🇭🇹' }, { value: 'HU', label: 'Hungary', emoji: '🇭🇺' }, { value: 'ID', label: 'Indonesia', emoji: '🇮🇩' }, { value: 'IE', label: 'Ireland', emoji: '🇮🇪' }, { value: 'IL', label: 'Israel', emoji: '🇮🇱' }, { value: 'IM', label: 'Isle of Man', emoji: '🇮🇲' }, { value: 'IN', label: 'India', emoji: '🇮🇳' }, { value: 'IQ', label: 'Iraq', emoji: '🇮🇶' }, { value: 'IR', label: 'Iran', emoji: '🇮🇷' }, { value: 'IS', label: 'Iceland', emoji: '🇮🇸' }, { value: 'IT', label: 'Italy', emoji: '🇮🇹' }, { value: 'JE', label: 'Jersey', emoji: '🇯🇪' }, { value: 'JM', label: 'Jamaica', emoji: '🇯🇲' }, { value: 'JO', label: 'Jordan', emoji: '🇯🇴' }, { value: 'JP', label: 'Japan', emoji: '🇯🇵' }, { value: 'KE', label: 'Kenya', emoji: '🇰🇪' }, { value: 'KG', label: 'Kyrgyzstan', emoji: '🇰🇬' }, { value: 'KH', label: 'Cambodia', emoji: '🇰🇭' }, { value: 'KI', label: 'Kiribati', emoji: '🇰🇮' }, { value: 'KM', label: 'Comoros', emoji: '🇰🇲' }, { value: 'KN', label: 'Saint Kitts and Nevis', emoji: '🇰🇳' }, { value: 'KP', label: 'North Korea', emoji: '🇰🇵' }, { value: 'KR', label: 'South Korea', emoji: '🇰🇷' }, { value: 'KW', label: 'Kuwait', emoji: '🇰🇼' }, { value: 'KY', label: 'Cayman Islands', emoji: '🇰🇾' }, { value: 'KZ', label: 'Kazakhstan', emoji: '🇰🇿' }, { value: 'LA', label: 'Laos', emoji: '🇱🇦' }, { value: 'LB', label: 'Lebanon', emoji: '🇱🇧' }, { value: 'LC', label: 'Saint Lucia', emoji: '🇱🇨' }, { value: 'LI', label: 'Liechtenstein', emoji: '🇱🇮' }, { value: 'LK', label: 'Sri Lanka', emoji: '🇱🇰' }, { value: 'LR', label: 'Liberia', emoji: '🇱🇷' }, { value: 'LS', label: 'Lesotho', emoji: '🇱🇸' }, { value: 'LT', label: 'Lithuania', emoji: '🇱🇹' }, { value: 'LU', label: 'Luxembourg', emoji: '🇱🇺' }, { value: 'LV', label: 'Latvia', emoji: '🇱🇻' }, { value: 'LY', label: 'Libya', emoji: '🇱🇾' }, { value: 'MA', label: 'Morocco', emoji: '🇲🇦' }, { value: 'MC', label: 'Monaco', emoji: '🇲🇨' }, { value: 'MD', label: 'Moldova', emoji: '🇲🇩' }, { value: 'ME', label: 'Montenegro', emoji: '🇲🇪' }, { value: 'MG', label: 'Madagascar', emoji: '🇲🇬' }, { value: 'MH', label: 'Marshall Islands', emoji: '🇲🇭' }, { value: 'MK', label: 'North Macedonia', emoji: '🇲🇰' }, { value: 'ML', label: 'Mali', emoji: '🇲🇱' }, { value: 'MM', label: 'Myanmar', emoji: '🇲🇲' }, { value: 'MN', label: 'Mongolia', emoji: '🇲🇳' }, { value: 'MO', label: 'Macao', emoji: '🇲🇴' }, { value: 'MR', label: 'Mauritania', emoji: '🇲🇷' }, { value: 'MS', label: 'Montserrat', emoji: '🇲🇸' }, { value: 'MT', label: 'Malta', emoji: '🇲🇹' }, { value: 'MU', label: 'Mauritius', emoji: '🇲🇺' }, { value: 'MV', label: 'Maldives', emoji: '🇲🇻' }, { value: 'MW', label: 'Malawi', emoji: '🇲🇼' }, { value: 'MX', label: 'Mexico', emoji: '🇲🇽' }, { value: 'MY', label: 'Malaysia', emoji: '🇲🇾' }, { value: 'MZ', label: 'Mozambique', emoji: '🇲🇿' }, { value: 'NA', label: 'Namibia', emoji: '🇳🇦' }, { value: 'NC', label: 'New Caledonia', emoji: '🇳🇨' }, { value: 'NE', label: 'Niger', emoji: '🇳🇪' }, { value: 'NF', label: 'Norfolk Island', emoji: '🇳🇫' }, { value: 'NG', label: 'Nigeria', emoji: '🇳🇬' }, { value: 'NI', label: 'Nicaragua', emoji: '🇳🇮' }, { value: 'NL', label: 'Netherlands', emoji: '🇳🇱' }, { value: 'NO', label: 'Norway', emoji: '🇳🇴' }, { value: 'NP', label: 'Nepal', emoji: '🇳🇵' }, { value: 'NR', label: 'Nauru', emoji: '🇳🇷' }, { value: 'NU', label: 'Niue', emoji: '🇳🇺' }, { value: 'NZ', label: 'New Zealand', emoji: '🇳🇿' }, { value: 'OM', label: 'Oman', emoji: '🇴🇲' }, { value: 'PA', label: 'Panama', emoji: '🇵🇦' }, { value: 'PE', label: 'Peru', emoji: '🇵🇪' }, { value: 'PF', label: 'French Polynesia', emoji: '🇵🇫' }, { value: 'PG', label: 'Papua New Guinea', emoji: '🇵🇬' }, { value: 'PH', label: 'Philippines', emoji: '🇵🇭' }, { value: 'PK', label: 'Pakistan', emoji: '🇵🇰' }, { value: 'PL', label: 'Poland', emoji: '🇵🇱' }, { value: 'PR', label: 'Puerto Rico', emoji: '🇵🇷' }, { value: 'PS', label: 'Palestine', emoji: '🇵🇸' }, { value: 'PT', label: 'Portugal', emoji: '🇵🇹' }, { value: 'PW', label: 'Palau', emoji: '🇵🇼' }, { value: 'PY', label: 'Paraguay', emoji: '🇵🇾' }, { value: 'QA', label: 'Qatar', emoji: '🇶🇦' }, { value: 'RO', label: 'Romania', emoji: '🇷🇴' }, { value: 'RS', label: 'Serbia', emoji: '🇷🇸' }, { value: 'RU', label: 'Russia', emoji: '🇷🇺' }, { value: 'RW', label: 'Rwanda', emoji: '🇷🇼' }, { value: 'SA', label: 'Saudi Arabia', emoji: '🇸🇦' }, { value: 'SB', label: 'Solomon Islands', emoji: '🇸🇧' }, { value: 'SC', label: 'Seychelles', emoji: '🇸🇨' }, { value: 'SD', label: 'Sudan', emoji: '🇸🇩' }, { value: 'SE', label: 'Sweden', emoji: '🇸🇪' }, { value: 'SG', label: 'Singapore', emoji: '🇸🇬' }, { value: 'SI', label: 'Slovenia', emoji: '🇸🇮' }, { value: 'SK', label: 'Slovakia', emoji: '🇸🇰' }, { value: 'SL', label: 'Sierra Leone', emoji: '🇸🇱' }, { value: 'SM', label: 'San Marino', emoji: '🇸🇲' }, { value: 'SN', label: 'Senegal', emoji: '🇸🇳' }, { value: 'SO', label: 'Somalia', emoji: '🇸🇴' }, { value: 'SR', label: 'Suriname', emoji: '🇸🇷' }, { value: 'SS', label: 'South Sudan', emoji: '🇸🇸' }, { value: 'ST', label: 'Sao Tome and Principe', emoji: '🇸🇹' }, { value: 'SV', label: 'El Salvador', emoji: '🇸🇻' }, { value: 'SY', label: 'Syria', emoji: '🇸🇾' }, { value: 'SZ', label: 'Eswatini', emoji: '🇸🇿' }, { value: 'TC', label: 'Turks and Caicos Islands', emoji: '🇹🇨' }, { value: 'TD', label: 'Chad', emoji: '🇹🇩' }, { value: 'TG', label: 'Togo', emoji: '🇹🇬' }, { value: 'TH', label: 'Thailand', emoji: '🇹🇭' }, { value: 'TJ', label: 'Tajikistan', emoji: '🇹🇯' }, { value: 'TK', label: 'Tokelau', emoji: '🇹🇰' }, { value: 'TL', label: 'Timor-Leste', emoji: '🇹🇱' }, { value: 'TM', label: 'Turkmenistan', emoji: '🇹🇲' }, { value: 'TN', label: 'Tunisia', emoji: '🇹🇳' }, { value: 'TO', label: 'Tonga', emoji: '🇹🇴' }, { value: 'TR', label: 'Türkiye', emoji: '🇹🇷' }, { value: 'TT', label: 'Trinidad and Tobago', emoji: '🇹🇹' }, { value: 'TV', label: 'Tuvalu', emoji: '🇹🇻' }, { value: 'TW', label: 'Taiwan', emoji: '🇹🇼' }, { value: 'TZ', label: 'Tanzania', emoji: '🇹🇿' }, { value: 'UA', label: 'Ukraine', emoji: '🇺🇦' }, { value: 'UG', label: 'Uganda', emoji: '🇺🇬' }, { value: 'US', label: 'United States', emoji: '🇺🇸' }, { value: 'UY', label: 'Uruguay', emoji: '🇺🇾' }, { value: 'UZ', label: 'Uzbekistan', emoji: '🇺🇿' }, { value: 'VA', label: 'Vatican City', emoji: '🇻🇦' }, { value: 'VC', label: 'Saint Vincent and the Grenadines', emoji: '🇻🇨' }, { value: 'VE', label: 'Venezuela', emoji: '🇻🇪' }, { value: 'VG', label: 'British Virgin Islands', emoji: '🇻🇬' }, { value: 'VI', label: 'U.S. Virgin Islands', emoji: '🇻🇮' }, { value: 'VN', label: 'Vietnam', emoji: '🇻🇳' }, { value: 'VU', label: 'Vanuatu', emoji: '🇻🇺' }, { value: 'WF', label: 'Wallis and Futuna', emoji: '🇼🇫' }, { value: 'WS', label: 'Samoa', emoji: '🇼🇸' }, { value: 'YE', label: 'Yemen', emoji: '🇾🇪' }, { value: 'YT', label: 'Mayotte', emoji: '🇾🇹' }, { value: 'ZA', label: 'South Africa', emoji: '🇿🇦' }, { value: 'ZM', label: 'Zambia', emoji: '🇿🇲' }, { value: 'ZW', label: 'Zimbabwe', emoji: '🇿🇼' }, ] ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { createVirtualizer } from '@tanstack/solid-virtual' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const Virtualized = () => { let contentRef: HTMLDivElement | undefined const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter, reset } = useListCollection({ initialItems: countries, filter: filterFn().startsWith, }) const virtualizer = createVirtualizer({ get count() { return collection().size }, getScrollElement: () => contentRef ?? null, estimateSize: () => 32, overscan: 10, }) const handleScrollToIndex: Combobox.RootProps['scrollToIndexFn'] = (details) => { virtualizer.scrollToIndex(details.index, { align: 'center', behavior: 'auto', }) } const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {virtualizer.getVirtualItems().map((virtualItem) => { const item = collection().items[virtualItem.index] return ( {item.emoji} {item.label} ) })}
                    ) } interface Country { value: string label: string emoji: string } const countries: Country[] = [ { value: 'AD', label: 'Andorra', emoji: '🇦🇩' }, { value: 'AE', label: 'United Arab Emirates', emoji: '🇦🇪' }, { value: 'AF', label: 'Afghanistan', emoji: '🇦🇫' }, { value: 'AG', label: 'Antigua and Barbuda', emoji: '🇦🇬' }, { value: 'AI', label: 'Anguilla', emoji: '🇦🇮' }, { value: 'AL', label: 'Albania', emoji: '🇦🇱' }, { value: 'AM', label: 'Armenia', emoji: '🇦🇲' }, { value: 'AO', label: 'Angola', emoji: '🇦🇴' }, { value: 'AQ', label: 'Antarctica', emoji: '🇦🇶' }, { value: 'AR', label: 'Argentina', emoji: '🇦🇷' }, { value: 'AS', label: 'American Samoa', emoji: '🇦🇸' }, { value: 'AT', label: 'Austria', emoji: '🇦🇹' }, { value: 'AU', label: 'Australia', emoji: '🇦🇺' }, { value: 'AW', label: 'Aruba', emoji: '🇦🇼' }, { value: 'AX', label: 'Åland Islands', emoji: '🇦🇽' }, { value: 'AZ', label: 'Azerbaijan', emoji: '🇦🇿' }, { value: 'BA', label: 'Bosnia and Herzegovina', emoji: '🇧🇦' }, { value: 'BB', label: 'Barbados', emoji: '🇧🇧' }, { value: 'BD', label: 'Bangladesh', emoji: '🇧🇩' }, { value: 'BE', label: 'Belgium', emoji: '🇧🇪' }, { value: 'BF', label: 'Burkina Faso', emoji: '🇧🇫' }, { value: 'BG', label: 'Bulgaria', emoji: '🇧🇬' }, { value: 'BH', label: 'Bahrain', emoji: '🇧🇭' }, { value: 'BI', label: 'Burundi', emoji: '🇧🇮' }, { value: 'BJ', label: 'Benin', emoji: '🇧🇯' }, { value: 'BL', label: 'Saint Barthélemy', emoji: '🇧🇱' }, { value: 'BM', label: 'Bermuda', emoji: '🇧🇲' }, { value: 'BN', label: 'Brunei', emoji: '🇧🇳' }, { value: 'BO', label: 'Bolivia', emoji: '🇧🇴' }, { value: 'BR', label: 'Brazil', emoji: '🇧🇷' }, { value: 'BS', label: 'Bahamas', emoji: '🇧🇸' }, { value: 'BT', label: 'Bhutan', emoji: '🇧🇹' }, { value: 'BW', label: 'Botswana', emoji: '🇧🇼' }, { value: 'BY', label: 'Belarus', emoji: '🇧🇾' }, { value: 'BZ', label: 'Belize', emoji: '🇧🇿' }, { value: 'CA', label: 'Canada', emoji: '🇨🇦' }, { value: 'CD', label: 'Congo', emoji: '🇨🇩' }, { value: 'CF', label: 'Central African Republic', emoji: '🇨🇫' }, { value: 'CH', label: 'Switzerland', emoji: '🇨🇭' }, { value: 'CI', label: "Côte d'Ivoire", emoji: '🇨🇮' }, { value: 'CK', label: 'Cook Islands', emoji: '🇨🇰' }, { value: 'CL', label: 'Chile', emoji: '🇨🇱' }, { value: 'CM', label: 'Cameroon', emoji: '🇨🇲' }, { value: 'CN', label: 'China', emoji: '🇨🇳' }, { value: 'CO', label: 'Colombia', emoji: '🇨🇴' }, { value: 'CR', label: 'Costa Rica', emoji: '🇨🇷' }, { value: 'CU', label: 'Cuba', emoji: '🇨🇺' }, { value: 'CV', label: 'Cabo Verde', emoji: '🇨🇻' }, { value: 'CY', label: 'Cyprus', emoji: '🇨🇾' }, { value: 'CZ', label: 'Czech Republic', emoji: '🇨🇿' }, { value: 'DE', label: 'Germany', emoji: '🇩🇪' }, { value: 'DJ', label: 'Djibouti', emoji: '🇩🇯' }, { value: 'DK', label: 'Denmark', emoji: '🇩🇰' }, { value: 'DM', label: 'Dominica', emoji: '🇩🇲' }, { value: 'DO', label: 'Dominican Republic', emoji: '🇩🇴' }, { value: 'DZ', label: 'Algeria', emoji: '🇩🇿' }, { value: 'EC', label: 'Ecuador', emoji: '🇪🇨' }, { value: 'EE', label: 'Estonia', emoji: '🇪🇪' }, { value: 'EG', label: 'Egypt', emoji: '🇪🇬' }, { value: 'ER', label: 'Eritrea', emoji: '🇪🇷' }, { value: 'ES', label: 'Spain', emoji: '🇪🇸' }, { value: 'ET', label: 'Ethiopia', emoji: '🇪🇹' }, { value: 'FI', label: 'Finland', emoji: '🇫🇮' }, { value: 'FJ', label: 'Fiji', emoji: '🇫🇯' }, { value: 'FK', label: 'Falkland Islands', emoji: '🇫🇰' }, { value: 'FM', label: 'Micronesia', emoji: '🇫🇲' }, { value: 'FO', label: 'Faroe Islands', emoji: '🇫🇴' }, { value: 'FR', label: 'France', emoji: '🇫🇷' }, { value: 'GA', label: 'Gabon', emoji: '🇬🇦' }, { value: 'GB', label: 'United Kingdom', emoji: '🇬🇧' }, { value: 'GD', label: 'Grenada', emoji: '🇬🇩' }, { value: 'GE', label: 'Georgia', emoji: '🇬🇪' }, { value: 'GH', label: 'Ghana', emoji: '🇬🇭' }, { value: 'GI', label: 'Gibraltar', emoji: '🇬🇮' }, { value: 'GL', label: 'Greenland', emoji: '🇬🇱' }, { value: 'GM', label: 'Gambia', emoji: '🇬🇲' }, { value: 'GN', label: 'Guinea', emoji: '🇬🇳' }, { value: 'GQ', label: 'Equatorial Guinea', emoji: '🇬🇶' }, { value: 'GR', label: 'Greece', emoji: '🇬🇷' }, { value: 'GT', label: 'Guatemala', emoji: '🇬🇹' }, { value: 'GU', label: 'Guam', emoji: '🇬🇺' }, { value: 'GW', label: 'Guinea-Bissau', emoji: '🇬🇼' }, { value: 'GY', label: 'Guyana', emoji: '🇬🇾' }, { value: 'HK', label: 'Hong Kong', emoji: '🇭🇰' }, { value: 'HN', label: 'Honduras', emoji: '🇭🇳' }, { value: 'HR', label: 'Croatia', emoji: '🇭🇷' }, { value: 'HT', label: 'Haiti', emoji: '🇭🇹' }, { value: 'HU', label: 'Hungary', emoji: '🇭🇺' }, { value: 'ID', label: 'Indonesia', emoji: '🇮🇩' }, { value: 'IE', label: 'Ireland', emoji: '🇮🇪' }, { value: 'IL', label: 'Israel', emoji: '🇮🇱' }, { value: 'IM', label: 'Isle of Man', emoji: '🇮🇲' }, { value: 'IN', label: 'India', emoji: '🇮🇳' }, { value: 'IQ', label: 'Iraq', emoji: '🇮🇶' }, { value: 'IR', label: 'Iran', emoji: '🇮🇷' }, { value: 'IS', label: 'Iceland', emoji: '🇮🇸' }, { value: 'IT', label: 'Italy', emoji: '🇮🇹' }, { value: 'JE', label: 'Jersey', emoji: '🇯🇪' }, { value: 'JM', label: 'Jamaica', emoji: '🇯🇲' }, { value: 'JO', label: 'Jordan', emoji: '🇯🇴' }, { value: 'JP', label: 'Japan', emoji: '🇯🇵' }, { value: 'KE', label: 'Kenya', emoji: '🇰🇪' }, { value: 'KG', label: 'Kyrgyzstan', emoji: '🇰🇬' }, { value: 'KH', label: 'Cambodia', emoji: '🇰🇭' }, { value: 'KI', label: 'Kiribati', emoji: '🇰🇮' }, { value: 'KM', label: 'Comoros', emoji: '🇰🇲' }, { value: 'KN', label: 'Saint Kitts and Nevis', emoji: '🇰🇳' }, { value: 'KP', label: 'North Korea', emoji: '🇰🇵' }, { value: 'KR', label: 'South Korea', emoji: '🇰🇷' }, { value: 'KW', label: 'Kuwait', emoji: '🇰🇼' }, { value: 'KY', label: 'Cayman Islands', emoji: '🇰🇾' }, { value: 'KZ', label: 'Kazakhstan', emoji: '🇰🇿' }, { value: 'LA', label: 'Laos', emoji: '🇱🇦' }, { value: 'LB', label: 'Lebanon', emoji: '🇱🇧' }, { value: 'LC', label: 'Saint Lucia', emoji: '🇱🇨' }, { value: 'LI', label: 'Liechtenstein', emoji: '🇱🇮' }, { value: 'LK', label: 'Sri Lanka', emoji: '🇱🇰' }, { value: 'LR', label: 'Liberia', emoji: '🇱🇷' }, { value: 'LS', label: 'Lesotho', emoji: '🇱🇸' }, { value: 'LT', label: 'Lithuania', emoji: '🇱🇹' }, { value: 'LU', label: 'Luxembourg', emoji: '🇱🇺' }, { value: 'LV', label: 'Latvia', emoji: '🇱🇻' }, { value: 'LY', label: 'Libya', emoji: '🇱🇾' }, { value: 'MA', label: 'Morocco', emoji: '🇲🇦' }, { value: 'MC', label: 'Monaco', emoji: '🇲🇨' }, { value: 'MD', label: 'Moldova', emoji: '🇲🇩' }, { value: 'ME', label: 'Montenegro', emoji: '🇲🇪' }, { value: 'MG', label: 'Madagascar', emoji: '🇲🇬' }, { value: 'MH', label: 'Marshall Islands', emoji: '🇲🇭' }, { value: 'MK', label: 'North Macedonia', emoji: '🇲🇰' }, { value: 'ML', label: 'Mali', emoji: '🇲🇱' }, { value: 'MM', label: 'Myanmar', emoji: '🇲🇲' }, { value: 'MN', label: 'Mongolia', emoji: '🇲🇳' }, { value: 'MO', label: 'Macao', emoji: '🇲🇴' }, { value: 'MR', label: 'Mauritania', emoji: '🇲🇷' }, { value: 'MS', label: 'Montserrat', emoji: '🇲🇸' }, { value: 'MT', label: 'Malta', emoji: '🇲🇹' }, { value: 'MU', label: 'Mauritius', emoji: '🇲🇺' }, { value: 'MV', label: 'Maldives', emoji: '🇲🇻' }, { value: 'MW', label: 'Malawi', emoji: '🇲🇼' }, { value: 'MX', label: 'Mexico', emoji: '🇲🇽' }, { value: 'MY', label: 'Malaysia', emoji: '🇲🇾' }, { value: 'MZ', label: 'Mozambique', emoji: '🇲🇿' }, { value: 'NA', label: 'Namibia', emoji: '🇳🇦' }, { value: 'NC', label: 'New Caledonia', emoji: '🇳🇨' }, { value: 'NE', label: 'Niger', emoji: '🇳🇪' }, { value: 'NF', label: 'Norfolk Island', emoji: '🇳🇫' }, { value: 'NG', label: 'Nigeria', emoji: '🇳🇬' }, { value: 'NI', label: 'Nicaragua', emoji: '🇳🇮' }, { value: 'NL', label: 'Netherlands', emoji: '🇳🇱' }, { value: 'NO', label: 'Norway', emoji: '🇳🇴' }, { value: 'NP', label: 'Nepal', emoji: '🇳🇵' }, { value: 'NR', label: 'Nauru', emoji: '🇳🇷' }, { value: 'NU', label: 'Niue', emoji: '🇳🇺' }, { value: 'NZ', label: 'New Zealand', emoji: '🇳🇿' }, { value: 'OM', label: 'Oman', emoji: '🇴🇲' }, { value: 'PA', label: 'Panama', emoji: '🇵🇦' }, { value: 'PE', label: 'Peru', emoji: '🇵🇪' }, { value: 'PF', label: 'French Polynesia', emoji: '🇵🇫' }, { value: 'PG', label: 'Papua New Guinea', emoji: '🇵🇬' }, { value: 'PH', label: 'Philippines', emoji: '🇵🇭' }, { value: 'PK', label: 'Pakistan', emoji: '🇵🇰' }, { value: 'PL', label: 'Poland', emoji: '🇵🇱' }, { value: 'PR', label: 'Puerto Rico', emoji: '🇵🇷' }, { value: 'PS', label: 'Palestine', emoji: '🇵🇸' }, { value: 'PT', label: 'Portugal', emoji: '🇵🇹' }, { value: 'PW', label: 'Palau', emoji: '🇵🇼' }, { value: 'PY', label: 'Paraguay', emoji: '🇵🇾' }, { value: 'QA', label: 'Qatar', emoji: '🇶🇦' }, { value: 'RO', label: 'Romania', emoji: '🇷🇴' }, { value: 'RS', label: 'Serbia', emoji: '🇷🇸' }, { value: 'RU', label: 'Russia', emoji: '🇷🇺' }, { value: 'RW', label: 'Rwanda', emoji: '🇷🇼' }, { value: 'SA', label: 'Saudi Arabia', emoji: '🇸🇦' }, { value: 'SB', label: 'Solomon Islands', emoji: '🇸🇧' }, { value: 'SC', label: 'Seychelles', emoji: '🇸🇨' }, { value: 'SD', label: 'Sudan', emoji: '🇸🇩' }, { value: 'SE', label: 'Sweden', emoji: '🇸🇪' }, { value: 'SG', label: 'Singapore', emoji: '🇸🇬' }, { value: 'SI', label: 'Slovenia', emoji: '🇸🇮' }, { value: 'SK', label: 'Slovakia', emoji: '🇸🇰' }, { value: 'SL', label: 'Sierra Leone', emoji: '🇸🇱' }, { value: 'SM', label: 'San Marino', emoji: '🇸🇲' }, { value: 'SN', label: 'Senegal', emoji: '🇸🇳' }, { value: 'SO', label: 'Somalia', emoji: '🇸🇴' }, { value: 'SR', label: 'Suriname', emoji: '🇸🇷' }, { value: 'SS', label: 'South Sudan', emoji: '🇸🇸' }, { value: 'ST', label: 'Sao Tome and Principe', emoji: '🇸🇹' }, { value: 'SV', label: 'El Salvador', emoji: '🇸🇻' }, { value: 'SY', label: 'Syria', emoji: '🇸🇾' }, { value: 'SZ', label: 'Eswatini', emoji: '🇸🇿' }, { value: 'TC', label: 'Turks and Caicos Islands', emoji: '🇹🇨' }, { value: 'TD', label: 'Chad', emoji: '🇹🇩' }, { value: 'TG', label: 'Togo', emoji: '🇹🇬' }, { value: 'TH', label: 'Thailand', emoji: '🇹🇭' }, { value: 'TJ', label: 'Tajikistan', emoji: '🇹🇯' }, { value: 'TK', label: 'Tokelau', emoji: '🇹🇰' }, { value: 'TL', label: 'Timor-Leste', emoji: '🇹🇱' }, { value: 'TM', label: 'Turkmenistan', emoji: '🇹🇲' }, { value: 'TN', label: 'Tunisia', emoji: '🇹🇳' }, { value: 'TO', label: 'Tonga', emoji: '🇹🇴' }, { value: 'TR', label: 'Türkiye', emoji: '🇹🇷' }, { value: 'TT', label: 'Trinidad and Tobago', emoji: '🇹🇹' }, { value: 'TV', label: 'Tuvalu', emoji: '🇹🇻' }, { value: 'TW', label: 'Taiwan', emoji: '🇹🇼' }, { value: 'TZ', label: 'Tanzania', emoji: '🇹🇿' }, { value: 'UA', label: 'Ukraine', emoji: '🇺🇦' }, { value: 'UG', label: 'Uganda', emoji: '🇺🇬' }, { value: 'US', label: 'United States', emoji: '🇺🇸' }, { value: 'UY', label: 'Uruguay', emoji: '🇺🇾' }, { value: 'UZ', label: 'Uzbekistan', emoji: '🇺🇿' }, { value: 'VA', label: 'Vatican City', emoji: '🇻🇦' }, { value: 'VC', label: 'Saint Vincent and the Grenadines', emoji: '🇻🇨' }, { value: 'VE', label: 'Venezuela', emoji: '🇻🇪' }, { value: 'VG', label: 'British Virgin Islands', emoji: '🇻🇬' }, { value: 'VI', label: 'U.S. Virgin Islands', emoji: '🇻🇮' }, { value: 'VN', label: 'Vietnam', emoji: '🇻🇳' }, { value: 'VU', label: 'Vanuatu', emoji: '🇻🇺' }, { value: 'WF', label: 'Wallis and Futuna', emoji: '🇼🇫' }, { value: 'WS', label: 'Samoa', emoji: '🇼🇸' }, { value: 'YE', label: 'Yemen', emoji: '🇾🇪' }, { value: 'YT', label: 'Mayotte', emoji: '🇾🇹' }, { value: 'ZA', label: 'South Africa', emoji: '🇿🇦' }, { value: 'ZM', label: 'Zambia', emoji: '🇿🇲' }, { value: 'ZW', label: 'Zimbabwe', emoji: '🇿🇼' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte Country
                    Open
                    {#each $virtualizer.getVirtualItems() as virtualItem (virtualItem.key)} {@const item = collection().items[virtualItem.index]} {item.label} {/each}
                    ``` ### Custom Object Use the `itemToString` and `itemToValue` props to map custom objects to the required interface. **Example: custom-object** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const CustomObject = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { country: 'United States', code: 'US', flag: '🇺🇸' }, { country: 'Canada', code: 'CA', flag: '🇨🇦' }, { country: 'Australia', code: 'AU', flag: '🇦🇺' }, ], itemToString: (item) => item.country, itemToValue: (item) => item.code, filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {collection.items.map((item) => ( {item.flag} {item.country} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const CustomObject = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { country: 'United States', code: 'US', flag: '🇺🇸' }, { country: 'Canada', code: 'CA', flag: '🇨🇦' }, { country: 'Australia', code: 'AU', flag: '🇦🇺' }, ], itemToString: (item) => item.country, itemToValue: (item) => item.code, filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    Clear Open
                    {(item) => ( {item.flag} {item.country} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Country
                    Clear Open
                    {#each collection().items as item (item.code)} {item.flag} {item.country} {/each}
                    ``` ### Limit Results Use the `limit` property on `useListCollection` to limit the number of rendered items in the DOM. **Example: limit-results** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' const cities = [ { label: 'New York', value: 'new-york' }, { label: 'Los Angeles', value: 'los-angeles' }, { label: 'Chicago', value: 'chicago' }, { label: 'Houston', value: 'houston' }, { label: 'Phoenix', value: 'phoenix' }, { label: 'Philadelphia', value: 'philadelphia' }, { label: 'San Antonio', value: 'san-antonio' }, { label: 'San Diego', value: 'san-diego' }, { label: 'Dallas', value: 'dallas' }, { label: 'San Jose', value: 'san-jose' }, { label: 'Austin', value: 'austin' }, { label: 'Jacksonville', value: 'jacksonville' }, { label: 'Fort Worth', value: 'fort-worth' }, { label: 'Columbus', value: 'columbus' }, { label: 'Charlotte', value: 'charlotte' }, { label: 'San Francisco', value: 'san-francisco' }, { label: 'Indianapolis', value: 'indianapolis' }, { label: 'Seattle', value: 'seattle' }, { label: 'Denver', value: 'denver' }, { label: 'Boston', value: 'boston' }, ] export const LimitResults = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: cities, limit: 5, filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( City
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' const cities = [ { label: 'New York', value: 'new-york' }, { label: 'Los Angeles', value: 'los-angeles' }, { label: 'Chicago', value: 'chicago' }, { label: 'Houston', value: 'houston' }, { label: 'Phoenix', value: 'phoenix' }, { label: 'Philadelphia', value: 'philadelphia' }, { label: 'San Antonio', value: 'san-antonio' }, { label: 'San Diego', value: 'san-diego' }, { label: 'Dallas', value: 'dallas' }, { label: 'San Jose', value: 'san-jose' }, { label: 'Austin', value: 'austin' }, { label: 'Jacksonville', value: 'jacksonville' }, { label: 'Fort Worth', value: 'fort-worth' }, { label: 'Columbus', value: 'columbus' }, { label: 'Charlotte', value: 'charlotte' }, { label: 'San Francisco', value: 'san-francisco' }, { label: 'Indianapolis', value: 'indianapolis' }, { label: 'Seattle', value: 'seattle' }, { label: 'Denver', value: 'denver' }, { label: 'Boston', value: 'boston' }, ] export const LimitResults = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: cities, limit: 5, filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( City
                    Open
                    {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte City
                    Open
                    {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ## Guides ### Router Links Customize the `navigate` prop on `Combobox.Root` to integrate with your router. Using Tanstack Router: ```tsx import { Combobox } from '@ark-ui//combobox' import { useNavigate } from '@tanstack/react-router' function Demo() { const navigate = useNavigate() return ( { navigate({ to: e.node.href }) }} > {/* ... */} ) } ``` ### Custom Objects By default, the combobox collection expects an array of objects with `label` and `value` properties. In some cases, you may need to deal with custom objects. Use the `itemToString` and `itemToValue` props to map the custom object to the required interface. ```tsx const items = [ { country: 'United States', code: 'US', flag: '🇺🇸' }, { country: 'Canada', code: 'CA', flag: '🇨🇦' }, { country: 'Australia', code: 'AU', flag: '🇦🇺' }, // ... ] const { collection } = useListCollection({ initialItems: items, itemToString: (item) => item.country, itemToValue: (item) => item.code, }) ``` ### Type Safety The `Combobox.RootComponent` type enables you to create typed wrapper components that maintain full type safety for collection items. ```tsx const Combobox: ArkCombobox.RootComponent = (props) => { return {/* ... */} } ``` Use the wrapper with full type inference on `onValueChange` and other callbacks: ```tsx const App = () => { const { collection } = useListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, ], }) return ( { // e.items is typed as Array<{ label: string, value: string }> console.log(e.items) }} > {/* ... */} ) } ``` ### Large Datasets The recommended way of managing large lists is to use the `limit` property on the `useListCollection` hook. This will limit the number of rendered items in the DOM to improve performance. ```tsx {3} const { collection } = useListCollection({ initialItems: items, limit: 10, }) ``` ### Available Size The following css variables are exposed to the `Combobox.Positioner` which you can use to style the `Combobox.Content` ```css /* width of the combobox control */ --reference-width: ; /* width of the available viewport */ --available-width: ; /* height of the available viewport */ --available-height: ; ``` For example, if you want to make sure the maximum height doesn't exceed the available height, you can use the following: ```css [data-scope='combobox'][data-part='content'] { max-height: calc(var(--available-height) - 100px); } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input | | `alwaysSubmitOnEnter` | `boolean` | No | Whether to always submit on Enter key press, even if popup is open. Useful for single-field autocomplete forms where Enter should submit the form. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the input on mount | | `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. | | `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. | | `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. | | `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. | | `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. | | `disabled` | `boolean` | No | Whether the combobox is disabled | | `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer | | `form` | `string` | No | The associate form of the combobox. | | `highlightedValue` | `string` | No | The controlled highlighted value of the combobox | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string control: string input: string content: string trigger: string clearTrigger: string item: (id: string, index?: number | undefined) => string positioner: string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the combobox. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inputBehavior` | `'none' | 'autohighlight' | 'autocomplete'` | No | Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated | | `inputValue` | `string` | No | The controlled value of the combobox's input | | `invalid` | `boolean` | No | Whether the combobox is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items | | `multiple` | `boolean` | No | Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. | | `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when an item is highlighted using the pointer or keyboard navigation. | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Function called when the input's value changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when a new item is selected | | `open` | `boolean` | No | The controlled open state of the combobox | | `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes | | `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input | | `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press | | `placeholder` | `string` | No | The placeholder text of the combobox's input | | `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it | | `required` | `boolean` | No | Whether the combobox is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionBehavior` | `'clear' | 'replace' | 'preserve'` | No | The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the combobox's selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested comboboxs | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-autofocus]` | | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-group | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-value]` | The value of the item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | label | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | list | | `[data-empty]` | Present when the content is empty | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseComboboxReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `focusable` | `boolean` | No | Whether the trigger is focusable | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | | `[data-focusable]` | | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input | | `alwaysSubmitOnEnter` | `boolean` | No | Whether to always submit on Enter key press, even if popup is open. Useful for single-field autocomplete forms where Enter should submit the form. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the input on mount | | `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. | | `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. | | `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. | | `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. | | `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. | | `disabled` | `boolean` | No | Whether the combobox is disabled | | `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer | | `form` | `string` | No | The associate form of the combobox. | | `highlightedValue` | `string` | No | The controlled highlighted value of the combobox | | `ids` | `Partial<{ root: string label: string control: string input: string content: string trigger: string clearTrigger: string item: (id: string, index?: number | undefined) => string positioner: string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the combobox. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inputBehavior` | `'none' | 'autohighlight' | 'autocomplete'` | No | Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated | | `inputValue` | `string` | No | The controlled value of the combobox's input | | `invalid` | `boolean` | No | Whether the combobox is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items | | `multiple` | `boolean` | No | Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. | | `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when an item is highlighted using the pointer or keyboard navigation. | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Function called when the input's value changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when a new item is selected | | `open` | `boolean` | No | The controlled open state of the combobox | | `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes | | `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input | | `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press | | `placeholder` | `string` | No | The placeholder text of the combobox's input | | `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it | | `required` | `boolean` | No | Whether the combobox is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionBehavior` | `'replace' | 'clear' | 'preserve'` | No | The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the combobox's selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested comboboxs | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-autofocus]` | | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-group | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-value]` | The value of the item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | label | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | list | | `[data-empty]` | Present when the content is empty | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseComboboxReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `focusable` | `boolean` | No | Whether the trigger is focusable | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | | `[data-focusable]` | | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input | | `alwaysSubmitOnEnter` | `boolean` | No | Whether to allow bypassing the default two-step behavior (Enter to close combobox, then Enter to submit form) and instead submit the form immediately on Enter press. This is useful for single-field autocomplete forms where Enter should submit the form directly. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the input on mount | | `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. | | `collection` | `ListCollection` | No | The collection of items | | `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. | | `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. | | `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. | | `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. | | `disabled` | `boolean` | No | Whether the combobox is disabled | | `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer | | `form` | `string` | No | The associate form of the combobox. | | `highlightedValue` | `string` | No | The controlled highlighted value of the combobox | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string control: string input: string content: string trigger: string clearTrigger: string item(id: string, index?: number | undefined): string positioner: string itemGroup(id: string | number): string itemGroupLabel(id: string | number): string }>` | No | The ids of the elements in the combobox. Useful for composition. | | `inputBehavior` | `'none' | 'autohighlight' | 'autocomplete'` | No | Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated | | `inputValue` | `string` | No | The controlled value of the combobox's input | | `invalid` | `boolean` | No | Whether the combobox is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items | | `modelValue` | `string[]` | No | The v-model value of the combobox | | `multiple` | `boolean` | No | Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. | | `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item | | `open` | `boolean` | No | The controlled open state of the combobox | | `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes | | `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input | | `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press | | `placeholder` | `string` | No | The placeholder text of the combobox's input | | `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu | | `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it | | `required` | `boolean` | No | Whether the combobox is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionBehavior` | `'clear' | 'replace' | 'preserve'` | No | The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested comboboxs | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-autofocus]` | | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-group | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-value]` | The value of the item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | label | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | list | | `[data-empty]` | Present when the content is empty | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ComboboxApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `focusable` | `boolean` | No | Whether the trigger is focusable | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | | `[data-focusable]` | | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `MaybeFunction>` | Yes | The collection of items | | `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input | | `alwaysSubmitOnEnter` | `boolean` | No | Whether to always submit on Enter key press, even if popup is open. Useful for single-field autocomplete forms where Enter should submit the form. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the input on mount | | `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. | | `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. | | `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. | | `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. | | `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. | | `disabled` | `boolean` | No | Whether the combobox is disabled | | `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer | | `form` | `string` | No | The associate form of the combobox. | | `highlightedValue` | `string` | No | The controlled highlighted value of the combobox | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string control: string input: string content: string trigger: string clearTrigger: string item: (id: string, index?: number | undefined) => string positioner: string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the combobox. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inputBehavior` | `'none' | 'autocomplete' | 'autohighlight'` | No | Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated | | `inputValue` | `string` | No | The controlled value of the combobox's input | | `invalid` | `boolean` | No | Whether the combobox is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items | | `multiple` | `boolean` | No | Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. | | `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when an item is highlighted using the pointer or keyboard navigation. | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Function called when the input's value changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when a new item is selected | | `open` | `boolean` | No | The controlled open state of the combobox | | `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes | | `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input | | `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press | | `placeholder` | `string` | No | The placeholder text of the combobox's input | | `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the combobox is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionBehavior` | `'replace' | 'clear' | 'preserve'` | No | The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the combobox's selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested comboboxs | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseComboboxContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-autofocus]` | | | `[data-state]` | "open" | "closed" | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseComboboxItemContext]>` | Yes | | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | | `ref` | `Element` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-group | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `{}` | No | | | `persistFocus` | `boolean` | No | | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-value]` | The value of the item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | label | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | list | | `[data-empty]` | Present when the content is empty | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseComboboxReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `ref` | `Element` | No | | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | | `[data-focusable]` | | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focused` | `boolean` | Whether the combobox is focused | | `open` | `boolean` | Whether the combobox is open | | `inputValue` | `string` | The value of the combobox input | | `highlightedValue` | `string` | The value of the highlighted item | | `highlightedItem` | `V` | The highlighted item | | `setHighlightValue` | `(value: string) => void` | The value of the combobox input | | `clearHighlightValue` | `VoidFunction` | Function to clear the highlighted value | | `syncSelectedItems` | `VoidFunction` | Function to sync the selected items with the value. Useful when `value` is updated from async sources. | | `selectedItems` | `V[]` | The selected items | | `hasSelectedItems` | `boolean` | Whether there's a selected item | | `value` | `string[]` | The selected item keys | | `valueAsString` | `string` | The string representation of the selected items | | `selectValue` | `(value: string) => void` | Function to select a value | | `setValue` | `(value: string[]) => void` | Function to set the value of the combobox | | `clearValue` | `(value?: string) => void` | Function to clear the value of the combobox | | `focus` | `VoidFunction` | Function to focus on the combobox input | | `setInputValue` | `(value: string, reason?: InputValueChangeReason) => void` | Function to set the input value of the combobox | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a combobox item | | `setOpen` | `(open: boolean, reason?: OpenChangeReason) => void` | Function to open or close the combobox | | `collection` | `ListCollection` | Function to toggle the combobox | | `reposition` | `(options?: Partial) => void` | Function to set the positioning options | | `multiple` | `boolean` | Whether the combobox allows multiple selections | | `disabled` | `boolean` | Whether the combobox is disabled | ## Accessibility Complies with the [Combobox WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/). ### Keyboard Support **`ArrowDown`** Description: When the combobox is closed, opens the listbox and highlights to the first option. When the combobox is open, moves focus to the next option. **`ArrowUp`** Description: When the combobox is closed, opens the listbox and highlights to the last option. When the combobox is open, moves focus to the previous option. **`Home`** Description: When the combobox is open, moves focus to the first option. **`End`** Description: When the combobox is open, moves focus to the last option. **`Escape`** Description: Closes the listbox. **`Enter`** Description: Selects the highlighted option and closes the combobox. **`Esc`** Description: Closes the combobox --- # Combobox (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const Basic = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }, { label: 'Orange', value: 'orange' }, { label: 'Mango', value: 'mango' }, { label: 'Pineapple', value: 'pineapple' }, { label: 'Strawberry', value: 'strawberry' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Favorite Fruit
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const Basic = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }, { label: 'Orange', value: 'orange' }, { label: 'Mango', value: 'mango' }, { label: 'Pineapple', value: 'pineapple' }, { label: 'Strawberry', value: 'strawberry' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Favorite Fruit
                    {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Fruit
                    Clear Open
                    No results found {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Auto Highlight Automatically highlight the first matching item as the user types by setting `inputBehavior="autohighlight"`. **Example: auto-highlight** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const AutoHighlight = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Engineering', value: 'engineering' }, { label: 'Marketing', value: 'marketing' }, { label: 'Sales', value: 'sales' }, { label: 'Finance', value: 'finance' }, { label: 'Human Resources', value: 'hr' }, { label: 'Operations', value: 'operations' }, { label: 'Product', value: 'product' }, { label: 'Customer Success', value: 'customer-success' }, { label: 'Legal', value: 'legal' }, { label: 'Information Technology', value: 'information-technology' }, { label: 'Design', value: 'design' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Department
                    No results found {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const AutoHighlight = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Engineering', value: 'engineering' }, { label: 'Marketing', value: 'marketing' }, { label: 'Sales', value: 'sales' }, { label: 'Finance', value: 'finance' }, { label: 'Human Resources', value: 'hr' }, { label: 'Operations', value: 'operations' }, { label: 'Product', value: 'product' }, { label: 'Customer Success', value: 'customer-success' }, { label: 'Legal', value: 'legal' }, { label: 'Information Technology', value: 'information-technology' }, { label: 'Design', value: 'design' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Department
                    Clear Open
                    No results found {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Department
                    Clear Open
                    No results found {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Inline Autocomplete Complete the input value with the first matching item by setting `inputBehavior="autocomplete"`. Use with `startsWith` filter for best results. **Example: inline-autocomplete** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const InlineAutocomplete = () => { const { startsWith } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Whale', value: 'whale' }, { label: 'Dolphin', value: 'dolphin' }, { label: 'Shark', value: 'shark' }, { label: 'Octopus', value: 'octopus' }, { label: 'Jellyfish', value: 'jellyfish' }, { label: 'Seahorse', value: 'seahorse' }, ], filter: startsWith, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Sea Creature
                    No results found {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const InlineAutocomplete = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Whale', value: 'whale' }, { label: 'Dolphin', value: 'dolphin' }, { label: 'Shark', value: 'shark' }, { label: 'Octopus', value: 'octopus' }, { label: 'Jellyfish', value: 'jellyfish' }, { label: 'Seahorse', value: 'seahorse' }, ], filter: filterFn().startsWith, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Sea Creature
                    Clear Open
                    No results found {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Sea Creature
                    Clear Open
                    No results found {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Grouping To group related combobox items, use the `groupBy` prop on the collection and `collection.group()` to iterate the groups. **Example: grouping** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const Grouping = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: contains, groupBy: (item) => item.continent, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {collection.group().map(([continent, group]) => ( {continent} {group.map((item) => ( {item.label} ))} ))}
                    ) } const initialItems = [ { label: 'Canada', value: 'ca', continent: 'North America' }, { label: 'United States', value: 'us', continent: 'North America' }, { label: 'Mexico', value: 'mx', continent: 'North America' }, { label: 'United Kingdom', value: 'uk', continent: 'Europe' }, { label: 'Germany', value: 'de', continent: 'Europe' }, { label: 'France', value: 'fr', continent: 'Europe' }, { label: 'Japan', value: 'jp', continent: 'Asia' }, { label: 'South Korea', value: 'kr', continent: 'Asia' }, { label: 'China', value: 'cn', continent: 'Asia' }, ] ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' const initialItems = [ { label: 'Canada', value: 'ca', continent: 'North America' }, { label: 'United States', value: 'us', continent: 'North America' }, { label: 'Mexico', value: 'mx', continent: 'North America' }, { label: 'United Kingdom', value: 'uk', continent: 'Europe' }, { label: 'Germany', value: 'de', continent: 'Europe' }, { label: 'France', value: 'fr', continent: 'Europe' }, { label: 'Japan', value: 'jp', continent: 'Asia' }, { label: 'South Korea', value: 'kr', continent: 'Asia' }, { label: 'China', value: 'cn', continent: 'Asia' }, ] export const Grouping = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: filterFn().contains, groupBy: (item) => item.continent, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {([continent, group]) => ( {continent} {(item) => ( {item.label} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Country
                    Clear Open
                    {#each collection().group() as [continent, group]} {continent} {#each group as item} {item.label} {/each} {/each}
                    ``` ### Field The `Field` component helps manage form-related state and accessibility attributes of a combobox. It includes handling ARIA labels, helper text, and error text to ensure proper accessibility. **Example: with-field** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { Field } from '@ark-ui/react/field' import { useFilter } from '@ark-ui/react/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' import field from 'styles/field.module.css' export const WithField = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Department
                    {collection.items.map((item) => ( {item.label} ))}
                    Select your primary department Department is required
                    ) } const initialItems = [ { label: 'Engineering', value: 'engineering' }, { label: 'Design', value: 'design' }, { label: 'Marketing', value: 'marketing' }, { label: 'Sales', value: 'sales' }, { label: 'Human Resources', value: 'hr' }, { label: 'Finance', value: 'finance' }, ] ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { Field } from '@ark-ui/solid/field' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import styles from 'styles/combobox.module.css' import field from 'styles/field.module.css' const initialItems = [ { label: 'Engineering', value: 'engineering' }, { label: 'Design', value: 'design' }, { label: 'Marketing', value: 'marketing' }, { label: 'Sales', value: 'sales' }, { label: 'Human Resources', value: 'hr' }, { label: 'Finance', value: 'finance' }, ] export const WithField = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Department
                    Clear Open
                    {(item) => ( {item.label} )}
                    Select your primary department Department is required
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Department
                    Clear Open
                    {#each collection().items as item (item.value)} {item.label} {/each}
                    Select your primary department Department is required
                    ``` ### Context Use the `Combobox.Context` component to access the combobox state and display information like the selected value. **Example: context** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const Context = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Small', value: 'sm' }, { label: 'Medium', value: 'md' }, { label: 'Large', value: 'lg' }, { label: 'Extra Large', value: 'xl' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( {(combobox) =>

                    Selected: {combobox.valueAsString || 'None'}

                    }
                    Size
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const Context = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Small', value: 'sm' }, { label: 'Medium', value: 'md' }, { label: 'Large', value: 'lg' }, { label: 'Extra Large', value: 'xl' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( {(context) =>

                    Selected: {context().valueAsString || 'None'}

                    }
                    Size
                    {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(combobox)}

                    Selected: {combobox().valueAsString || 'None'}

                    {/snippet}
                    Size
                    Clear Open
                    {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Root Provider An alternative way to control the combobox is to use the `RootProvider` component and the `useCombobox` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { Combobox, useCombobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/combobox.module.css' const initialItems = [ { label: 'Designer', value: 'designer' }, { label: 'Developer', value: 'developer' }, { label: 'Product Manager', value: 'pm' }, { label: 'Data Scientist', value: 'data-scientist' }, { label: 'DevOps Engineer', value: 'devops' }, { label: 'Marketing Lead', value: 'marketing' }, ] export const RootProvider = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: contains, }) const combobox = useCombobox({ collection, onInputValueChange(details) { filter(details.inputValue) }, }) return (
                    Job Title
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useCombobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/combobox.module.css' const initialItems = [ { label: 'Designer', value: 'designer' }, { label: 'Developer', value: 'developer' }, { label: 'Product Manager', value: 'pm' }, { label: 'Data Scientist', value: 'data-scientist' }, { label: 'DevOps Engineer', value: 'devops' }, { label: 'Marketing Lead', value: 'marketing' }, ] export const RootProvider = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: filterFn().contains, }) const combobox = useCombobox({ get collection() { return collection() }, onInputValueChange(details) { filter(details.inputValue) }, }) return (
                    Job Title
                    {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Job Title
                    Clear Open
                    {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Links Use the `asChild` prop to render the combobox items as links. **Example: links** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const Links = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Developer Resources
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } const initialItems = [ { label: 'GitHub', href: 'https://github.com', value: 'github' }, { label: 'Stack Overflow', href: 'https://stackoverflow.com', value: 'stackoverflow' }, { label: 'MDN Web Docs', href: 'https://developer.mozilla.org', value: 'mdn' }, { label: 'npm', href: 'https://www.npmjs.com', value: 'npm' }, { label: 'TypeScript', href: 'https://www.typescriptlang.org', value: 'typescript' }, { label: 'React', href: 'https://react.dev', value: 'react' }, ] ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' const initialItems = [ { label: 'GitHub', href: 'https://github.com', value: 'github' }, { label: 'Stack Overflow', href: 'https://stackoverflow.com', value: 'stackoverflow' }, { label: 'MDN Web Docs', href: 'https://developer.mozilla.org', value: 'mdn' }, { label: 'npm', href: 'https://www.npmjs.com', value: 'npm' }, { label: 'TypeScript', href: 'https://www.typescriptlang.org', value: 'typescript' }, { label: 'React', href: 'https://react.dev', value: 'react' }, ] export const Links = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Developer Resources
                    {(item) => ( }> {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Developer Resources
                    Open
                    {#each collection().items as item (item.value)} {#snippet asChild(props)}
                    {item.label} {/snippet} {/each} ``` ### Rehydrate When a combobox has a `defaultValue` or `value` but the `collection` is not loaded yet, you can rehydrate the value to populate the input. **Example: rehydrate-value** #### React ```tsx import { Combobox, useCombobox, useComboboxContext, useListCollection } from '@ark-ui/react/combobox' import { Portal } from '@ark-ui/react/portal' import { CheckIcon } from 'lucide-react' import { useRef, useState } from 'react' import { useAsync } from 'react-use' import styles from 'styles/combobox.module.css' function ComboboxRehydrateValue() { const combobox = useComboboxContext() const hydrated = useRef(false) if (combobox.value.length && combobox.collection.size && !hydrated.current) { combobox.syncSelectedItems() hydrated.current = true } return null } export const RehydrateValue = () => { const [inputValue, setInputValue] = useState('') const { collection, set } = useListCollection({ initialItems: [], itemToString: (item) => item.name, itemToValue: (item) => item.name, }) const combobox = useCombobox({ collection, defaultValue: ['C-3PO'], placeholder: 'Example: Dexter', inputValue, onInputValueChange: (e) => setInputValue(e.inputValue), }) const state = useAsync(async () => { const response = await fetch(`https://swapi.py4e.com/api/people/?search=${inputValue}`) const data = await response.json() set(data.results) }, [inputValue, set]) return ( Search Star Wars Characters {state.loading ? ( Loading... ) : state.error ? ( {state.error.message} ) : ( collection.items.map((item) => ( {item.name} - {item.height}cm / {item.mass}kg )) )} ) } interface Character { name: string height: string mass: string created: string edited: string url: string } ``` #### Solid ```tsx import { Combobox, useCombobox, useComboboxContext, useListCollection } from '@ark-ui/solid/combobox' import { For, createEffect, createRenderEffect, createSignal, on } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' import { useAsync } from './use-async' function ComboboxRehydrateValue() { const combobox = useComboboxContext() let hydrated = false createRenderEffect(() => { if (combobox().value.length && combobox().collection.size && !hydrated) { combobox().syncSelectedItems() hydrated = true } }) return null } export const RehydrateValue = () => { const [inputValue, setInputValue] = createSignal('') const { collection, set } = useListCollection({ initialItems: [], itemToString: (item) => item.name, itemToValue: (item) => item.name, }) const combobox = useCombobox(() => ({ collection: collection(), defaultValue: ['C-3PO'], placeholder: 'Example: Dexter', inputValue: inputValue(), onInputValueChange: (e) => setInputValue(e.inputValue), })) const state = useAsync(async (signal) => { const response = await fetch(`https://swapi.py4e.com/api/people/?search=${inputValue()}`, { signal }) const data = await response.json() set(data.results) }) createEffect(on(inputValue, () => state.load())) return ( Search Star Wars Characters {state.loading() ? ( Loading... ) : state.error() ? ( {state.error()?.message} ) : ( {(item) => ( {item.name} - {item.height}cm / {item.mass}kg )} )} ) } interface Character { name: string height: string mass: string created: string edited: string url: string } ``` #### Vue ```vue ``` #### Svelte ```svelte Search Star Wars Characters {#if _state.loading()} Loading... {:else if _state.error()} {_state.error()?.message} {:else} {#each collection().items as item (item.name)} {item.name} - {item.height}cm / {item.mass}kg {/each} {/if} ``` ### Highlight Text Highlight the matching search text in combobox items based on the user's input. **Example: highlight-matching-text** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { Highlight } from '@ark-ui/react/highlight' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const HighlightMatchingText = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'John Smith', value: 'john-smith' }, { label: 'Jane Doe', value: 'jane-doe' }, { label: 'Bob Johnson', value: 'bob-johnson' }, { label: 'Alice Williams', value: 'alice-williams' }, { label: 'Charlie Brown', value: 'charlie-brown' }, { label: 'Diana Ross', value: 'diana-ross' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Assignee
                    {collection.items.map((item) => ( {(context) => } ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { Highlight } from '@ark-ui/solid/highlight' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const HighlightMatchingText = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'John Smith', value: 'john-smith' }, { label: 'Jane Doe', value: 'jane-doe' }, { label: 'Bob Johnson', value: 'bob-johnson' }, { label: 'Alice Williams', value: 'alice-williams' }, { label: 'Charlie Brown', value: 'charlie-brown' }, { label: 'Diana Ross', value: 'diana-ross' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Assignee
                    Clear Open
                    {(item) => ( {(context) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Assignee
                    Clear Open
                    {#each collection().items as item (item.value)} {#snippet render(context)} {/snippet} {/each}
                    ``` ### Dynamic Generate combobox items dynamically based on user input. This is useful for creating suggestions or autocomplete functionality. **Example: dynamic** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' const suggestList = ['gmail.com', 'yahoo.com', 'ark-ui.com'] export const Dynamic = () => { const { collection, set } = useListCollection({ initialItems: [], }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { if (details.reason === 'input-change') { const items = suggestList.map((item) => `${details.inputValue}@${item}`) set(items) } } return ( Email
                    {collection.items.map((item) => ( {item} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' const suggestList = ['gmail.com', 'yahoo.com', 'ark-ui.com'] export const Dynamic = () => { const { collection, set } = useListCollection({ initialItems: [], }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { if (details.reason === 'input-change') { const items = suggestList.map((item) => `${details.inputValue}@${item}`) set(items) } } return ( Email
                    Open
                    {(item) => ( {item} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Email
                    Open
                    {#each collection().items as item (item)} {item} {/each}
                    ``` ### 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. **Example: creatable** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import { flushSync } from 'react-dom' import styles from 'styles/combobox.module.css' interface Item { label: string value: string __new__?: boolean } const NEW_OPTION_VALUE = '[[new]]' const createNewOption = (value: string): Item => ({ label: value, value: NEW_OPTION_VALUE }) const isNewOptionValue = (value: string) => value === NEW_OPTION_VALUE const replaceNewOptionValue = (values: string[], value: string) => values.map((v) => (v === NEW_OPTION_VALUE ? value : v)) const getNewOptionData = (inputValue: string): Item => ({ label: inputValue, value: inputValue, __new__: true }) export const Creatable = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter, upsert, update, remove } = useListCollection({ initialItems: [ { label: 'Bug', value: 'bug' }, { label: 'Feature', value: 'feature' }, { label: 'Enhancement', value: 'enhancement' }, { label: 'Documentation', value: 'docs' }, ], filter: contains, }) const isValidNewOption = (inputValue: string) => { const exactOptionMatch = collection.filter((item) => item.toLowerCase() === inputValue.toLowerCase()).size > 0 return !exactOptionMatch && inputValue.trim().length > 0 } const [selectedValue, setSelectedValue] = useState([]) const [inputValue, setInputValue] = useState('') const handleInputChange = ({ inputValue, reason }: Combobox.InputValueChangeDetails) => { if (reason === 'input-change' || reason === 'item-select') { flushSync(() => { if (isValidNewOption(inputValue)) { upsert(NEW_OPTION_VALUE, createNewOption(inputValue)) } else if (inputValue.trim().length === 0) { remove(NEW_OPTION_VALUE) } }) filter(inputValue) } setInputValue(inputValue) } const handleOpenChange = ({ reason }: Combobox.OpenChangeDetails) => { if (reason === 'trigger-click') { filter('') } } const handleValueChange = ({ value }: Combobox.ValueChangeDetails) => { setSelectedValue(replaceNewOptionValue(value, inputValue)) if (value.includes(NEW_OPTION_VALUE)) { console.log('New Option Created', inputValue) update(NEW_OPTION_VALUE, getNewOptionData(inputValue)) } } return ( Label
                    {collection.items.map((item) => ( {isNewOptionValue(item.value) ? ( + Create "{item.label}" ) : ( {item.label} {item.__new__ ? '(new)' : ''} )} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { createSignal, For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' interface Item { label: string value: string __new__?: boolean } const NEW_OPTION_VALUE = '[[new]]' const createNewOption = (value: string): Item => ({ label: value, value: NEW_OPTION_VALUE }) const isNewOptionValue = (value: string) => value === NEW_OPTION_VALUE const replaceNewOptionValue = (values: string[], value: string) => values.map((v) => (v === NEW_OPTION_VALUE ? value : v)) const getNewOptionData = (inputValue: string): Item => ({ label: inputValue, value: inputValue, __new__: true }) export const Creatable = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter, upsert, update, remove } = useListCollection({ initialItems: [ { label: 'Bug', value: 'bug' }, { label: 'Feature', value: 'feature' }, { label: 'Enhancement', value: 'enhancement' }, { label: 'Documentation', value: 'docs' }, ], filter: filterFn().contains, }) const isValidNewOption = (inputValue: string) => { const exactOptionMatch = collection().items.filter((item) => item.label.toLowerCase() === inputValue.toLowerCase()).length > 0 return !exactOptionMatch && inputValue.trim().length > 0 } const [selectedValue, setSelectedValue] = createSignal([]) const [inputValue, setInputValue] = createSignal('') const handleInputChange = ({ inputValue: newInputValue, reason }: Combobox.InputValueChangeDetails) => { if (reason === 'input-change' || reason === 'item-select') { if (isValidNewOption(newInputValue)) { upsert(NEW_OPTION_VALUE, createNewOption(newInputValue)) } else if (newInputValue.trim().length === 0) { remove(NEW_OPTION_VALUE) } filter(newInputValue) } setInputValue(newInputValue) } const handleOpenChange = ({ reason }: Combobox.OpenChangeDetails) => { if (reason === 'trigger-click') { filter('') } } const handleValueChange = ({ value }: Combobox.ValueChangeDetails) => { setSelectedValue(replaceNewOptionValue(value, inputValue())) if (value.includes(NEW_OPTION_VALUE)) { console.log('New Option Created', inputValue()) update(NEW_OPTION_VALUE, getNewOptionData(inputValue())) } } return ( Label
                    Clear Open
                    {(item) => ( {isNewOptionValue(item.value) ? ( + Create "{item.label}" ) : ( {item.label} {item.__new__ ? '(new)' : ''} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    Clear Open
                    {#each collection().items as item (item.value)} {#if isNewOptionValue(item.value)} + Create "{item.label}" {:else} {item.label} {item.__new__ ? '(new)' : ''} {/if} {/each}
                    ``` ### Multiple Selection Enable multiple selection by setting the `multiple` prop. Selected items can be displayed as tags above the input. **Example: multiple** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import { useRef } from 'react' import styles from 'styles/combobox.module.css' export const Multiple = () => { const { contains } = useFilter({ sensitivity: 'base' }) const selectedValue = useRef([]) const { collection, filter, remove } = useListCollection({ initialItems: [ { label: 'JavaScript', value: 'js' }, { label: 'TypeScript', value: 'ts' }, { label: 'Python', value: 'python' }, { label: 'Go', value: 'go' }, { label: 'Rust', value: 'rust' }, { label: 'Java', value: 'java' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } const handleValueChange = (details: Combobox.ValueChangeDetails) => { selectedValue.current = details.value remove(...details.value) } return ( Skills {(combobox) => (
                    {combobox.selectedItems.length === 0 && None selected} {combobox.selectedItems.map((item: any) => ( {item.label} ))}
                    )}
                    No skills found {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const Multiple = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter, remove } = useListCollection({ initialItems: [ { label: 'JavaScript', value: 'js' }, { label: 'TypeScript', value: 'ts' }, { label: 'Python', value: 'python' }, { label: 'Go', value: 'go' }, { label: 'Rust', value: 'rust' }, { label: 'Java', value: 'java' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } const handleValueChange = (details: Combobox.ValueChangeDetails) => { remove(...details.value) } return ( Skills {(context) => (
                    {context().selectedItems.length === 0 && None selected} {(item: any) => {item.label}}
                    )}
                    No skills found {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Skills
                    {#if selectedItems.length === 0} None selected {/if} {#each selectedItems as item (item.value)} {item.label} {/each}
                    Open
                    No skills found {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### 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. **Example: async-search** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { Combobox, createListCollection } from '@ark-ui/react/combobox' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, LoaderIcon, XIcon } from 'lucide-react' import { startTransition } from 'react' import styles from 'styles/combobox.module.css' interface Movie { id: string title: string year: number director: string genre: string } export const AsyncSearch = () => { const list = useAsyncList({ async load({ filterText, signal }) { if (!filterText) return { items: [] } await new Promise((resolve) => setTimeout(resolve, 300)) if (signal?.aborted) return { items: [] } const items = allMovies.filter( (movie) => movie.title.toLowerCase().includes(filterText.toLowerCase()) || movie.director.toLowerCase().includes(filterText.toLowerCase()) || movie.genre.toLowerCase().includes(filterText.toLowerCase()), ) return { items } }, }) const collection = createListCollection({ items: list.items, itemToString: (item) => item.title, itemToValue: (item) => item.id, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { if (details.reason === 'input-change') { startTransition(() => { list.setFilterText(details.inputValue) }) } } return ( Movie
                    {list.loading ? (
                    Searching...
                    ) : list.error ? (
                    {list.error.message}
                    ) : list.items.length === 0 ? (
                    {list.filterText ? 'No results found' : 'Start typing to search movies...'}
                    ) : ( collection.items.map((movie) => ( {movie.title} {movie.year} · {movie.director} )) )}
                    ) } const allMovies: Movie[] = [ { id: 'inception', title: 'Inception', year: 2010, director: 'Christopher Nolan', genre: 'Sci-Fi' }, { id: 'the-dark-knight', title: 'The Dark Knight', year: 2008, director: 'Christopher Nolan', genre: 'Action' }, { id: 'pulp-fiction', title: 'Pulp Fiction', year: 1994, director: 'Quentin Tarantino', genre: 'Crime' }, { id: 'the-godfather', title: 'The Godfather', year: 1972, director: 'Francis Ford Coppola', genre: 'Crime' }, { id: 'forrest-gump', title: 'Forrest Gump', year: 1994, director: 'Robert Zemeckis', genre: 'Drama' }, { id: 'the-matrix', title: 'The Matrix', year: 1999, director: 'The Wachowskis', genre: 'Sci-Fi' }, { id: 'interstellar', title: 'Interstellar', year: 2014, director: 'Christopher Nolan', genre: 'Sci-Fi' }, { id: 'parasite', title: 'Parasite', year: 2019, director: 'Bong Joon-ho', genre: 'Thriller' }, { id: 'the-shawshank-redemption', title: 'The Shawshank Redemption', year: 1994, director: 'Frank Darabont', genre: 'Drama', }, { id: 'fight-club', title: 'Fight Club', year: 1999, director: 'David Fincher', genre: 'Drama' }, { id: 'goodfellas', title: 'Goodfellas', year: 1990, director: 'Martin Scorsese', genre: 'Crime' }, { id: 'the-silence-of-the-lambs', title: 'The Silence of the Lambs', year: 1991, director: 'Jonathan Demme', genre: 'Thriller', }, ] ``` ### 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. **Example: virtualized** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { useVirtualizer } from '@tanstack/react-virtual' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import { useRef } from 'react' import { flushSync } from 'react-dom' import styles from 'styles/combobox.module.css' export const Virtualized = () => { const contentRef = useRef(null) const { startsWith } = useFilter({ sensitivity: 'base' }) const { collection, filter, reset } = useListCollection({ initialItems: countries, filter: startsWith, }) const virtualizer = useVirtualizer({ count: collection.size, getScrollElement: () => contentRef.current, estimateSize: () => 32, overscan: 10, }) const handleScrollToIndex: Combobox.RootProps['scrollToIndexFn'] = (details) => { flushSync(() => { virtualizer.scrollToIndex(details.index, { align: 'center', behavior: 'auto', }) }) } const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {virtualizer.getVirtualItems().map((virtualItem) => { const item = collection.items[virtualItem.index] return ( {item.emoji} {item.label} ) })}
                    ) } interface Country { value: string label: string emoji: string } const countries: Country[] = [ { value: 'AD', label: 'Andorra', emoji: '🇦🇩' }, { value: 'AE', label: 'United Arab Emirates', emoji: '🇦🇪' }, { value: 'AF', label: 'Afghanistan', emoji: '🇦🇫' }, { value: 'AG', label: 'Antigua and Barbuda', emoji: '🇦🇬' }, { value: 'AI', label: 'Anguilla', emoji: '🇦🇮' }, { value: 'AL', label: 'Albania', emoji: '🇦🇱' }, { value: 'AM', label: 'Armenia', emoji: '🇦🇲' }, { value: 'AO', label: 'Angola', emoji: '🇦🇴' }, { value: 'AQ', label: 'Antarctica', emoji: '🇦🇶' }, { value: 'AR', label: 'Argentina', emoji: '🇦🇷' }, { value: 'AS', label: 'American Samoa', emoji: '🇦🇸' }, { value: 'AT', label: 'Austria', emoji: '🇦🇹' }, { value: 'AU', label: 'Australia', emoji: '🇦🇺' }, { value: 'AW', label: 'Aruba', emoji: '🇦🇼' }, { value: 'AX', label: 'Åland Islands', emoji: '🇦🇽' }, { value: 'AZ', label: 'Azerbaijan', emoji: '🇦🇿' }, { value: 'BA', label: 'Bosnia and Herzegovina', emoji: '🇧🇦' }, { value: 'BB', label: 'Barbados', emoji: '🇧🇧' }, { value: 'BD', label: 'Bangladesh', emoji: '🇧🇩' }, { value: 'BE', label: 'Belgium', emoji: '🇧🇪' }, { value: 'BF', label: 'Burkina Faso', emoji: '🇧🇫' }, { value: 'BG', label: 'Bulgaria', emoji: '🇧🇬' }, { value: 'BH', label: 'Bahrain', emoji: '🇧🇭' }, { value: 'BI', label: 'Burundi', emoji: '🇧🇮' }, { value: 'BJ', label: 'Benin', emoji: '🇧🇯' }, { value: 'BL', label: 'Saint Barthélemy', emoji: '🇧🇱' }, { value: 'BM', label: 'Bermuda', emoji: '🇧🇲' }, { value: 'BN', label: 'Brunei', emoji: '🇧🇳' }, { value: 'BO', label: 'Bolivia', emoji: '🇧🇴' }, { value: 'BR', label: 'Brazil', emoji: '🇧🇷' }, { value: 'BS', label: 'Bahamas', emoji: '🇧🇸' }, { value: 'BT', label: 'Bhutan', emoji: '🇧🇹' }, { value: 'BW', label: 'Botswana', emoji: '🇧🇼' }, { value: 'BY', label: 'Belarus', emoji: '🇧🇾' }, { value: 'BZ', label: 'Belize', emoji: '🇧🇿' }, { value: 'CA', label: 'Canada', emoji: '🇨🇦' }, { value: 'CD', label: 'Congo', emoji: '🇨🇩' }, { value: 'CF', label: 'Central African Republic', emoji: '🇨🇫' }, { value: 'CH', label: 'Switzerland', emoji: '🇨🇭' }, { value: 'CI', label: "Côte d'Ivoire", emoji: '🇨🇮' }, { value: 'CK', label: 'Cook Islands', emoji: '🇨🇰' }, { value: 'CL', label: 'Chile', emoji: '🇨🇱' }, { value: 'CM', label: 'Cameroon', emoji: '🇨🇲' }, { value: 'CN', label: 'China', emoji: '🇨🇳' }, { value: 'CO', label: 'Colombia', emoji: '🇨🇴' }, { value: 'CR', label: 'Costa Rica', emoji: '🇨🇷' }, { value: 'CU', label: 'Cuba', emoji: '🇨🇺' }, { value: 'CV', label: 'Cabo Verde', emoji: '🇨🇻' }, { value: 'CY', label: 'Cyprus', emoji: '🇨🇾' }, { value: 'CZ', label: 'Czech Republic', emoji: '🇨🇿' }, { value: 'DE', label: 'Germany', emoji: '🇩🇪' }, { value: 'DJ', label: 'Djibouti', emoji: '🇩🇯' }, { value: 'DK', label: 'Denmark', emoji: '🇩🇰' }, { value: 'DM', label: 'Dominica', emoji: '🇩🇲' }, { value: 'DO', label: 'Dominican Republic', emoji: '🇩🇴' }, { value: 'DZ', label: 'Algeria', emoji: '🇩🇿' }, { value: 'EC', label: 'Ecuador', emoji: '🇪🇨' }, { value: 'EE', label: 'Estonia', emoji: '🇪🇪' }, { value: 'EG', label: 'Egypt', emoji: '🇪🇬' }, { value: 'ER', label: 'Eritrea', emoji: '🇪🇷' }, { value: 'ES', label: 'Spain', emoji: '🇪🇸' }, { value: 'ET', label: 'Ethiopia', emoji: '🇪🇹' }, { value: 'FI', label: 'Finland', emoji: '🇫🇮' }, { value: 'FJ', label: 'Fiji', emoji: '🇫🇯' }, { value: 'FK', label: 'Falkland Islands', emoji: '🇫🇰' }, { value: 'FM', label: 'Micronesia', emoji: '🇫🇲' }, { value: 'FO', label: 'Faroe Islands', emoji: '🇫🇴' }, { value: 'FR', label: 'France', emoji: '🇫🇷' }, { value: 'GA', label: 'Gabon', emoji: '🇬🇦' }, { value: 'GB', label: 'United Kingdom', emoji: '🇬🇧' }, { value: 'GD', label: 'Grenada', emoji: '🇬🇩' }, { value: 'GE', label: 'Georgia', emoji: '🇬🇪' }, { value: 'GH', label: 'Ghana', emoji: '🇬🇭' }, { value: 'GI', label: 'Gibraltar', emoji: '🇬🇮' }, { value: 'GL', label: 'Greenland', emoji: '🇬🇱' }, { value: 'GM', label: 'Gambia', emoji: '🇬🇲' }, { value: 'GN', label: 'Guinea', emoji: '🇬🇳' }, { value: 'GQ', label: 'Equatorial Guinea', emoji: '🇬🇶' }, { value: 'GR', label: 'Greece', emoji: '🇬🇷' }, { value: 'GT', label: 'Guatemala', emoji: '🇬🇹' }, { value: 'GU', label: 'Guam', emoji: '🇬🇺' }, { value: 'GW', label: 'Guinea-Bissau', emoji: '🇬🇼' }, { value: 'GY', label: 'Guyana', emoji: '🇬🇾' }, { value: 'HK', label: 'Hong Kong', emoji: '🇭🇰' }, { value: 'HN', label: 'Honduras', emoji: '🇭🇳' }, { value: 'HR', label: 'Croatia', emoji: '🇭🇷' }, { value: 'HT', label: 'Haiti', emoji: '🇭🇹' }, { value: 'HU', label: 'Hungary', emoji: '🇭🇺' }, { value: 'ID', label: 'Indonesia', emoji: '🇮🇩' }, { value: 'IE', label: 'Ireland', emoji: '🇮🇪' }, { value: 'IL', label: 'Israel', emoji: '🇮🇱' }, { value: 'IM', label: 'Isle of Man', emoji: '🇮🇲' }, { value: 'IN', label: 'India', emoji: '🇮🇳' }, { value: 'IQ', label: 'Iraq', emoji: '🇮🇶' }, { value: 'IR', label: 'Iran', emoji: '🇮🇷' }, { value: 'IS', label: 'Iceland', emoji: '🇮🇸' }, { value: 'IT', label: 'Italy', emoji: '🇮🇹' }, { value: 'JE', label: 'Jersey', emoji: '🇯🇪' }, { value: 'JM', label: 'Jamaica', emoji: '🇯🇲' }, { value: 'JO', label: 'Jordan', emoji: '🇯🇴' }, { value: 'JP', label: 'Japan', emoji: '🇯🇵' }, { value: 'KE', label: 'Kenya', emoji: '🇰🇪' }, { value: 'KG', label: 'Kyrgyzstan', emoji: '🇰🇬' }, { value: 'KH', label: 'Cambodia', emoji: '🇰🇭' }, { value: 'KI', label: 'Kiribati', emoji: '🇰🇮' }, { value: 'KM', label: 'Comoros', emoji: '🇰🇲' }, { value: 'KN', label: 'Saint Kitts and Nevis', emoji: '🇰🇳' }, { value: 'KP', label: 'North Korea', emoji: '🇰🇵' }, { value: 'KR', label: 'South Korea', emoji: '🇰🇷' }, { value: 'KW', label: 'Kuwait', emoji: '🇰🇼' }, { value: 'KY', label: 'Cayman Islands', emoji: '🇰🇾' }, { value: 'KZ', label: 'Kazakhstan', emoji: '🇰🇿' }, { value: 'LA', label: 'Laos', emoji: '🇱🇦' }, { value: 'LB', label: 'Lebanon', emoji: '🇱🇧' }, { value: 'LC', label: 'Saint Lucia', emoji: '🇱🇨' }, { value: 'LI', label: 'Liechtenstein', emoji: '🇱🇮' }, { value: 'LK', label: 'Sri Lanka', emoji: '🇱🇰' }, { value: 'LR', label: 'Liberia', emoji: '🇱🇷' }, { value: 'LS', label: 'Lesotho', emoji: '🇱🇸' }, { value: 'LT', label: 'Lithuania', emoji: '🇱🇹' }, { value: 'LU', label: 'Luxembourg', emoji: '🇱🇺' }, { value: 'LV', label: 'Latvia', emoji: '🇱🇻' }, { value: 'LY', label: 'Libya', emoji: '🇱🇾' }, { value: 'MA', label: 'Morocco', emoji: '🇲🇦' }, { value: 'MC', label: 'Monaco', emoji: '🇲🇨' }, { value: 'MD', label: 'Moldova', emoji: '🇲🇩' }, { value: 'ME', label: 'Montenegro', emoji: '🇲🇪' }, { value: 'MG', label: 'Madagascar', emoji: '🇲🇬' }, { value: 'MH', label: 'Marshall Islands', emoji: '🇲🇭' }, { value: 'MK', label: 'North Macedonia', emoji: '🇲🇰' }, { value: 'ML', label: 'Mali', emoji: '🇲🇱' }, { value: 'MM', label: 'Myanmar', emoji: '🇲🇲' }, { value: 'MN', label: 'Mongolia', emoji: '🇲🇳' }, { value: 'MO', label: 'Macao', emoji: '🇲🇴' }, { value: 'MR', label: 'Mauritania', emoji: '🇲🇷' }, { value: 'MS', label: 'Montserrat', emoji: '🇲🇸' }, { value: 'MT', label: 'Malta', emoji: '🇲🇹' }, { value: 'MU', label: 'Mauritius', emoji: '🇲🇺' }, { value: 'MV', label: 'Maldives', emoji: '🇲🇻' }, { value: 'MW', label: 'Malawi', emoji: '🇲🇼' }, { value: 'MX', label: 'Mexico', emoji: '🇲🇽' }, { value: 'MY', label: 'Malaysia', emoji: '🇲🇾' }, { value: 'MZ', label: 'Mozambique', emoji: '🇲🇿' }, { value: 'NA', label: 'Namibia', emoji: '🇳🇦' }, { value: 'NC', label: 'New Caledonia', emoji: '🇳🇨' }, { value: 'NE', label: 'Niger', emoji: '🇳🇪' }, { value: 'NF', label: 'Norfolk Island', emoji: '🇳🇫' }, { value: 'NG', label: 'Nigeria', emoji: '🇳🇬' }, { value: 'NI', label: 'Nicaragua', emoji: '🇳🇮' }, { value: 'NL', label: 'Netherlands', emoji: '🇳🇱' }, { value: 'NO', label: 'Norway', emoji: '🇳🇴' }, { value: 'NP', label: 'Nepal', emoji: '🇳🇵' }, { value: 'NR', label: 'Nauru', emoji: '🇳🇷' }, { value: 'NU', label: 'Niue', emoji: '🇳🇺' }, { value: 'NZ', label: 'New Zealand', emoji: '🇳🇿' }, { value: 'OM', label: 'Oman', emoji: '🇴🇲' }, { value: 'PA', label: 'Panama', emoji: '🇵🇦' }, { value: 'PE', label: 'Peru', emoji: '🇵🇪' }, { value: 'PF', label: 'French Polynesia', emoji: '🇵🇫' }, { value: 'PG', label: 'Papua New Guinea', emoji: '🇵🇬' }, { value: 'PH', label: 'Philippines', emoji: '🇵🇭' }, { value: 'PK', label: 'Pakistan', emoji: '🇵🇰' }, { value: 'PL', label: 'Poland', emoji: '🇵🇱' }, { value: 'PR', label: 'Puerto Rico', emoji: '🇵🇷' }, { value: 'PS', label: 'Palestine', emoji: '🇵🇸' }, { value: 'PT', label: 'Portugal', emoji: '🇵🇹' }, { value: 'PW', label: 'Palau', emoji: '🇵🇼' }, { value: 'PY', label: 'Paraguay', emoji: '🇵🇾' }, { value: 'QA', label: 'Qatar', emoji: '🇶🇦' }, { value: 'RO', label: 'Romania', emoji: '🇷🇴' }, { value: 'RS', label: 'Serbia', emoji: '🇷🇸' }, { value: 'RU', label: 'Russia', emoji: '🇷🇺' }, { value: 'RW', label: 'Rwanda', emoji: '🇷🇼' }, { value: 'SA', label: 'Saudi Arabia', emoji: '🇸🇦' }, { value: 'SB', label: 'Solomon Islands', emoji: '🇸🇧' }, { value: 'SC', label: 'Seychelles', emoji: '🇸🇨' }, { value: 'SD', label: 'Sudan', emoji: '🇸🇩' }, { value: 'SE', label: 'Sweden', emoji: '🇸🇪' }, { value: 'SG', label: 'Singapore', emoji: '🇸🇬' }, { value: 'SI', label: 'Slovenia', emoji: '🇸🇮' }, { value: 'SK', label: 'Slovakia', emoji: '🇸🇰' }, { value: 'SL', label: 'Sierra Leone', emoji: '🇸🇱' }, { value: 'SM', label: 'San Marino', emoji: '🇸🇲' }, { value: 'SN', label: 'Senegal', emoji: '🇸🇳' }, { value: 'SO', label: 'Somalia', emoji: '🇸🇴' }, { value: 'SR', label: 'Suriname', emoji: '🇸🇷' }, { value: 'SS', label: 'South Sudan', emoji: '🇸🇸' }, { value: 'ST', label: 'Sao Tome and Principe', emoji: '🇸🇹' }, { value: 'SV', label: 'El Salvador', emoji: '🇸🇻' }, { value: 'SY', label: 'Syria', emoji: '🇸🇾' }, { value: 'SZ', label: 'Eswatini', emoji: '🇸🇿' }, { value: 'TC', label: 'Turks and Caicos Islands', emoji: '🇹🇨' }, { value: 'TD', label: 'Chad', emoji: '🇹🇩' }, { value: 'TG', label: 'Togo', emoji: '🇹🇬' }, { value: 'TH', label: 'Thailand', emoji: '🇹🇭' }, { value: 'TJ', label: 'Tajikistan', emoji: '🇹🇯' }, { value: 'TK', label: 'Tokelau', emoji: '🇹🇰' }, { value: 'TL', label: 'Timor-Leste', emoji: '🇹🇱' }, { value: 'TM', label: 'Turkmenistan', emoji: '🇹🇲' }, { value: 'TN', label: 'Tunisia', emoji: '🇹🇳' }, { value: 'TO', label: 'Tonga', emoji: '🇹🇴' }, { value: 'TR', label: 'Türkiye', emoji: '🇹🇷' }, { value: 'TT', label: 'Trinidad and Tobago', emoji: '🇹🇹' }, { value: 'TV', label: 'Tuvalu', emoji: '🇹🇻' }, { value: 'TW', label: 'Taiwan', emoji: '🇹🇼' }, { value: 'TZ', label: 'Tanzania', emoji: '🇹🇿' }, { value: 'UA', label: 'Ukraine', emoji: '🇺🇦' }, { value: 'UG', label: 'Uganda', emoji: '🇺🇬' }, { value: 'US', label: 'United States', emoji: '🇺🇸' }, { value: 'UY', label: 'Uruguay', emoji: '🇺🇾' }, { value: 'UZ', label: 'Uzbekistan', emoji: '🇺🇿' }, { value: 'VA', label: 'Vatican City', emoji: '🇻🇦' }, { value: 'VC', label: 'Saint Vincent and the Grenadines', emoji: '🇻🇨' }, { value: 'VE', label: 'Venezuela', emoji: '🇻🇪' }, { value: 'VG', label: 'British Virgin Islands', emoji: '🇻🇬' }, { value: 'VI', label: 'U.S. Virgin Islands', emoji: '🇻🇮' }, { value: 'VN', label: 'Vietnam', emoji: '🇻🇳' }, { value: 'VU', label: 'Vanuatu', emoji: '🇻🇺' }, { value: 'WF', label: 'Wallis and Futuna', emoji: '🇼🇫' }, { value: 'WS', label: 'Samoa', emoji: '🇼🇸' }, { value: 'YE', label: 'Yemen', emoji: '🇾🇪' }, { value: 'YT', label: 'Mayotte', emoji: '🇾🇹' }, { value: 'ZA', label: 'South Africa', emoji: '🇿🇦' }, { value: 'ZM', label: 'Zambia', emoji: '🇿🇲' }, { value: 'ZW', label: 'Zimbabwe', emoji: '🇿🇼' }, ] ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { createVirtualizer } from '@tanstack/solid-virtual' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const Virtualized = () => { let contentRef: HTMLDivElement | undefined const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter, reset } = useListCollection({ initialItems: countries, filter: filterFn().startsWith, }) const virtualizer = createVirtualizer({ get count() { return collection().size }, getScrollElement: () => contentRef ?? null, estimateSize: () => 32, overscan: 10, }) const handleScrollToIndex: Combobox.RootProps['scrollToIndexFn'] = (details) => { virtualizer.scrollToIndex(details.index, { align: 'center', behavior: 'auto', }) } const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {virtualizer.getVirtualItems().map((virtualItem) => { const item = collection().items[virtualItem.index] return ( {item.emoji} {item.label} ) })}
                    ) } interface Country { value: string label: string emoji: string } const countries: Country[] = [ { value: 'AD', label: 'Andorra', emoji: '🇦🇩' }, { value: 'AE', label: 'United Arab Emirates', emoji: '🇦🇪' }, { value: 'AF', label: 'Afghanistan', emoji: '🇦🇫' }, { value: 'AG', label: 'Antigua and Barbuda', emoji: '🇦🇬' }, { value: 'AI', label: 'Anguilla', emoji: '🇦🇮' }, { value: 'AL', label: 'Albania', emoji: '🇦🇱' }, { value: 'AM', label: 'Armenia', emoji: '🇦🇲' }, { value: 'AO', label: 'Angola', emoji: '🇦🇴' }, { value: 'AQ', label: 'Antarctica', emoji: '🇦🇶' }, { value: 'AR', label: 'Argentina', emoji: '🇦🇷' }, { value: 'AS', label: 'American Samoa', emoji: '🇦🇸' }, { value: 'AT', label: 'Austria', emoji: '🇦🇹' }, { value: 'AU', label: 'Australia', emoji: '🇦🇺' }, { value: 'AW', label: 'Aruba', emoji: '🇦🇼' }, { value: 'AX', label: 'Åland Islands', emoji: '🇦🇽' }, { value: 'AZ', label: 'Azerbaijan', emoji: '🇦🇿' }, { value: 'BA', label: 'Bosnia and Herzegovina', emoji: '🇧🇦' }, { value: 'BB', label: 'Barbados', emoji: '🇧🇧' }, { value: 'BD', label: 'Bangladesh', emoji: '🇧🇩' }, { value: 'BE', label: 'Belgium', emoji: '🇧🇪' }, { value: 'BF', label: 'Burkina Faso', emoji: '🇧🇫' }, { value: 'BG', label: 'Bulgaria', emoji: '🇧🇬' }, { value: 'BH', label: 'Bahrain', emoji: '🇧🇭' }, { value: 'BI', label: 'Burundi', emoji: '🇧🇮' }, { value: 'BJ', label: 'Benin', emoji: '🇧🇯' }, { value: 'BL', label: 'Saint Barthélemy', emoji: '🇧🇱' }, { value: 'BM', label: 'Bermuda', emoji: '🇧🇲' }, { value: 'BN', label: 'Brunei', emoji: '🇧🇳' }, { value: 'BO', label: 'Bolivia', emoji: '🇧🇴' }, { value: 'BR', label: 'Brazil', emoji: '🇧🇷' }, { value: 'BS', label: 'Bahamas', emoji: '🇧🇸' }, { value: 'BT', label: 'Bhutan', emoji: '🇧🇹' }, { value: 'BW', label: 'Botswana', emoji: '🇧🇼' }, { value: 'BY', label: 'Belarus', emoji: '🇧🇾' }, { value: 'BZ', label: 'Belize', emoji: '🇧🇿' }, { value: 'CA', label: 'Canada', emoji: '🇨🇦' }, { value: 'CD', label: 'Congo', emoji: '🇨🇩' }, { value: 'CF', label: 'Central African Republic', emoji: '🇨🇫' }, { value: 'CH', label: 'Switzerland', emoji: '🇨🇭' }, { value: 'CI', label: "Côte d'Ivoire", emoji: '🇨🇮' }, { value: 'CK', label: 'Cook Islands', emoji: '🇨🇰' }, { value: 'CL', label: 'Chile', emoji: '🇨🇱' }, { value: 'CM', label: 'Cameroon', emoji: '🇨🇲' }, { value: 'CN', label: 'China', emoji: '🇨🇳' }, { value: 'CO', label: 'Colombia', emoji: '🇨🇴' }, { value: 'CR', label: 'Costa Rica', emoji: '🇨🇷' }, { value: 'CU', label: 'Cuba', emoji: '🇨🇺' }, { value: 'CV', label: 'Cabo Verde', emoji: '🇨🇻' }, { value: 'CY', label: 'Cyprus', emoji: '🇨🇾' }, { value: 'CZ', label: 'Czech Republic', emoji: '🇨🇿' }, { value: 'DE', label: 'Germany', emoji: '🇩🇪' }, { value: 'DJ', label: 'Djibouti', emoji: '🇩🇯' }, { value: 'DK', label: 'Denmark', emoji: '🇩🇰' }, { value: 'DM', label: 'Dominica', emoji: '🇩🇲' }, { value: 'DO', label: 'Dominican Republic', emoji: '🇩🇴' }, { value: 'DZ', label: 'Algeria', emoji: '🇩🇿' }, { value: 'EC', label: 'Ecuador', emoji: '🇪🇨' }, { value: 'EE', label: 'Estonia', emoji: '🇪🇪' }, { value: 'EG', label: 'Egypt', emoji: '🇪🇬' }, { value: 'ER', label: 'Eritrea', emoji: '🇪🇷' }, { value: 'ES', label: 'Spain', emoji: '🇪🇸' }, { value: 'ET', label: 'Ethiopia', emoji: '🇪🇹' }, { value: 'FI', label: 'Finland', emoji: '🇫🇮' }, { value: 'FJ', label: 'Fiji', emoji: '🇫🇯' }, { value: 'FK', label: 'Falkland Islands', emoji: '🇫🇰' }, { value: 'FM', label: 'Micronesia', emoji: '🇫🇲' }, { value: 'FO', label: 'Faroe Islands', emoji: '🇫🇴' }, { value: 'FR', label: 'France', emoji: '🇫🇷' }, { value: 'GA', label: 'Gabon', emoji: '🇬🇦' }, { value: 'GB', label: 'United Kingdom', emoji: '🇬🇧' }, { value: 'GD', label: 'Grenada', emoji: '🇬🇩' }, { value: 'GE', label: 'Georgia', emoji: '🇬🇪' }, { value: 'GH', label: 'Ghana', emoji: '🇬🇭' }, { value: 'GI', label: 'Gibraltar', emoji: '🇬🇮' }, { value: 'GL', label: 'Greenland', emoji: '🇬🇱' }, { value: 'GM', label: 'Gambia', emoji: '🇬🇲' }, { value: 'GN', label: 'Guinea', emoji: '🇬🇳' }, { value: 'GQ', label: 'Equatorial Guinea', emoji: '🇬🇶' }, { value: 'GR', label: 'Greece', emoji: '🇬🇷' }, { value: 'GT', label: 'Guatemala', emoji: '🇬🇹' }, { value: 'GU', label: 'Guam', emoji: '🇬🇺' }, { value: 'GW', label: 'Guinea-Bissau', emoji: '🇬🇼' }, { value: 'GY', label: 'Guyana', emoji: '🇬🇾' }, { value: 'HK', label: 'Hong Kong', emoji: '🇭🇰' }, { value: 'HN', label: 'Honduras', emoji: '🇭🇳' }, { value: 'HR', label: 'Croatia', emoji: '🇭🇷' }, { value: 'HT', label: 'Haiti', emoji: '🇭🇹' }, { value: 'HU', label: 'Hungary', emoji: '🇭🇺' }, { value: 'ID', label: 'Indonesia', emoji: '🇮🇩' }, { value: 'IE', label: 'Ireland', emoji: '🇮🇪' }, { value: 'IL', label: 'Israel', emoji: '🇮🇱' }, { value: 'IM', label: 'Isle of Man', emoji: '🇮🇲' }, { value: 'IN', label: 'India', emoji: '🇮🇳' }, { value: 'IQ', label: 'Iraq', emoji: '🇮🇶' }, { value: 'IR', label: 'Iran', emoji: '🇮🇷' }, { value: 'IS', label: 'Iceland', emoji: '🇮🇸' }, { value: 'IT', label: 'Italy', emoji: '🇮🇹' }, { value: 'JE', label: 'Jersey', emoji: '🇯🇪' }, { value: 'JM', label: 'Jamaica', emoji: '🇯🇲' }, { value: 'JO', label: 'Jordan', emoji: '🇯🇴' }, { value: 'JP', label: 'Japan', emoji: '🇯🇵' }, { value: 'KE', label: 'Kenya', emoji: '🇰🇪' }, { value: 'KG', label: 'Kyrgyzstan', emoji: '🇰🇬' }, { value: 'KH', label: 'Cambodia', emoji: '🇰🇭' }, { value: 'KI', label: 'Kiribati', emoji: '🇰🇮' }, { value: 'KM', label: 'Comoros', emoji: '🇰🇲' }, { value: 'KN', label: 'Saint Kitts and Nevis', emoji: '🇰🇳' }, { value: 'KP', label: 'North Korea', emoji: '🇰🇵' }, { value: 'KR', label: 'South Korea', emoji: '🇰🇷' }, { value: 'KW', label: 'Kuwait', emoji: '🇰🇼' }, { value: 'KY', label: 'Cayman Islands', emoji: '🇰🇾' }, { value: 'KZ', label: 'Kazakhstan', emoji: '🇰🇿' }, { value: 'LA', label: 'Laos', emoji: '🇱🇦' }, { value: 'LB', label: 'Lebanon', emoji: '🇱🇧' }, { value: 'LC', label: 'Saint Lucia', emoji: '🇱🇨' }, { value: 'LI', label: 'Liechtenstein', emoji: '🇱🇮' }, { value: 'LK', label: 'Sri Lanka', emoji: '🇱🇰' }, { value: 'LR', label: 'Liberia', emoji: '🇱🇷' }, { value: 'LS', label: 'Lesotho', emoji: '🇱🇸' }, { value: 'LT', label: 'Lithuania', emoji: '🇱🇹' }, { value: 'LU', label: 'Luxembourg', emoji: '🇱🇺' }, { value: 'LV', label: 'Latvia', emoji: '🇱🇻' }, { value: 'LY', label: 'Libya', emoji: '🇱🇾' }, { value: 'MA', label: 'Morocco', emoji: '🇲🇦' }, { value: 'MC', label: 'Monaco', emoji: '🇲🇨' }, { value: 'MD', label: 'Moldova', emoji: '🇲🇩' }, { value: 'ME', label: 'Montenegro', emoji: '🇲🇪' }, { value: 'MG', label: 'Madagascar', emoji: '🇲🇬' }, { value: 'MH', label: 'Marshall Islands', emoji: '🇲🇭' }, { value: 'MK', label: 'North Macedonia', emoji: '🇲🇰' }, { value: 'ML', label: 'Mali', emoji: '🇲🇱' }, { value: 'MM', label: 'Myanmar', emoji: '🇲🇲' }, { value: 'MN', label: 'Mongolia', emoji: '🇲🇳' }, { value: 'MO', label: 'Macao', emoji: '🇲🇴' }, { value: 'MR', label: 'Mauritania', emoji: '🇲🇷' }, { value: 'MS', label: 'Montserrat', emoji: '🇲🇸' }, { value: 'MT', label: 'Malta', emoji: '🇲🇹' }, { value: 'MU', label: 'Mauritius', emoji: '🇲🇺' }, { value: 'MV', label: 'Maldives', emoji: '🇲🇻' }, { value: 'MW', label: 'Malawi', emoji: '🇲🇼' }, { value: 'MX', label: 'Mexico', emoji: '🇲🇽' }, { value: 'MY', label: 'Malaysia', emoji: '🇲🇾' }, { value: 'MZ', label: 'Mozambique', emoji: '🇲🇿' }, { value: 'NA', label: 'Namibia', emoji: '🇳🇦' }, { value: 'NC', label: 'New Caledonia', emoji: '🇳🇨' }, { value: 'NE', label: 'Niger', emoji: '🇳🇪' }, { value: 'NF', label: 'Norfolk Island', emoji: '🇳🇫' }, { value: 'NG', label: 'Nigeria', emoji: '🇳🇬' }, { value: 'NI', label: 'Nicaragua', emoji: '🇳🇮' }, { value: 'NL', label: 'Netherlands', emoji: '🇳🇱' }, { value: 'NO', label: 'Norway', emoji: '🇳🇴' }, { value: 'NP', label: 'Nepal', emoji: '🇳🇵' }, { value: 'NR', label: 'Nauru', emoji: '🇳🇷' }, { value: 'NU', label: 'Niue', emoji: '🇳🇺' }, { value: 'NZ', label: 'New Zealand', emoji: '🇳🇿' }, { value: 'OM', label: 'Oman', emoji: '🇴🇲' }, { value: 'PA', label: 'Panama', emoji: '🇵🇦' }, { value: 'PE', label: 'Peru', emoji: '🇵🇪' }, { value: 'PF', label: 'French Polynesia', emoji: '🇵🇫' }, { value: 'PG', label: 'Papua New Guinea', emoji: '🇵🇬' }, { value: 'PH', label: 'Philippines', emoji: '🇵🇭' }, { value: 'PK', label: 'Pakistan', emoji: '🇵🇰' }, { value: 'PL', label: 'Poland', emoji: '🇵🇱' }, { value: 'PR', label: 'Puerto Rico', emoji: '🇵🇷' }, { value: 'PS', label: 'Palestine', emoji: '🇵🇸' }, { value: 'PT', label: 'Portugal', emoji: '🇵🇹' }, { value: 'PW', label: 'Palau', emoji: '🇵🇼' }, { value: 'PY', label: 'Paraguay', emoji: '🇵🇾' }, { value: 'QA', label: 'Qatar', emoji: '🇶🇦' }, { value: 'RO', label: 'Romania', emoji: '🇷🇴' }, { value: 'RS', label: 'Serbia', emoji: '🇷🇸' }, { value: 'RU', label: 'Russia', emoji: '🇷🇺' }, { value: 'RW', label: 'Rwanda', emoji: '🇷🇼' }, { value: 'SA', label: 'Saudi Arabia', emoji: '🇸🇦' }, { value: 'SB', label: 'Solomon Islands', emoji: '🇸🇧' }, { value: 'SC', label: 'Seychelles', emoji: '🇸🇨' }, { value: 'SD', label: 'Sudan', emoji: '🇸🇩' }, { value: 'SE', label: 'Sweden', emoji: '🇸🇪' }, { value: 'SG', label: 'Singapore', emoji: '🇸🇬' }, { value: 'SI', label: 'Slovenia', emoji: '🇸🇮' }, { value: 'SK', label: 'Slovakia', emoji: '🇸🇰' }, { value: 'SL', label: 'Sierra Leone', emoji: '🇸🇱' }, { value: 'SM', label: 'San Marino', emoji: '🇸🇲' }, { value: 'SN', label: 'Senegal', emoji: '🇸🇳' }, { value: 'SO', label: 'Somalia', emoji: '🇸🇴' }, { value: 'SR', label: 'Suriname', emoji: '🇸🇷' }, { value: 'SS', label: 'South Sudan', emoji: '🇸🇸' }, { value: 'ST', label: 'Sao Tome and Principe', emoji: '🇸🇹' }, { value: 'SV', label: 'El Salvador', emoji: '🇸🇻' }, { value: 'SY', label: 'Syria', emoji: '🇸🇾' }, { value: 'SZ', label: 'Eswatini', emoji: '🇸🇿' }, { value: 'TC', label: 'Turks and Caicos Islands', emoji: '🇹🇨' }, { value: 'TD', label: 'Chad', emoji: '🇹🇩' }, { value: 'TG', label: 'Togo', emoji: '🇹🇬' }, { value: 'TH', label: 'Thailand', emoji: '🇹🇭' }, { value: 'TJ', label: 'Tajikistan', emoji: '🇹🇯' }, { value: 'TK', label: 'Tokelau', emoji: '🇹🇰' }, { value: 'TL', label: 'Timor-Leste', emoji: '🇹🇱' }, { value: 'TM', label: 'Turkmenistan', emoji: '🇹🇲' }, { value: 'TN', label: 'Tunisia', emoji: '🇹🇳' }, { value: 'TO', label: 'Tonga', emoji: '🇹🇴' }, { value: 'TR', label: 'Türkiye', emoji: '🇹🇷' }, { value: 'TT', label: 'Trinidad and Tobago', emoji: '🇹🇹' }, { value: 'TV', label: 'Tuvalu', emoji: '🇹🇻' }, { value: 'TW', label: 'Taiwan', emoji: '🇹🇼' }, { value: 'TZ', label: 'Tanzania', emoji: '🇹🇿' }, { value: 'UA', label: 'Ukraine', emoji: '🇺🇦' }, { value: 'UG', label: 'Uganda', emoji: '🇺🇬' }, { value: 'US', label: 'United States', emoji: '🇺🇸' }, { value: 'UY', label: 'Uruguay', emoji: '🇺🇾' }, { value: 'UZ', label: 'Uzbekistan', emoji: '🇺🇿' }, { value: 'VA', label: 'Vatican City', emoji: '🇻🇦' }, { value: 'VC', label: 'Saint Vincent and the Grenadines', emoji: '🇻🇨' }, { value: 'VE', label: 'Venezuela', emoji: '🇻🇪' }, { value: 'VG', label: 'British Virgin Islands', emoji: '🇻🇬' }, { value: 'VI', label: 'U.S. Virgin Islands', emoji: '🇻🇮' }, { value: 'VN', label: 'Vietnam', emoji: '🇻🇳' }, { value: 'VU', label: 'Vanuatu', emoji: '🇻🇺' }, { value: 'WF', label: 'Wallis and Futuna', emoji: '🇼🇫' }, { value: 'WS', label: 'Samoa', emoji: '🇼🇸' }, { value: 'YE', label: 'Yemen', emoji: '🇾🇪' }, { value: 'YT', label: 'Mayotte', emoji: '🇾🇹' }, { value: 'ZA', label: 'South Africa', emoji: '🇿🇦' }, { value: 'ZM', label: 'Zambia', emoji: '🇿🇲' }, { value: 'ZW', label: 'Zimbabwe', emoji: '🇿🇼' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte Country
                    Open
                    {#each $virtualizer.getVirtualItems() as virtualItem (virtualItem.key)} {@const item = collection().items[virtualItem.index]} {item.label} {/each}
                    ``` ### Custom Object Use the `itemToString` and `itemToValue` props to map custom objects to the required interface. **Example: custom-object** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const CustomObject = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { country: 'United States', code: 'US', flag: '🇺🇸' }, { country: 'Canada', code: 'CA', flag: '🇨🇦' }, { country: 'Australia', code: 'AU', flag: '🇦🇺' }, ], itemToString: (item) => item.country, itemToValue: (item) => item.code, filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {collection.items.map((item) => ( {item.flag} {item.country} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const CustomObject = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { country: 'United States', code: 'US', flag: '🇺🇸' }, { country: 'Canada', code: 'CA', flag: '🇨🇦' }, { country: 'Australia', code: 'AU', flag: '🇦🇺' }, ], itemToString: (item) => item.country, itemToValue: (item) => item.code, filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    Clear Open
                    {(item) => ( {item.flag} {item.country} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Country
                    Clear Open
                    {#each collection().items as item (item.code)} {item.flag} {item.country} {/each}
                    ``` ### Limit Results Use the `limit` property on `useListCollection` to limit the number of rendered items in the DOM. **Example: limit-results** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' const cities = [ { label: 'New York', value: 'new-york' }, { label: 'Los Angeles', value: 'los-angeles' }, { label: 'Chicago', value: 'chicago' }, { label: 'Houston', value: 'houston' }, { label: 'Phoenix', value: 'phoenix' }, { label: 'Philadelphia', value: 'philadelphia' }, { label: 'San Antonio', value: 'san-antonio' }, { label: 'San Diego', value: 'san-diego' }, { label: 'Dallas', value: 'dallas' }, { label: 'San Jose', value: 'san-jose' }, { label: 'Austin', value: 'austin' }, { label: 'Jacksonville', value: 'jacksonville' }, { label: 'Fort Worth', value: 'fort-worth' }, { label: 'Columbus', value: 'columbus' }, { label: 'Charlotte', value: 'charlotte' }, { label: 'San Francisco', value: 'san-francisco' }, { label: 'Indianapolis', value: 'indianapolis' }, { label: 'Seattle', value: 'seattle' }, { label: 'Denver', value: 'denver' }, { label: 'Boston', value: 'boston' }, ] export const LimitResults = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: cities, limit: 5, filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( City
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' const cities = [ { label: 'New York', value: 'new-york' }, { label: 'Los Angeles', value: 'los-angeles' }, { label: 'Chicago', value: 'chicago' }, { label: 'Houston', value: 'houston' }, { label: 'Phoenix', value: 'phoenix' }, { label: 'Philadelphia', value: 'philadelphia' }, { label: 'San Antonio', value: 'san-antonio' }, { label: 'San Diego', value: 'san-diego' }, { label: 'Dallas', value: 'dallas' }, { label: 'San Jose', value: 'san-jose' }, { label: 'Austin', value: 'austin' }, { label: 'Jacksonville', value: 'jacksonville' }, { label: 'Fort Worth', value: 'fort-worth' }, { label: 'Columbus', value: 'columbus' }, { label: 'Charlotte', value: 'charlotte' }, { label: 'San Francisco', value: 'san-francisco' }, { label: 'Indianapolis', value: 'indianapolis' }, { label: 'Seattle', value: 'seattle' }, { label: 'Denver', value: 'denver' }, { label: 'Boston', value: 'boston' }, ] export const LimitResults = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: cities, limit: 5, filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( City
                    Open
                    {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte City
                    Open
                    {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ## Guides ### Router Links Customize the `navigate` prop on `Combobox.Root` to integrate with your router. Using Tanstack Router: ```tsx import { Combobox } from '@ark-ui//combobox' import { useNavigate } from '@tanstack/react-router' function Demo() { const navigate = useNavigate() return ( { navigate({ to: e.node.href }) }} > {/* ... */} ) } ``` ### Custom Objects By default, the combobox collection expects an array of objects with `label` and `value` properties. In some cases, you may need to deal with custom objects. Use the `itemToString` and `itemToValue` props to map the custom object to the required interface. ```tsx const items = [ { country: 'United States', code: 'US', flag: '🇺🇸' }, { country: 'Canada', code: 'CA', flag: '🇨🇦' }, { country: 'Australia', code: 'AU', flag: '🇦🇺' }, // ... ] const { collection } = useListCollection({ initialItems: items, itemToString: (item) => item.country, itemToValue: (item) => item.code, }) ``` ### Type Safety The `Combobox.RootComponent` type enables you to create typed wrapper components that maintain full type safety for collection items. ```tsx const Combobox: ArkCombobox.RootComponent = (props) => { return {/* ... */} } ``` Use the wrapper with full type inference on `onValueChange` and other callbacks: ```tsx const App = () => { const { collection } = useListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, ], }) return ( { // e.items is typed as Array<{ label: string, value: string }> console.log(e.items) }} > {/* ... */} ) } ``` ### Large Datasets The recommended way of managing large lists is to use the `limit` property on the `useListCollection` hook. This will limit the number of rendered items in the DOM to improve performance. ```tsx {3} const { collection } = useListCollection({ initialItems: items, limit: 10, }) ``` ### Available Size The following css variables are exposed to the `Combobox.Positioner` which you can use to style the `Combobox.Content` ```css /* width of the combobox control */ --reference-width: ; /* width of the available viewport */ --available-width: ; /* height of the available viewport */ --available-height: ; ``` For example, if you want to make sure the maximum height doesn't exceed the available height, you can use the following: ```css [data-scope='combobox'][data-part='content'] { max-height: calc(var(--available-height) - 100px); } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input | | `alwaysSubmitOnEnter` | `boolean` | No | Whether to always submit on Enter key press, even if popup is open. Useful for single-field autocomplete forms where Enter should submit the form. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the input on mount | | `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. | | `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. | | `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. | | `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. | | `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. | | `disabled` | `boolean` | No | Whether the combobox is disabled | | `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer | | `form` | `string` | No | The associate form of the combobox. | | `highlightedValue` | `string` | No | The controlled highlighted value of the combobox | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string control: string input: string content: string trigger: string clearTrigger: string item: (id: string, index?: number | undefined) => string positioner: string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the combobox. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inputBehavior` | `'none' | 'autohighlight' | 'autocomplete'` | No | Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated | | `inputValue` | `string` | No | The controlled value of the combobox's input | | `invalid` | `boolean` | No | Whether the combobox is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items | | `multiple` | `boolean` | No | Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. | | `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when an item is highlighted using the pointer or keyboard navigation. | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Function called when the input's value changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when a new item is selected | | `open` | `boolean` | No | The controlled open state of the combobox | | `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes | | `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input | | `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press | | `placeholder` | `string` | No | The placeholder text of the combobox's input | | `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it | | `required` | `boolean` | No | Whether the combobox is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionBehavior` | `'clear' | 'replace' | 'preserve'` | No | The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the combobox's selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested comboboxs | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-autofocus]` | | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-group | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-value]` | The value of the item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | label | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | list | | `[data-empty]` | Present when the content is empty | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseComboboxReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `focusable` | `boolean` | No | Whether the trigger is focusable | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | | `[data-focusable]` | | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input | | `alwaysSubmitOnEnter` | `boolean` | No | Whether to always submit on Enter key press, even if popup is open. Useful for single-field autocomplete forms where Enter should submit the form. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the input on mount | | `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. | | `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. | | `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. | | `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. | | `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. | | `disabled` | `boolean` | No | Whether the combobox is disabled | | `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer | | `form` | `string` | No | The associate form of the combobox. | | `highlightedValue` | `string` | No | The controlled highlighted value of the combobox | | `ids` | `Partial<{ root: string label: string control: string input: string content: string trigger: string clearTrigger: string item: (id: string, index?: number | undefined) => string positioner: string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the combobox. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inputBehavior` | `'none' | 'autohighlight' | 'autocomplete'` | No | Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated | | `inputValue` | `string` | No | The controlled value of the combobox's input | | `invalid` | `boolean` | No | Whether the combobox is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items | | `multiple` | `boolean` | No | Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. | | `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when an item is highlighted using the pointer or keyboard navigation. | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Function called when the input's value changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when a new item is selected | | `open` | `boolean` | No | The controlled open state of the combobox | | `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes | | `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input | | `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press | | `placeholder` | `string` | No | The placeholder text of the combobox's input | | `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it | | `required` | `boolean` | No | Whether the combobox is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionBehavior` | `'replace' | 'clear' | 'preserve'` | No | The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the combobox's selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested comboboxs | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-autofocus]` | | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-group | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-value]` | The value of the item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | label | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | list | | `[data-empty]` | Present when the content is empty | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseComboboxReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `focusable` | `boolean` | No | Whether the trigger is focusable | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | | `[data-focusable]` | | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input | | `alwaysSubmitOnEnter` | `boolean` | No | Whether to allow bypassing the default two-step behavior (Enter to close combobox, then Enter to submit form) and instead submit the form immediately on Enter press. This is useful for single-field autocomplete forms where Enter should submit the form directly. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the input on mount | | `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. | | `collection` | `ListCollection` | No | The collection of items | | `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. | | `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. | | `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. | | `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. | | `disabled` | `boolean` | No | Whether the combobox is disabled | | `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer | | `form` | `string` | No | The associate form of the combobox. | | `highlightedValue` | `string` | No | The controlled highlighted value of the combobox | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string control: string input: string content: string trigger: string clearTrigger: string item(id: string, index?: number | undefined): string positioner: string itemGroup(id: string | number): string itemGroupLabel(id: string | number): string }>` | No | The ids of the elements in the combobox. Useful for composition. | | `inputBehavior` | `'none' | 'autohighlight' | 'autocomplete'` | No | Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated | | `inputValue` | `string` | No | The controlled value of the combobox's input | | `invalid` | `boolean` | No | Whether the combobox is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items | | `modelValue` | `string[]` | No | The v-model value of the combobox | | `multiple` | `boolean` | No | Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. | | `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item | | `open` | `boolean` | No | The controlled open state of the combobox | | `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes | | `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input | | `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press | | `placeholder` | `string` | No | The placeholder text of the combobox's input | | `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu | | `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it | | `required` | `boolean` | No | Whether the combobox is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionBehavior` | `'clear' | 'replace' | 'preserve'` | No | The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested comboboxs | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-autofocus]` | | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-group | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-value]` | The value of the item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | label | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | list | | `[data-empty]` | Present when the content is empty | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ComboboxApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `focusable` | `boolean` | No | Whether the trigger is focusable | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | | `[data-focusable]` | | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `MaybeFunction>` | Yes | The collection of items | | `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input | | `alwaysSubmitOnEnter` | `boolean` | No | Whether to always submit on Enter key press, even if popup is open. Useful for single-field autocomplete forms where Enter should submit the form. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the input on mount | | `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. | | `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. | | `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. | | `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. | | `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. | | `disabled` | `boolean` | No | Whether the combobox is disabled | | `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer | | `form` | `string` | No | The associate form of the combobox. | | `highlightedValue` | `string` | No | The controlled highlighted value of the combobox | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string control: string input: string content: string trigger: string clearTrigger: string item: (id: string, index?: number | undefined) => string positioner: string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the combobox. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inputBehavior` | `'none' | 'autocomplete' | 'autohighlight'` | No | Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated | | `inputValue` | `string` | No | The controlled value of the combobox's input | | `invalid` | `boolean` | No | Whether the combobox is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items | | `multiple` | `boolean` | No | Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. | | `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when an item is highlighted using the pointer or keyboard navigation. | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Function called when the input's value changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when a new item is selected | | `open` | `boolean` | No | The controlled open state of the combobox | | `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes | | `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input | | `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press | | `placeholder` | `string` | No | The placeholder text of the combobox's input | | `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the combobox is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionBehavior` | `'replace' | 'clear' | 'preserve'` | No | The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the combobox's selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested comboboxs | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseComboboxContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-autofocus]` | | | `[data-state]` | "open" | "closed" | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseComboboxItemContext]>` | Yes | | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | | `ref` | `Element` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-group | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `{}` | No | | | `persistFocus` | `boolean` | No | | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-value]` | The value of the item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | label | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | list | | `[data-empty]` | Present when the content is empty | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseComboboxReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `ref` | `Element` | No | | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | | `[data-focusable]` | | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focused` | `boolean` | Whether the combobox is focused | | `open` | `boolean` | Whether the combobox is open | | `inputValue` | `string` | The value of the combobox input | | `highlightedValue` | `string` | The value of the highlighted item | | `highlightedItem` | `V` | The highlighted item | | `setHighlightValue` | `(value: string) => void` | The value of the combobox input | | `clearHighlightValue` | `VoidFunction` | Function to clear the highlighted value | | `syncSelectedItems` | `VoidFunction` | Function to sync the selected items with the value. Useful when `value` is updated from async sources. | | `selectedItems` | `V[]` | The selected items | | `hasSelectedItems` | `boolean` | Whether there's a selected item | | `value` | `string[]` | The selected item keys | | `valueAsString` | `string` | The string representation of the selected items | | `selectValue` | `(value: string) => void` | Function to select a value | | `setValue` | `(value: string[]) => void` | Function to set the value of the combobox | | `clearValue` | `(value?: string) => void` | Function to clear the value of the combobox | | `focus` | `VoidFunction` | Function to focus on the combobox input | | `setInputValue` | `(value: string, reason?: InputValueChangeReason) => void` | Function to set the input value of the combobox | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a combobox item | | `setOpen` | `(open: boolean, reason?: OpenChangeReason) => void` | Function to open or close the combobox | | `collection` | `ListCollection` | Function to toggle the combobox | | `reposition` | `(options?: Partial) => void` | Function to set the positioning options | | `multiple` | `boolean` | Whether the combobox allows multiple selections | | `disabled` | `boolean` | Whether the combobox is disabled | ## Accessibility Complies with the [Combobox WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/). ### Keyboard Support **`ArrowDown`** Description: When the combobox is closed, opens the listbox and highlights to the first option. When the combobox is open, moves focus to the next option. **`ArrowUp`** Description: When the combobox is closed, opens the listbox and highlights to the last option. When the combobox is open, moves focus to the previous option. **`Home`** Description: When the combobox is open, moves focus to the first option. **`End`** Description: When the combobox is open, moves focus to the last option. **`Escape`** Description: Closes the listbox. **`Enter`** Description: Selects the highlighted option and closes the combobox. **`Esc`** Description: Closes the combobox --- # Combobox (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const Basic = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }, { label: 'Orange', value: 'orange' }, { label: 'Mango', value: 'mango' }, { label: 'Pineapple', value: 'pineapple' }, { label: 'Strawberry', value: 'strawberry' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Favorite Fruit
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const Basic = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }, { label: 'Orange', value: 'orange' }, { label: 'Mango', value: 'mango' }, { label: 'Pineapple', value: 'pineapple' }, { label: 'Strawberry', value: 'strawberry' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Favorite Fruit
                    {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Fruit
                    Clear Open
                    No results found {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Auto Highlight Automatically highlight the first matching item as the user types by setting `inputBehavior="autohighlight"`. **Example: auto-highlight** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const AutoHighlight = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Engineering', value: 'engineering' }, { label: 'Marketing', value: 'marketing' }, { label: 'Sales', value: 'sales' }, { label: 'Finance', value: 'finance' }, { label: 'Human Resources', value: 'hr' }, { label: 'Operations', value: 'operations' }, { label: 'Product', value: 'product' }, { label: 'Customer Success', value: 'customer-success' }, { label: 'Legal', value: 'legal' }, { label: 'Information Technology', value: 'information-technology' }, { label: 'Design', value: 'design' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Department
                    No results found {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const AutoHighlight = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Engineering', value: 'engineering' }, { label: 'Marketing', value: 'marketing' }, { label: 'Sales', value: 'sales' }, { label: 'Finance', value: 'finance' }, { label: 'Human Resources', value: 'hr' }, { label: 'Operations', value: 'operations' }, { label: 'Product', value: 'product' }, { label: 'Customer Success', value: 'customer-success' }, { label: 'Legal', value: 'legal' }, { label: 'Information Technology', value: 'information-technology' }, { label: 'Design', value: 'design' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Department
                    Clear Open
                    No results found {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Department
                    Clear Open
                    No results found {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Inline Autocomplete Complete the input value with the first matching item by setting `inputBehavior="autocomplete"`. Use with `startsWith` filter for best results. **Example: inline-autocomplete** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const InlineAutocomplete = () => { const { startsWith } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Whale', value: 'whale' }, { label: 'Dolphin', value: 'dolphin' }, { label: 'Shark', value: 'shark' }, { label: 'Octopus', value: 'octopus' }, { label: 'Jellyfish', value: 'jellyfish' }, { label: 'Seahorse', value: 'seahorse' }, ], filter: startsWith, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Sea Creature
                    No results found {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const InlineAutocomplete = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Whale', value: 'whale' }, { label: 'Dolphin', value: 'dolphin' }, { label: 'Shark', value: 'shark' }, { label: 'Octopus', value: 'octopus' }, { label: 'Jellyfish', value: 'jellyfish' }, { label: 'Seahorse', value: 'seahorse' }, ], filter: filterFn().startsWith, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Sea Creature
                    Clear Open
                    No results found {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Sea Creature
                    Clear Open
                    No results found {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Grouping To group related combobox items, use the `groupBy` prop on the collection and `collection.group()` to iterate the groups. **Example: grouping** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const Grouping = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: contains, groupBy: (item) => item.continent, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {collection.group().map(([continent, group]) => ( {continent} {group.map((item) => ( {item.label} ))} ))}
                    ) } const initialItems = [ { label: 'Canada', value: 'ca', continent: 'North America' }, { label: 'United States', value: 'us', continent: 'North America' }, { label: 'Mexico', value: 'mx', continent: 'North America' }, { label: 'United Kingdom', value: 'uk', continent: 'Europe' }, { label: 'Germany', value: 'de', continent: 'Europe' }, { label: 'France', value: 'fr', continent: 'Europe' }, { label: 'Japan', value: 'jp', continent: 'Asia' }, { label: 'South Korea', value: 'kr', continent: 'Asia' }, { label: 'China', value: 'cn', continent: 'Asia' }, ] ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' const initialItems = [ { label: 'Canada', value: 'ca', continent: 'North America' }, { label: 'United States', value: 'us', continent: 'North America' }, { label: 'Mexico', value: 'mx', continent: 'North America' }, { label: 'United Kingdom', value: 'uk', continent: 'Europe' }, { label: 'Germany', value: 'de', continent: 'Europe' }, { label: 'France', value: 'fr', continent: 'Europe' }, { label: 'Japan', value: 'jp', continent: 'Asia' }, { label: 'South Korea', value: 'kr', continent: 'Asia' }, { label: 'China', value: 'cn', continent: 'Asia' }, ] export const Grouping = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: filterFn().contains, groupBy: (item) => item.continent, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {([continent, group]) => ( {continent} {(item) => ( {item.label} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Country
                    Clear Open
                    {#each collection().group() as [continent, group]} {continent} {#each group as item} {item.label} {/each} {/each}
                    ``` ### Field The `Field` component helps manage form-related state and accessibility attributes of a combobox. It includes handling ARIA labels, helper text, and error text to ensure proper accessibility. **Example: with-field** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { Field } from '@ark-ui/react/field' import { useFilter } from '@ark-ui/react/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' import field from 'styles/field.module.css' export const WithField = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Department
                    {collection.items.map((item) => ( {item.label} ))}
                    Select your primary department Department is required
                    ) } const initialItems = [ { label: 'Engineering', value: 'engineering' }, { label: 'Design', value: 'design' }, { label: 'Marketing', value: 'marketing' }, { label: 'Sales', value: 'sales' }, { label: 'Human Resources', value: 'hr' }, { label: 'Finance', value: 'finance' }, ] ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { Field } from '@ark-ui/solid/field' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import styles from 'styles/combobox.module.css' import field from 'styles/field.module.css' const initialItems = [ { label: 'Engineering', value: 'engineering' }, { label: 'Design', value: 'design' }, { label: 'Marketing', value: 'marketing' }, { label: 'Sales', value: 'sales' }, { label: 'Human Resources', value: 'hr' }, { label: 'Finance', value: 'finance' }, ] export const WithField = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Department
                    Clear Open
                    {(item) => ( {item.label} )}
                    Select your primary department Department is required
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Department
                    Clear Open
                    {#each collection().items as item (item.value)} {item.label} {/each}
                    Select your primary department Department is required
                    ``` ### Context Use the `Combobox.Context` component to access the combobox state and display information like the selected value. **Example: context** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const Context = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Small', value: 'sm' }, { label: 'Medium', value: 'md' }, { label: 'Large', value: 'lg' }, { label: 'Extra Large', value: 'xl' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( {(combobox) =>

                    Selected: {combobox.valueAsString || 'None'}

                    }
                    Size
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const Context = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Small', value: 'sm' }, { label: 'Medium', value: 'md' }, { label: 'Large', value: 'lg' }, { label: 'Extra Large', value: 'xl' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( {(context) =>

                    Selected: {context().valueAsString || 'None'}

                    }
                    Size
                    {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(combobox)}

                    Selected: {combobox().valueAsString || 'None'}

                    {/snippet}
                    Size
                    Clear Open
                    {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Root Provider An alternative way to control the combobox is to use the `RootProvider` component and the `useCombobox` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { Combobox, useCombobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/combobox.module.css' const initialItems = [ { label: 'Designer', value: 'designer' }, { label: 'Developer', value: 'developer' }, { label: 'Product Manager', value: 'pm' }, { label: 'Data Scientist', value: 'data-scientist' }, { label: 'DevOps Engineer', value: 'devops' }, { label: 'Marketing Lead', value: 'marketing' }, ] export const RootProvider = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: contains, }) const combobox = useCombobox({ collection, onInputValueChange(details) { filter(details.inputValue) }, }) return (
                    Job Title
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useCombobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/combobox.module.css' const initialItems = [ { label: 'Designer', value: 'designer' }, { label: 'Developer', value: 'developer' }, { label: 'Product Manager', value: 'pm' }, { label: 'Data Scientist', value: 'data-scientist' }, { label: 'DevOps Engineer', value: 'devops' }, { label: 'Marketing Lead', value: 'marketing' }, ] export const RootProvider = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: filterFn().contains, }) const combobox = useCombobox({ get collection() { return collection() }, onInputValueChange(details) { filter(details.inputValue) }, }) return (
                    Job Title
                    {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Job Title
                    Clear Open
                    {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Links Use the `asChild` prop to render the combobox items as links. **Example: links** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const Links = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Developer Resources
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } const initialItems = [ { label: 'GitHub', href: 'https://github.com', value: 'github' }, { label: 'Stack Overflow', href: 'https://stackoverflow.com', value: 'stackoverflow' }, { label: 'MDN Web Docs', href: 'https://developer.mozilla.org', value: 'mdn' }, { label: 'npm', href: 'https://www.npmjs.com', value: 'npm' }, { label: 'TypeScript', href: 'https://www.typescriptlang.org', value: 'typescript' }, { label: 'React', href: 'https://react.dev', value: 'react' }, ] ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' const initialItems = [ { label: 'GitHub', href: 'https://github.com', value: 'github' }, { label: 'Stack Overflow', href: 'https://stackoverflow.com', value: 'stackoverflow' }, { label: 'MDN Web Docs', href: 'https://developer.mozilla.org', value: 'mdn' }, { label: 'npm', href: 'https://www.npmjs.com', value: 'npm' }, { label: 'TypeScript', href: 'https://www.typescriptlang.org', value: 'typescript' }, { label: 'React', href: 'https://react.dev', value: 'react' }, ] export const Links = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Developer Resources
                    {(item) => ( }> {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Developer Resources
                    Open
                    {#each collection().items as item (item.value)} {#snippet asChild(props)}
                    {item.label} {/snippet} {/each} ``` ### Rehydrate When a combobox has a `defaultValue` or `value` but the `collection` is not loaded yet, you can rehydrate the value to populate the input. **Example: rehydrate-value** #### React ```tsx import { Combobox, useCombobox, useComboboxContext, useListCollection } from '@ark-ui/react/combobox' import { Portal } from '@ark-ui/react/portal' import { CheckIcon } from 'lucide-react' import { useRef, useState } from 'react' import { useAsync } from 'react-use' import styles from 'styles/combobox.module.css' function ComboboxRehydrateValue() { const combobox = useComboboxContext() const hydrated = useRef(false) if (combobox.value.length && combobox.collection.size && !hydrated.current) { combobox.syncSelectedItems() hydrated.current = true } return null } export const RehydrateValue = () => { const [inputValue, setInputValue] = useState('') const { collection, set } = useListCollection({ initialItems: [], itemToString: (item) => item.name, itemToValue: (item) => item.name, }) const combobox = useCombobox({ collection, defaultValue: ['C-3PO'], placeholder: 'Example: Dexter', inputValue, onInputValueChange: (e) => setInputValue(e.inputValue), }) const state = useAsync(async () => { const response = await fetch(`https://swapi.py4e.com/api/people/?search=${inputValue}`) const data = await response.json() set(data.results) }, [inputValue, set]) return ( Search Star Wars Characters {state.loading ? ( Loading... ) : state.error ? ( {state.error.message} ) : ( collection.items.map((item) => ( {item.name} - {item.height}cm / {item.mass}kg )) )} ) } interface Character { name: string height: string mass: string created: string edited: string url: string } ``` #### Solid ```tsx import { Combobox, useCombobox, useComboboxContext, useListCollection } from '@ark-ui/solid/combobox' import { For, createEffect, createRenderEffect, createSignal, on } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' import { useAsync } from './use-async' function ComboboxRehydrateValue() { const combobox = useComboboxContext() let hydrated = false createRenderEffect(() => { if (combobox().value.length && combobox().collection.size && !hydrated) { combobox().syncSelectedItems() hydrated = true } }) return null } export const RehydrateValue = () => { const [inputValue, setInputValue] = createSignal('') const { collection, set } = useListCollection({ initialItems: [], itemToString: (item) => item.name, itemToValue: (item) => item.name, }) const combobox = useCombobox(() => ({ collection: collection(), defaultValue: ['C-3PO'], placeholder: 'Example: Dexter', inputValue: inputValue(), onInputValueChange: (e) => setInputValue(e.inputValue), })) const state = useAsync(async (signal) => { const response = await fetch(`https://swapi.py4e.com/api/people/?search=${inputValue()}`, { signal }) const data = await response.json() set(data.results) }) createEffect(on(inputValue, () => state.load())) return ( Search Star Wars Characters {state.loading() ? ( Loading... ) : state.error() ? ( {state.error()?.message} ) : ( {(item) => ( {item.name} - {item.height}cm / {item.mass}kg )} )} ) } interface Character { name: string height: string mass: string created: string edited: string url: string } ``` #### Vue ```vue ``` #### Svelte ```svelte Search Star Wars Characters {#if _state.loading()} Loading... {:else if _state.error()} {_state.error()?.message} {:else} {#each collection().items as item (item.name)} {item.name} - {item.height}cm / {item.mass}kg {/each} {/if} ``` ### Highlight Text Highlight the matching search text in combobox items based on the user's input. **Example: highlight-matching-text** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { Highlight } from '@ark-ui/react/highlight' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const HighlightMatchingText = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'John Smith', value: 'john-smith' }, { label: 'Jane Doe', value: 'jane-doe' }, { label: 'Bob Johnson', value: 'bob-johnson' }, { label: 'Alice Williams', value: 'alice-williams' }, { label: 'Charlie Brown', value: 'charlie-brown' }, { label: 'Diana Ross', value: 'diana-ross' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Assignee
                    {collection.items.map((item) => ( {(context) => } ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { Highlight } from '@ark-ui/solid/highlight' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const HighlightMatchingText = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'John Smith', value: 'john-smith' }, { label: 'Jane Doe', value: 'jane-doe' }, { label: 'Bob Johnson', value: 'bob-johnson' }, { label: 'Alice Williams', value: 'alice-williams' }, { label: 'Charlie Brown', value: 'charlie-brown' }, { label: 'Diana Ross', value: 'diana-ross' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Assignee
                    Clear Open
                    {(item) => ( {(context) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Assignee
                    Clear Open
                    {#each collection().items as item (item.value)} {#snippet render(context)} {/snippet} {/each}
                    ``` ### Dynamic Generate combobox items dynamically based on user input. This is useful for creating suggestions or autocomplete functionality. **Example: dynamic** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' const suggestList = ['gmail.com', 'yahoo.com', 'ark-ui.com'] export const Dynamic = () => { const { collection, set } = useListCollection({ initialItems: [], }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { if (details.reason === 'input-change') { const items = suggestList.map((item) => `${details.inputValue}@${item}`) set(items) } } return ( Email
                    {collection.items.map((item) => ( {item} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' const suggestList = ['gmail.com', 'yahoo.com', 'ark-ui.com'] export const Dynamic = () => { const { collection, set } = useListCollection({ initialItems: [], }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { if (details.reason === 'input-change') { const items = suggestList.map((item) => `${details.inputValue}@${item}`) set(items) } } return ( Email
                    Open
                    {(item) => ( {item} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Email
                    Open
                    {#each collection().items as item (item)} {item} {/each}
                    ``` ### 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. **Example: creatable** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import { flushSync } from 'react-dom' import styles from 'styles/combobox.module.css' interface Item { label: string value: string __new__?: boolean } const NEW_OPTION_VALUE = '[[new]]' const createNewOption = (value: string): Item => ({ label: value, value: NEW_OPTION_VALUE }) const isNewOptionValue = (value: string) => value === NEW_OPTION_VALUE const replaceNewOptionValue = (values: string[], value: string) => values.map((v) => (v === NEW_OPTION_VALUE ? value : v)) const getNewOptionData = (inputValue: string): Item => ({ label: inputValue, value: inputValue, __new__: true }) export const Creatable = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter, upsert, update, remove } = useListCollection({ initialItems: [ { label: 'Bug', value: 'bug' }, { label: 'Feature', value: 'feature' }, { label: 'Enhancement', value: 'enhancement' }, { label: 'Documentation', value: 'docs' }, ], filter: contains, }) const isValidNewOption = (inputValue: string) => { const exactOptionMatch = collection.filter((item) => item.toLowerCase() === inputValue.toLowerCase()).size > 0 return !exactOptionMatch && inputValue.trim().length > 0 } const [selectedValue, setSelectedValue] = useState([]) const [inputValue, setInputValue] = useState('') const handleInputChange = ({ inputValue, reason }: Combobox.InputValueChangeDetails) => { if (reason === 'input-change' || reason === 'item-select') { flushSync(() => { if (isValidNewOption(inputValue)) { upsert(NEW_OPTION_VALUE, createNewOption(inputValue)) } else if (inputValue.trim().length === 0) { remove(NEW_OPTION_VALUE) } }) filter(inputValue) } setInputValue(inputValue) } const handleOpenChange = ({ reason }: Combobox.OpenChangeDetails) => { if (reason === 'trigger-click') { filter('') } } const handleValueChange = ({ value }: Combobox.ValueChangeDetails) => { setSelectedValue(replaceNewOptionValue(value, inputValue)) if (value.includes(NEW_OPTION_VALUE)) { console.log('New Option Created', inputValue) update(NEW_OPTION_VALUE, getNewOptionData(inputValue)) } } return ( Label
                    {collection.items.map((item) => ( {isNewOptionValue(item.value) ? ( + Create "{item.label}" ) : ( {item.label} {item.__new__ ? '(new)' : ''} )} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { createSignal, For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' interface Item { label: string value: string __new__?: boolean } const NEW_OPTION_VALUE = '[[new]]' const createNewOption = (value: string): Item => ({ label: value, value: NEW_OPTION_VALUE }) const isNewOptionValue = (value: string) => value === NEW_OPTION_VALUE const replaceNewOptionValue = (values: string[], value: string) => values.map((v) => (v === NEW_OPTION_VALUE ? value : v)) const getNewOptionData = (inputValue: string): Item => ({ label: inputValue, value: inputValue, __new__: true }) export const Creatable = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter, upsert, update, remove } = useListCollection({ initialItems: [ { label: 'Bug', value: 'bug' }, { label: 'Feature', value: 'feature' }, { label: 'Enhancement', value: 'enhancement' }, { label: 'Documentation', value: 'docs' }, ], filter: filterFn().contains, }) const isValidNewOption = (inputValue: string) => { const exactOptionMatch = collection().items.filter((item) => item.label.toLowerCase() === inputValue.toLowerCase()).length > 0 return !exactOptionMatch && inputValue.trim().length > 0 } const [selectedValue, setSelectedValue] = createSignal([]) const [inputValue, setInputValue] = createSignal('') const handleInputChange = ({ inputValue: newInputValue, reason }: Combobox.InputValueChangeDetails) => { if (reason === 'input-change' || reason === 'item-select') { if (isValidNewOption(newInputValue)) { upsert(NEW_OPTION_VALUE, createNewOption(newInputValue)) } else if (newInputValue.trim().length === 0) { remove(NEW_OPTION_VALUE) } filter(newInputValue) } setInputValue(newInputValue) } const handleOpenChange = ({ reason }: Combobox.OpenChangeDetails) => { if (reason === 'trigger-click') { filter('') } } const handleValueChange = ({ value }: Combobox.ValueChangeDetails) => { setSelectedValue(replaceNewOptionValue(value, inputValue())) if (value.includes(NEW_OPTION_VALUE)) { console.log('New Option Created', inputValue()) update(NEW_OPTION_VALUE, getNewOptionData(inputValue())) } } return ( Label
                    Clear Open
                    {(item) => ( {isNewOptionValue(item.value) ? ( + Create "{item.label}" ) : ( {item.label} {item.__new__ ? '(new)' : ''} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    Clear Open
                    {#each collection().items as item (item.value)} {#if isNewOptionValue(item.value)} + Create "{item.label}" {:else} {item.label} {item.__new__ ? '(new)' : ''} {/if} {/each}
                    ``` ### Multiple Selection Enable multiple selection by setting the `multiple` prop. Selected items can be displayed as tags above the input. **Example: multiple** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import { useRef } from 'react' import styles from 'styles/combobox.module.css' export const Multiple = () => { const { contains } = useFilter({ sensitivity: 'base' }) const selectedValue = useRef([]) const { collection, filter, remove } = useListCollection({ initialItems: [ { label: 'JavaScript', value: 'js' }, { label: 'TypeScript', value: 'ts' }, { label: 'Python', value: 'python' }, { label: 'Go', value: 'go' }, { label: 'Rust', value: 'rust' }, { label: 'Java', value: 'java' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } const handleValueChange = (details: Combobox.ValueChangeDetails) => { selectedValue.current = details.value remove(...details.value) } return ( Skills {(combobox) => (
                    {combobox.selectedItems.length === 0 && None selected} {combobox.selectedItems.map((item: any) => ( {item.label} ))}
                    )}
                    No skills found {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const Multiple = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter, remove } = useListCollection({ initialItems: [ { label: 'JavaScript', value: 'js' }, { label: 'TypeScript', value: 'ts' }, { label: 'Python', value: 'python' }, { label: 'Go', value: 'go' }, { label: 'Rust', value: 'rust' }, { label: 'Java', value: 'java' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } const handleValueChange = (details: Combobox.ValueChangeDetails) => { remove(...details.value) } return ( Skills {(context) => (
                    {context().selectedItems.length === 0 && None selected} {(item: any) => {item.label}}
                    )}
                    No skills found {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Skills
                    {#if selectedItems.length === 0} None selected {/if} {#each selectedItems as item (item.value)} {item.label} {/each}
                    Open
                    No skills found {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### 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. **Example: async-search** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { Combobox, createListCollection } from '@ark-ui/react/combobox' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, LoaderIcon, XIcon } from 'lucide-react' import { startTransition } from 'react' import styles from 'styles/combobox.module.css' interface Movie { id: string title: string year: number director: string genre: string } export const AsyncSearch = () => { const list = useAsyncList({ async load({ filterText, signal }) { if (!filterText) return { items: [] } await new Promise((resolve) => setTimeout(resolve, 300)) if (signal?.aborted) return { items: [] } const items = allMovies.filter( (movie) => movie.title.toLowerCase().includes(filterText.toLowerCase()) || movie.director.toLowerCase().includes(filterText.toLowerCase()) || movie.genre.toLowerCase().includes(filterText.toLowerCase()), ) return { items } }, }) const collection = createListCollection({ items: list.items, itemToString: (item) => item.title, itemToValue: (item) => item.id, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { if (details.reason === 'input-change') { startTransition(() => { list.setFilterText(details.inputValue) }) } } return ( Movie
                    {list.loading ? (
                    Searching...
                    ) : list.error ? (
                    {list.error.message}
                    ) : list.items.length === 0 ? (
                    {list.filterText ? 'No results found' : 'Start typing to search movies...'}
                    ) : ( collection.items.map((movie) => ( {movie.title} {movie.year} · {movie.director} )) )}
                    ) } const allMovies: Movie[] = [ { id: 'inception', title: 'Inception', year: 2010, director: 'Christopher Nolan', genre: 'Sci-Fi' }, { id: 'the-dark-knight', title: 'The Dark Knight', year: 2008, director: 'Christopher Nolan', genre: 'Action' }, { id: 'pulp-fiction', title: 'Pulp Fiction', year: 1994, director: 'Quentin Tarantino', genre: 'Crime' }, { id: 'the-godfather', title: 'The Godfather', year: 1972, director: 'Francis Ford Coppola', genre: 'Crime' }, { id: 'forrest-gump', title: 'Forrest Gump', year: 1994, director: 'Robert Zemeckis', genre: 'Drama' }, { id: 'the-matrix', title: 'The Matrix', year: 1999, director: 'The Wachowskis', genre: 'Sci-Fi' }, { id: 'interstellar', title: 'Interstellar', year: 2014, director: 'Christopher Nolan', genre: 'Sci-Fi' }, { id: 'parasite', title: 'Parasite', year: 2019, director: 'Bong Joon-ho', genre: 'Thriller' }, { id: 'the-shawshank-redemption', title: 'The Shawshank Redemption', year: 1994, director: 'Frank Darabont', genre: 'Drama', }, { id: 'fight-club', title: 'Fight Club', year: 1999, director: 'David Fincher', genre: 'Drama' }, { id: 'goodfellas', title: 'Goodfellas', year: 1990, director: 'Martin Scorsese', genre: 'Crime' }, { id: 'the-silence-of-the-lambs', title: 'The Silence of the Lambs', year: 1991, director: 'Jonathan Demme', genre: 'Thriller', }, ] ``` ### 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. **Example: virtualized** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { useVirtualizer } from '@tanstack/react-virtual' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import { useRef } from 'react' import { flushSync } from 'react-dom' import styles from 'styles/combobox.module.css' export const Virtualized = () => { const contentRef = useRef(null) const { startsWith } = useFilter({ sensitivity: 'base' }) const { collection, filter, reset } = useListCollection({ initialItems: countries, filter: startsWith, }) const virtualizer = useVirtualizer({ count: collection.size, getScrollElement: () => contentRef.current, estimateSize: () => 32, overscan: 10, }) const handleScrollToIndex: Combobox.RootProps['scrollToIndexFn'] = (details) => { flushSync(() => { virtualizer.scrollToIndex(details.index, { align: 'center', behavior: 'auto', }) }) } const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {virtualizer.getVirtualItems().map((virtualItem) => { const item = collection.items[virtualItem.index] return ( {item.emoji} {item.label} ) })}
                    ) } interface Country { value: string label: string emoji: string } const countries: Country[] = [ { value: 'AD', label: 'Andorra', emoji: '🇦🇩' }, { value: 'AE', label: 'United Arab Emirates', emoji: '🇦🇪' }, { value: 'AF', label: 'Afghanistan', emoji: '🇦🇫' }, { value: 'AG', label: 'Antigua and Barbuda', emoji: '🇦🇬' }, { value: 'AI', label: 'Anguilla', emoji: '🇦🇮' }, { value: 'AL', label: 'Albania', emoji: '🇦🇱' }, { value: 'AM', label: 'Armenia', emoji: '🇦🇲' }, { value: 'AO', label: 'Angola', emoji: '🇦🇴' }, { value: 'AQ', label: 'Antarctica', emoji: '🇦🇶' }, { value: 'AR', label: 'Argentina', emoji: '🇦🇷' }, { value: 'AS', label: 'American Samoa', emoji: '🇦🇸' }, { value: 'AT', label: 'Austria', emoji: '🇦🇹' }, { value: 'AU', label: 'Australia', emoji: '🇦🇺' }, { value: 'AW', label: 'Aruba', emoji: '🇦🇼' }, { value: 'AX', label: 'Åland Islands', emoji: '🇦🇽' }, { value: 'AZ', label: 'Azerbaijan', emoji: '🇦🇿' }, { value: 'BA', label: 'Bosnia and Herzegovina', emoji: '🇧🇦' }, { value: 'BB', label: 'Barbados', emoji: '🇧🇧' }, { value: 'BD', label: 'Bangladesh', emoji: '🇧🇩' }, { value: 'BE', label: 'Belgium', emoji: '🇧🇪' }, { value: 'BF', label: 'Burkina Faso', emoji: '🇧🇫' }, { value: 'BG', label: 'Bulgaria', emoji: '🇧🇬' }, { value: 'BH', label: 'Bahrain', emoji: '🇧🇭' }, { value: 'BI', label: 'Burundi', emoji: '🇧🇮' }, { value: 'BJ', label: 'Benin', emoji: '🇧🇯' }, { value: 'BL', label: 'Saint Barthélemy', emoji: '🇧🇱' }, { value: 'BM', label: 'Bermuda', emoji: '🇧🇲' }, { value: 'BN', label: 'Brunei', emoji: '🇧🇳' }, { value: 'BO', label: 'Bolivia', emoji: '🇧🇴' }, { value: 'BR', label: 'Brazil', emoji: '🇧🇷' }, { value: 'BS', label: 'Bahamas', emoji: '🇧🇸' }, { value: 'BT', label: 'Bhutan', emoji: '🇧🇹' }, { value: 'BW', label: 'Botswana', emoji: '🇧🇼' }, { value: 'BY', label: 'Belarus', emoji: '🇧🇾' }, { value: 'BZ', label: 'Belize', emoji: '🇧🇿' }, { value: 'CA', label: 'Canada', emoji: '🇨🇦' }, { value: 'CD', label: 'Congo', emoji: '🇨🇩' }, { value: 'CF', label: 'Central African Republic', emoji: '🇨🇫' }, { value: 'CH', label: 'Switzerland', emoji: '🇨🇭' }, { value: 'CI', label: "Côte d'Ivoire", emoji: '🇨🇮' }, { value: 'CK', label: 'Cook Islands', emoji: '🇨🇰' }, { value: 'CL', label: 'Chile', emoji: '🇨🇱' }, { value: 'CM', label: 'Cameroon', emoji: '🇨🇲' }, { value: 'CN', label: 'China', emoji: '🇨🇳' }, { value: 'CO', label: 'Colombia', emoji: '🇨🇴' }, { value: 'CR', label: 'Costa Rica', emoji: '🇨🇷' }, { value: 'CU', label: 'Cuba', emoji: '🇨🇺' }, { value: 'CV', label: 'Cabo Verde', emoji: '🇨🇻' }, { value: 'CY', label: 'Cyprus', emoji: '🇨🇾' }, { value: 'CZ', label: 'Czech Republic', emoji: '🇨🇿' }, { value: 'DE', label: 'Germany', emoji: '🇩🇪' }, { value: 'DJ', label: 'Djibouti', emoji: '🇩🇯' }, { value: 'DK', label: 'Denmark', emoji: '🇩🇰' }, { value: 'DM', label: 'Dominica', emoji: '🇩🇲' }, { value: 'DO', label: 'Dominican Republic', emoji: '🇩🇴' }, { value: 'DZ', label: 'Algeria', emoji: '🇩🇿' }, { value: 'EC', label: 'Ecuador', emoji: '🇪🇨' }, { value: 'EE', label: 'Estonia', emoji: '🇪🇪' }, { value: 'EG', label: 'Egypt', emoji: '🇪🇬' }, { value: 'ER', label: 'Eritrea', emoji: '🇪🇷' }, { value: 'ES', label: 'Spain', emoji: '🇪🇸' }, { value: 'ET', label: 'Ethiopia', emoji: '🇪🇹' }, { value: 'FI', label: 'Finland', emoji: '🇫🇮' }, { value: 'FJ', label: 'Fiji', emoji: '🇫🇯' }, { value: 'FK', label: 'Falkland Islands', emoji: '🇫🇰' }, { value: 'FM', label: 'Micronesia', emoji: '🇫🇲' }, { value: 'FO', label: 'Faroe Islands', emoji: '🇫🇴' }, { value: 'FR', label: 'France', emoji: '🇫🇷' }, { value: 'GA', label: 'Gabon', emoji: '🇬🇦' }, { value: 'GB', label: 'United Kingdom', emoji: '🇬🇧' }, { value: 'GD', label: 'Grenada', emoji: '🇬🇩' }, { value: 'GE', label: 'Georgia', emoji: '🇬🇪' }, { value: 'GH', label: 'Ghana', emoji: '🇬🇭' }, { value: 'GI', label: 'Gibraltar', emoji: '🇬🇮' }, { value: 'GL', label: 'Greenland', emoji: '🇬🇱' }, { value: 'GM', label: 'Gambia', emoji: '🇬🇲' }, { value: 'GN', label: 'Guinea', emoji: '🇬🇳' }, { value: 'GQ', label: 'Equatorial Guinea', emoji: '🇬🇶' }, { value: 'GR', label: 'Greece', emoji: '🇬🇷' }, { value: 'GT', label: 'Guatemala', emoji: '🇬🇹' }, { value: 'GU', label: 'Guam', emoji: '🇬🇺' }, { value: 'GW', label: 'Guinea-Bissau', emoji: '🇬🇼' }, { value: 'GY', label: 'Guyana', emoji: '🇬🇾' }, { value: 'HK', label: 'Hong Kong', emoji: '🇭🇰' }, { value: 'HN', label: 'Honduras', emoji: '🇭🇳' }, { value: 'HR', label: 'Croatia', emoji: '🇭🇷' }, { value: 'HT', label: 'Haiti', emoji: '🇭🇹' }, { value: 'HU', label: 'Hungary', emoji: '🇭🇺' }, { value: 'ID', label: 'Indonesia', emoji: '🇮🇩' }, { value: 'IE', label: 'Ireland', emoji: '🇮🇪' }, { value: 'IL', label: 'Israel', emoji: '🇮🇱' }, { value: 'IM', label: 'Isle of Man', emoji: '🇮🇲' }, { value: 'IN', label: 'India', emoji: '🇮🇳' }, { value: 'IQ', label: 'Iraq', emoji: '🇮🇶' }, { value: 'IR', label: 'Iran', emoji: '🇮🇷' }, { value: 'IS', label: 'Iceland', emoji: '🇮🇸' }, { value: 'IT', label: 'Italy', emoji: '🇮🇹' }, { value: 'JE', label: 'Jersey', emoji: '🇯🇪' }, { value: 'JM', label: 'Jamaica', emoji: '🇯🇲' }, { value: 'JO', label: 'Jordan', emoji: '🇯🇴' }, { value: 'JP', label: 'Japan', emoji: '🇯🇵' }, { value: 'KE', label: 'Kenya', emoji: '🇰🇪' }, { value: 'KG', label: 'Kyrgyzstan', emoji: '🇰🇬' }, { value: 'KH', label: 'Cambodia', emoji: '🇰🇭' }, { value: 'KI', label: 'Kiribati', emoji: '🇰🇮' }, { value: 'KM', label: 'Comoros', emoji: '🇰🇲' }, { value: 'KN', label: 'Saint Kitts and Nevis', emoji: '🇰🇳' }, { value: 'KP', label: 'North Korea', emoji: '🇰🇵' }, { value: 'KR', label: 'South Korea', emoji: '🇰🇷' }, { value: 'KW', label: 'Kuwait', emoji: '🇰🇼' }, { value: 'KY', label: 'Cayman Islands', emoji: '🇰🇾' }, { value: 'KZ', label: 'Kazakhstan', emoji: '🇰🇿' }, { value: 'LA', label: 'Laos', emoji: '🇱🇦' }, { value: 'LB', label: 'Lebanon', emoji: '🇱🇧' }, { value: 'LC', label: 'Saint Lucia', emoji: '🇱🇨' }, { value: 'LI', label: 'Liechtenstein', emoji: '🇱🇮' }, { value: 'LK', label: 'Sri Lanka', emoji: '🇱🇰' }, { value: 'LR', label: 'Liberia', emoji: '🇱🇷' }, { value: 'LS', label: 'Lesotho', emoji: '🇱🇸' }, { value: 'LT', label: 'Lithuania', emoji: '🇱🇹' }, { value: 'LU', label: 'Luxembourg', emoji: '🇱🇺' }, { value: 'LV', label: 'Latvia', emoji: '🇱🇻' }, { value: 'LY', label: 'Libya', emoji: '🇱🇾' }, { value: 'MA', label: 'Morocco', emoji: '🇲🇦' }, { value: 'MC', label: 'Monaco', emoji: '🇲🇨' }, { value: 'MD', label: 'Moldova', emoji: '🇲🇩' }, { value: 'ME', label: 'Montenegro', emoji: '🇲🇪' }, { value: 'MG', label: 'Madagascar', emoji: '🇲🇬' }, { value: 'MH', label: 'Marshall Islands', emoji: '🇲🇭' }, { value: 'MK', label: 'North Macedonia', emoji: '🇲🇰' }, { value: 'ML', label: 'Mali', emoji: '🇲🇱' }, { value: 'MM', label: 'Myanmar', emoji: '🇲🇲' }, { value: 'MN', label: 'Mongolia', emoji: '🇲🇳' }, { value: 'MO', label: 'Macao', emoji: '🇲🇴' }, { value: 'MR', label: 'Mauritania', emoji: '🇲🇷' }, { value: 'MS', label: 'Montserrat', emoji: '🇲🇸' }, { value: 'MT', label: 'Malta', emoji: '🇲🇹' }, { value: 'MU', label: 'Mauritius', emoji: '🇲🇺' }, { value: 'MV', label: 'Maldives', emoji: '🇲🇻' }, { value: 'MW', label: 'Malawi', emoji: '🇲🇼' }, { value: 'MX', label: 'Mexico', emoji: '🇲🇽' }, { value: 'MY', label: 'Malaysia', emoji: '🇲🇾' }, { value: 'MZ', label: 'Mozambique', emoji: '🇲🇿' }, { value: 'NA', label: 'Namibia', emoji: '🇳🇦' }, { value: 'NC', label: 'New Caledonia', emoji: '🇳🇨' }, { value: 'NE', label: 'Niger', emoji: '🇳🇪' }, { value: 'NF', label: 'Norfolk Island', emoji: '🇳🇫' }, { value: 'NG', label: 'Nigeria', emoji: '🇳🇬' }, { value: 'NI', label: 'Nicaragua', emoji: '🇳🇮' }, { value: 'NL', label: 'Netherlands', emoji: '🇳🇱' }, { value: 'NO', label: 'Norway', emoji: '🇳🇴' }, { value: 'NP', label: 'Nepal', emoji: '🇳🇵' }, { value: 'NR', label: 'Nauru', emoji: '🇳🇷' }, { value: 'NU', label: 'Niue', emoji: '🇳🇺' }, { value: 'NZ', label: 'New Zealand', emoji: '🇳🇿' }, { value: 'OM', label: 'Oman', emoji: '🇴🇲' }, { value: 'PA', label: 'Panama', emoji: '🇵🇦' }, { value: 'PE', label: 'Peru', emoji: '🇵🇪' }, { value: 'PF', label: 'French Polynesia', emoji: '🇵🇫' }, { value: 'PG', label: 'Papua New Guinea', emoji: '🇵🇬' }, { value: 'PH', label: 'Philippines', emoji: '🇵🇭' }, { value: 'PK', label: 'Pakistan', emoji: '🇵🇰' }, { value: 'PL', label: 'Poland', emoji: '🇵🇱' }, { value: 'PR', label: 'Puerto Rico', emoji: '🇵🇷' }, { value: 'PS', label: 'Palestine', emoji: '🇵🇸' }, { value: 'PT', label: 'Portugal', emoji: '🇵🇹' }, { value: 'PW', label: 'Palau', emoji: '🇵🇼' }, { value: 'PY', label: 'Paraguay', emoji: '🇵🇾' }, { value: 'QA', label: 'Qatar', emoji: '🇶🇦' }, { value: 'RO', label: 'Romania', emoji: '🇷🇴' }, { value: 'RS', label: 'Serbia', emoji: '🇷🇸' }, { value: 'RU', label: 'Russia', emoji: '🇷🇺' }, { value: 'RW', label: 'Rwanda', emoji: '🇷🇼' }, { value: 'SA', label: 'Saudi Arabia', emoji: '🇸🇦' }, { value: 'SB', label: 'Solomon Islands', emoji: '🇸🇧' }, { value: 'SC', label: 'Seychelles', emoji: '🇸🇨' }, { value: 'SD', label: 'Sudan', emoji: '🇸🇩' }, { value: 'SE', label: 'Sweden', emoji: '🇸🇪' }, { value: 'SG', label: 'Singapore', emoji: '🇸🇬' }, { value: 'SI', label: 'Slovenia', emoji: '🇸🇮' }, { value: 'SK', label: 'Slovakia', emoji: '🇸🇰' }, { value: 'SL', label: 'Sierra Leone', emoji: '🇸🇱' }, { value: 'SM', label: 'San Marino', emoji: '🇸🇲' }, { value: 'SN', label: 'Senegal', emoji: '🇸🇳' }, { value: 'SO', label: 'Somalia', emoji: '🇸🇴' }, { value: 'SR', label: 'Suriname', emoji: '🇸🇷' }, { value: 'SS', label: 'South Sudan', emoji: '🇸🇸' }, { value: 'ST', label: 'Sao Tome and Principe', emoji: '🇸🇹' }, { value: 'SV', label: 'El Salvador', emoji: '🇸🇻' }, { value: 'SY', label: 'Syria', emoji: '🇸🇾' }, { value: 'SZ', label: 'Eswatini', emoji: '🇸🇿' }, { value: 'TC', label: 'Turks and Caicos Islands', emoji: '🇹🇨' }, { value: 'TD', label: 'Chad', emoji: '🇹🇩' }, { value: 'TG', label: 'Togo', emoji: '🇹🇬' }, { value: 'TH', label: 'Thailand', emoji: '🇹🇭' }, { value: 'TJ', label: 'Tajikistan', emoji: '🇹🇯' }, { value: 'TK', label: 'Tokelau', emoji: '🇹🇰' }, { value: 'TL', label: 'Timor-Leste', emoji: '🇹🇱' }, { value: 'TM', label: 'Turkmenistan', emoji: '🇹🇲' }, { value: 'TN', label: 'Tunisia', emoji: '🇹🇳' }, { value: 'TO', label: 'Tonga', emoji: '🇹🇴' }, { value: 'TR', label: 'Türkiye', emoji: '🇹🇷' }, { value: 'TT', label: 'Trinidad and Tobago', emoji: '🇹🇹' }, { value: 'TV', label: 'Tuvalu', emoji: '🇹🇻' }, { value: 'TW', label: 'Taiwan', emoji: '🇹🇼' }, { value: 'TZ', label: 'Tanzania', emoji: '🇹🇿' }, { value: 'UA', label: 'Ukraine', emoji: '🇺🇦' }, { value: 'UG', label: 'Uganda', emoji: '🇺🇬' }, { value: 'US', label: 'United States', emoji: '🇺🇸' }, { value: 'UY', label: 'Uruguay', emoji: '🇺🇾' }, { value: 'UZ', label: 'Uzbekistan', emoji: '🇺🇿' }, { value: 'VA', label: 'Vatican City', emoji: '🇻🇦' }, { value: 'VC', label: 'Saint Vincent and the Grenadines', emoji: '🇻🇨' }, { value: 'VE', label: 'Venezuela', emoji: '🇻🇪' }, { value: 'VG', label: 'British Virgin Islands', emoji: '🇻🇬' }, { value: 'VI', label: 'U.S. Virgin Islands', emoji: '🇻🇮' }, { value: 'VN', label: 'Vietnam', emoji: '🇻🇳' }, { value: 'VU', label: 'Vanuatu', emoji: '🇻🇺' }, { value: 'WF', label: 'Wallis and Futuna', emoji: '🇼🇫' }, { value: 'WS', label: 'Samoa', emoji: '🇼🇸' }, { value: 'YE', label: 'Yemen', emoji: '🇾🇪' }, { value: 'YT', label: 'Mayotte', emoji: '🇾🇹' }, { value: 'ZA', label: 'South Africa', emoji: '🇿🇦' }, { value: 'ZM', label: 'Zambia', emoji: '🇿🇲' }, { value: 'ZW', label: 'Zimbabwe', emoji: '🇿🇼' }, ] ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { createVirtualizer } from '@tanstack/solid-virtual' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const Virtualized = () => { let contentRef: HTMLDivElement | undefined const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter, reset } = useListCollection({ initialItems: countries, filter: filterFn().startsWith, }) const virtualizer = createVirtualizer({ get count() { return collection().size }, getScrollElement: () => contentRef ?? null, estimateSize: () => 32, overscan: 10, }) const handleScrollToIndex: Combobox.RootProps['scrollToIndexFn'] = (details) => { virtualizer.scrollToIndex(details.index, { align: 'center', behavior: 'auto', }) } const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {virtualizer.getVirtualItems().map((virtualItem) => { const item = collection().items[virtualItem.index] return ( {item.emoji} {item.label} ) })}
                    ) } interface Country { value: string label: string emoji: string } const countries: Country[] = [ { value: 'AD', label: 'Andorra', emoji: '🇦🇩' }, { value: 'AE', label: 'United Arab Emirates', emoji: '🇦🇪' }, { value: 'AF', label: 'Afghanistan', emoji: '🇦🇫' }, { value: 'AG', label: 'Antigua and Barbuda', emoji: '🇦🇬' }, { value: 'AI', label: 'Anguilla', emoji: '🇦🇮' }, { value: 'AL', label: 'Albania', emoji: '🇦🇱' }, { value: 'AM', label: 'Armenia', emoji: '🇦🇲' }, { value: 'AO', label: 'Angola', emoji: '🇦🇴' }, { value: 'AQ', label: 'Antarctica', emoji: '🇦🇶' }, { value: 'AR', label: 'Argentina', emoji: '🇦🇷' }, { value: 'AS', label: 'American Samoa', emoji: '🇦🇸' }, { value: 'AT', label: 'Austria', emoji: '🇦🇹' }, { value: 'AU', label: 'Australia', emoji: '🇦🇺' }, { value: 'AW', label: 'Aruba', emoji: '🇦🇼' }, { value: 'AX', label: 'Åland Islands', emoji: '🇦🇽' }, { value: 'AZ', label: 'Azerbaijan', emoji: '🇦🇿' }, { value: 'BA', label: 'Bosnia and Herzegovina', emoji: '🇧🇦' }, { value: 'BB', label: 'Barbados', emoji: '🇧🇧' }, { value: 'BD', label: 'Bangladesh', emoji: '🇧🇩' }, { value: 'BE', label: 'Belgium', emoji: '🇧🇪' }, { value: 'BF', label: 'Burkina Faso', emoji: '🇧🇫' }, { value: 'BG', label: 'Bulgaria', emoji: '🇧🇬' }, { value: 'BH', label: 'Bahrain', emoji: '🇧🇭' }, { value: 'BI', label: 'Burundi', emoji: '🇧🇮' }, { value: 'BJ', label: 'Benin', emoji: '🇧🇯' }, { value: 'BL', label: 'Saint Barthélemy', emoji: '🇧🇱' }, { value: 'BM', label: 'Bermuda', emoji: '🇧🇲' }, { value: 'BN', label: 'Brunei', emoji: '🇧🇳' }, { value: 'BO', label: 'Bolivia', emoji: '🇧🇴' }, { value: 'BR', label: 'Brazil', emoji: '🇧🇷' }, { value: 'BS', label: 'Bahamas', emoji: '🇧🇸' }, { value: 'BT', label: 'Bhutan', emoji: '🇧🇹' }, { value: 'BW', label: 'Botswana', emoji: '🇧🇼' }, { value: 'BY', label: 'Belarus', emoji: '🇧🇾' }, { value: 'BZ', label: 'Belize', emoji: '🇧🇿' }, { value: 'CA', label: 'Canada', emoji: '🇨🇦' }, { value: 'CD', label: 'Congo', emoji: '🇨🇩' }, { value: 'CF', label: 'Central African Republic', emoji: '🇨🇫' }, { value: 'CH', label: 'Switzerland', emoji: '🇨🇭' }, { value: 'CI', label: "Côte d'Ivoire", emoji: '🇨🇮' }, { value: 'CK', label: 'Cook Islands', emoji: '🇨🇰' }, { value: 'CL', label: 'Chile', emoji: '🇨🇱' }, { value: 'CM', label: 'Cameroon', emoji: '🇨🇲' }, { value: 'CN', label: 'China', emoji: '🇨🇳' }, { value: 'CO', label: 'Colombia', emoji: '🇨🇴' }, { value: 'CR', label: 'Costa Rica', emoji: '🇨🇷' }, { value: 'CU', label: 'Cuba', emoji: '🇨🇺' }, { value: 'CV', label: 'Cabo Verde', emoji: '🇨🇻' }, { value: 'CY', label: 'Cyprus', emoji: '🇨🇾' }, { value: 'CZ', label: 'Czech Republic', emoji: '🇨🇿' }, { value: 'DE', label: 'Germany', emoji: '🇩🇪' }, { value: 'DJ', label: 'Djibouti', emoji: '🇩🇯' }, { value: 'DK', label: 'Denmark', emoji: '🇩🇰' }, { value: 'DM', label: 'Dominica', emoji: '🇩🇲' }, { value: 'DO', label: 'Dominican Republic', emoji: '🇩🇴' }, { value: 'DZ', label: 'Algeria', emoji: '🇩🇿' }, { value: 'EC', label: 'Ecuador', emoji: '🇪🇨' }, { value: 'EE', label: 'Estonia', emoji: '🇪🇪' }, { value: 'EG', label: 'Egypt', emoji: '🇪🇬' }, { value: 'ER', label: 'Eritrea', emoji: '🇪🇷' }, { value: 'ES', label: 'Spain', emoji: '🇪🇸' }, { value: 'ET', label: 'Ethiopia', emoji: '🇪🇹' }, { value: 'FI', label: 'Finland', emoji: '🇫🇮' }, { value: 'FJ', label: 'Fiji', emoji: '🇫🇯' }, { value: 'FK', label: 'Falkland Islands', emoji: '🇫🇰' }, { value: 'FM', label: 'Micronesia', emoji: '🇫🇲' }, { value: 'FO', label: 'Faroe Islands', emoji: '🇫🇴' }, { value: 'FR', label: 'France', emoji: '🇫🇷' }, { value: 'GA', label: 'Gabon', emoji: '🇬🇦' }, { value: 'GB', label: 'United Kingdom', emoji: '🇬🇧' }, { value: 'GD', label: 'Grenada', emoji: '🇬🇩' }, { value: 'GE', label: 'Georgia', emoji: '🇬🇪' }, { value: 'GH', label: 'Ghana', emoji: '🇬🇭' }, { value: 'GI', label: 'Gibraltar', emoji: '🇬🇮' }, { value: 'GL', label: 'Greenland', emoji: '🇬🇱' }, { value: 'GM', label: 'Gambia', emoji: '🇬🇲' }, { value: 'GN', label: 'Guinea', emoji: '🇬🇳' }, { value: 'GQ', label: 'Equatorial Guinea', emoji: '🇬🇶' }, { value: 'GR', label: 'Greece', emoji: '🇬🇷' }, { value: 'GT', label: 'Guatemala', emoji: '🇬🇹' }, { value: 'GU', label: 'Guam', emoji: '🇬🇺' }, { value: 'GW', label: 'Guinea-Bissau', emoji: '🇬🇼' }, { value: 'GY', label: 'Guyana', emoji: '🇬🇾' }, { value: 'HK', label: 'Hong Kong', emoji: '🇭🇰' }, { value: 'HN', label: 'Honduras', emoji: '🇭🇳' }, { value: 'HR', label: 'Croatia', emoji: '🇭🇷' }, { value: 'HT', label: 'Haiti', emoji: '🇭🇹' }, { value: 'HU', label: 'Hungary', emoji: '🇭🇺' }, { value: 'ID', label: 'Indonesia', emoji: '🇮🇩' }, { value: 'IE', label: 'Ireland', emoji: '🇮🇪' }, { value: 'IL', label: 'Israel', emoji: '🇮🇱' }, { value: 'IM', label: 'Isle of Man', emoji: '🇮🇲' }, { value: 'IN', label: 'India', emoji: '🇮🇳' }, { value: 'IQ', label: 'Iraq', emoji: '🇮🇶' }, { value: 'IR', label: 'Iran', emoji: '🇮🇷' }, { value: 'IS', label: 'Iceland', emoji: '🇮🇸' }, { value: 'IT', label: 'Italy', emoji: '🇮🇹' }, { value: 'JE', label: 'Jersey', emoji: '🇯🇪' }, { value: 'JM', label: 'Jamaica', emoji: '🇯🇲' }, { value: 'JO', label: 'Jordan', emoji: '🇯🇴' }, { value: 'JP', label: 'Japan', emoji: '🇯🇵' }, { value: 'KE', label: 'Kenya', emoji: '🇰🇪' }, { value: 'KG', label: 'Kyrgyzstan', emoji: '🇰🇬' }, { value: 'KH', label: 'Cambodia', emoji: '🇰🇭' }, { value: 'KI', label: 'Kiribati', emoji: '🇰🇮' }, { value: 'KM', label: 'Comoros', emoji: '🇰🇲' }, { value: 'KN', label: 'Saint Kitts and Nevis', emoji: '🇰🇳' }, { value: 'KP', label: 'North Korea', emoji: '🇰🇵' }, { value: 'KR', label: 'South Korea', emoji: '🇰🇷' }, { value: 'KW', label: 'Kuwait', emoji: '🇰🇼' }, { value: 'KY', label: 'Cayman Islands', emoji: '🇰🇾' }, { value: 'KZ', label: 'Kazakhstan', emoji: '🇰🇿' }, { value: 'LA', label: 'Laos', emoji: '🇱🇦' }, { value: 'LB', label: 'Lebanon', emoji: '🇱🇧' }, { value: 'LC', label: 'Saint Lucia', emoji: '🇱🇨' }, { value: 'LI', label: 'Liechtenstein', emoji: '🇱🇮' }, { value: 'LK', label: 'Sri Lanka', emoji: '🇱🇰' }, { value: 'LR', label: 'Liberia', emoji: '🇱🇷' }, { value: 'LS', label: 'Lesotho', emoji: '🇱🇸' }, { value: 'LT', label: 'Lithuania', emoji: '🇱🇹' }, { value: 'LU', label: 'Luxembourg', emoji: '🇱🇺' }, { value: 'LV', label: 'Latvia', emoji: '🇱🇻' }, { value: 'LY', label: 'Libya', emoji: '🇱🇾' }, { value: 'MA', label: 'Morocco', emoji: '🇲🇦' }, { value: 'MC', label: 'Monaco', emoji: '🇲🇨' }, { value: 'MD', label: 'Moldova', emoji: '🇲🇩' }, { value: 'ME', label: 'Montenegro', emoji: '🇲🇪' }, { value: 'MG', label: 'Madagascar', emoji: '🇲🇬' }, { value: 'MH', label: 'Marshall Islands', emoji: '🇲🇭' }, { value: 'MK', label: 'North Macedonia', emoji: '🇲🇰' }, { value: 'ML', label: 'Mali', emoji: '🇲🇱' }, { value: 'MM', label: 'Myanmar', emoji: '🇲🇲' }, { value: 'MN', label: 'Mongolia', emoji: '🇲🇳' }, { value: 'MO', label: 'Macao', emoji: '🇲🇴' }, { value: 'MR', label: 'Mauritania', emoji: '🇲🇷' }, { value: 'MS', label: 'Montserrat', emoji: '🇲🇸' }, { value: 'MT', label: 'Malta', emoji: '🇲🇹' }, { value: 'MU', label: 'Mauritius', emoji: '🇲🇺' }, { value: 'MV', label: 'Maldives', emoji: '🇲🇻' }, { value: 'MW', label: 'Malawi', emoji: '🇲🇼' }, { value: 'MX', label: 'Mexico', emoji: '🇲🇽' }, { value: 'MY', label: 'Malaysia', emoji: '🇲🇾' }, { value: 'MZ', label: 'Mozambique', emoji: '🇲🇿' }, { value: 'NA', label: 'Namibia', emoji: '🇳🇦' }, { value: 'NC', label: 'New Caledonia', emoji: '🇳🇨' }, { value: 'NE', label: 'Niger', emoji: '🇳🇪' }, { value: 'NF', label: 'Norfolk Island', emoji: '🇳🇫' }, { value: 'NG', label: 'Nigeria', emoji: '🇳🇬' }, { value: 'NI', label: 'Nicaragua', emoji: '🇳🇮' }, { value: 'NL', label: 'Netherlands', emoji: '🇳🇱' }, { value: 'NO', label: 'Norway', emoji: '🇳🇴' }, { value: 'NP', label: 'Nepal', emoji: '🇳🇵' }, { value: 'NR', label: 'Nauru', emoji: '🇳🇷' }, { value: 'NU', label: 'Niue', emoji: '🇳🇺' }, { value: 'NZ', label: 'New Zealand', emoji: '🇳🇿' }, { value: 'OM', label: 'Oman', emoji: '🇴🇲' }, { value: 'PA', label: 'Panama', emoji: '🇵🇦' }, { value: 'PE', label: 'Peru', emoji: '🇵🇪' }, { value: 'PF', label: 'French Polynesia', emoji: '🇵🇫' }, { value: 'PG', label: 'Papua New Guinea', emoji: '🇵🇬' }, { value: 'PH', label: 'Philippines', emoji: '🇵🇭' }, { value: 'PK', label: 'Pakistan', emoji: '🇵🇰' }, { value: 'PL', label: 'Poland', emoji: '🇵🇱' }, { value: 'PR', label: 'Puerto Rico', emoji: '🇵🇷' }, { value: 'PS', label: 'Palestine', emoji: '🇵🇸' }, { value: 'PT', label: 'Portugal', emoji: '🇵🇹' }, { value: 'PW', label: 'Palau', emoji: '🇵🇼' }, { value: 'PY', label: 'Paraguay', emoji: '🇵🇾' }, { value: 'QA', label: 'Qatar', emoji: '🇶🇦' }, { value: 'RO', label: 'Romania', emoji: '🇷🇴' }, { value: 'RS', label: 'Serbia', emoji: '🇷🇸' }, { value: 'RU', label: 'Russia', emoji: '🇷🇺' }, { value: 'RW', label: 'Rwanda', emoji: '🇷🇼' }, { value: 'SA', label: 'Saudi Arabia', emoji: '🇸🇦' }, { value: 'SB', label: 'Solomon Islands', emoji: '🇸🇧' }, { value: 'SC', label: 'Seychelles', emoji: '🇸🇨' }, { value: 'SD', label: 'Sudan', emoji: '🇸🇩' }, { value: 'SE', label: 'Sweden', emoji: '🇸🇪' }, { value: 'SG', label: 'Singapore', emoji: '🇸🇬' }, { value: 'SI', label: 'Slovenia', emoji: '🇸🇮' }, { value: 'SK', label: 'Slovakia', emoji: '🇸🇰' }, { value: 'SL', label: 'Sierra Leone', emoji: '🇸🇱' }, { value: 'SM', label: 'San Marino', emoji: '🇸🇲' }, { value: 'SN', label: 'Senegal', emoji: '🇸🇳' }, { value: 'SO', label: 'Somalia', emoji: '🇸🇴' }, { value: 'SR', label: 'Suriname', emoji: '🇸🇷' }, { value: 'SS', label: 'South Sudan', emoji: '🇸🇸' }, { value: 'ST', label: 'Sao Tome and Principe', emoji: '🇸🇹' }, { value: 'SV', label: 'El Salvador', emoji: '🇸🇻' }, { value: 'SY', label: 'Syria', emoji: '🇸🇾' }, { value: 'SZ', label: 'Eswatini', emoji: '🇸🇿' }, { value: 'TC', label: 'Turks and Caicos Islands', emoji: '🇹🇨' }, { value: 'TD', label: 'Chad', emoji: '🇹🇩' }, { value: 'TG', label: 'Togo', emoji: '🇹🇬' }, { value: 'TH', label: 'Thailand', emoji: '🇹🇭' }, { value: 'TJ', label: 'Tajikistan', emoji: '🇹🇯' }, { value: 'TK', label: 'Tokelau', emoji: '🇹🇰' }, { value: 'TL', label: 'Timor-Leste', emoji: '🇹🇱' }, { value: 'TM', label: 'Turkmenistan', emoji: '🇹🇲' }, { value: 'TN', label: 'Tunisia', emoji: '🇹🇳' }, { value: 'TO', label: 'Tonga', emoji: '🇹🇴' }, { value: 'TR', label: 'Türkiye', emoji: '🇹🇷' }, { value: 'TT', label: 'Trinidad and Tobago', emoji: '🇹🇹' }, { value: 'TV', label: 'Tuvalu', emoji: '🇹🇻' }, { value: 'TW', label: 'Taiwan', emoji: '🇹🇼' }, { value: 'TZ', label: 'Tanzania', emoji: '🇹🇿' }, { value: 'UA', label: 'Ukraine', emoji: '🇺🇦' }, { value: 'UG', label: 'Uganda', emoji: '🇺🇬' }, { value: 'US', label: 'United States', emoji: '🇺🇸' }, { value: 'UY', label: 'Uruguay', emoji: '🇺🇾' }, { value: 'UZ', label: 'Uzbekistan', emoji: '🇺🇿' }, { value: 'VA', label: 'Vatican City', emoji: '🇻🇦' }, { value: 'VC', label: 'Saint Vincent and the Grenadines', emoji: '🇻🇨' }, { value: 'VE', label: 'Venezuela', emoji: '🇻🇪' }, { value: 'VG', label: 'British Virgin Islands', emoji: '🇻🇬' }, { value: 'VI', label: 'U.S. Virgin Islands', emoji: '🇻🇮' }, { value: 'VN', label: 'Vietnam', emoji: '🇻🇳' }, { value: 'VU', label: 'Vanuatu', emoji: '🇻🇺' }, { value: 'WF', label: 'Wallis and Futuna', emoji: '🇼🇫' }, { value: 'WS', label: 'Samoa', emoji: '🇼🇸' }, { value: 'YE', label: 'Yemen', emoji: '🇾🇪' }, { value: 'YT', label: 'Mayotte', emoji: '🇾🇹' }, { value: 'ZA', label: 'South Africa', emoji: '🇿🇦' }, { value: 'ZM', label: 'Zambia', emoji: '🇿🇲' }, { value: 'ZW', label: 'Zimbabwe', emoji: '🇿🇼' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte Country
                    Open
                    {#each $virtualizer.getVirtualItems() as virtualItem (virtualItem.key)} {@const item = collection().items[virtualItem.index]} {item.label} {/each}
                    ``` ### Custom Object Use the `itemToString` and `itemToValue` props to map custom objects to the required interface. **Example: custom-object** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const CustomObject = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { country: 'United States', code: 'US', flag: '🇺🇸' }, { country: 'Canada', code: 'CA', flag: '🇨🇦' }, { country: 'Australia', code: 'AU', flag: '🇦🇺' }, ], itemToString: (item) => item.country, itemToValue: (item) => item.code, filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {collection.items.map((item) => ( {item.flag} {item.country} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const CustomObject = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { country: 'United States', code: 'US', flag: '🇺🇸' }, { country: 'Canada', code: 'CA', flag: '🇨🇦' }, { country: 'Australia', code: 'AU', flag: '🇦🇺' }, ], itemToString: (item) => item.country, itemToValue: (item) => item.code, filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    Clear Open
                    {(item) => ( {item.flag} {item.country} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Country
                    Clear Open
                    {#each collection().items as item (item.code)} {item.flag} {item.country} {/each}
                    ``` ### Limit Results Use the `limit` property on `useListCollection` to limit the number of rendered items in the DOM. **Example: limit-results** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' const cities = [ { label: 'New York', value: 'new-york' }, { label: 'Los Angeles', value: 'los-angeles' }, { label: 'Chicago', value: 'chicago' }, { label: 'Houston', value: 'houston' }, { label: 'Phoenix', value: 'phoenix' }, { label: 'Philadelphia', value: 'philadelphia' }, { label: 'San Antonio', value: 'san-antonio' }, { label: 'San Diego', value: 'san-diego' }, { label: 'Dallas', value: 'dallas' }, { label: 'San Jose', value: 'san-jose' }, { label: 'Austin', value: 'austin' }, { label: 'Jacksonville', value: 'jacksonville' }, { label: 'Fort Worth', value: 'fort-worth' }, { label: 'Columbus', value: 'columbus' }, { label: 'Charlotte', value: 'charlotte' }, { label: 'San Francisco', value: 'san-francisco' }, { label: 'Indianapolis', value: 'indianapolis' }, { label: 'Seattle', value: 'seattle' }, { label: 'Denver', value: 'denver' }, { label: 'Boston', value: 'boston' }, ] export const LimitResults = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: cities, limit: 5, filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( City
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' const cities = [ { label: 'New York', value: 'new-york' }, { label: 'Los Angeles', value: 'los-angeles' }, { label: 'Chicago', value: 'chicago' }, { label: 'Houston', value: 'houston' }, { label: 'Phoenix', value: 'phoenix' }, { label: 'Philadelphia', value: 'philadelphia' }, { label: 'San Antonio', value: 'san-antonio' }, { label: 'San Diego', value: 'san-diego' }, { label: 'Dallas', value: 'dallas' }, { label: 'San Jose', value: 'san-jose' }, { label: 'Austin', value: 'austin' }, { label: 'Jacksonville', value: 'jacksonville' }, { label: 'Fort Worth', value: 'fort-worth' }, { label: 'Columbus', value: 'columbus' }, { label: 'Charlotte', value: 'charlotte' }, { label: 'San Francisco', value: 'san-francisco' }, { label: 'Indianapolis', value: 'indianapolis' }, { label: 'Seattle', value: 'seattle' }, { label: 'Denver', value: 'denver' }, { label: 'Boston', value: 'boston' }, ] export const LimitResults = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: cities, limit: 5, filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( City
                    Open
                    {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte City
                    Open
                    {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ## Guides ### Router Links Customize the `navigate` prop on `Combobox.Root` to integrate with your router. Using Tanstack Router: ```tsx import { Combobox } from '@ark-ui//combobox' import { useNavigate } from '@tanstack/react-router' function Demo() { const navigate = useNavigate() return ( { navigate({ to: e.node.href }) }} > {/* ... */} ) } ``` ### Custom Objects By default, the combobox collection expects an array of objects with `label` and `value` properties. In some cases, you may need to deal with custom objects. Use the `itemToString` and `itemToValue` props to map the custom object to the required interface. ```tsx const items = [ { country: 'United States', code: 'US', flag: '🇺🇸' }, { country: 'Canada', code: 'CA', flag: '🇨🇦' }, { country: 'Australia', code: 'AU', flag: '🇦🇺' }, // ... ] const { collection } = useListCollection({ initialItems: items, itemToString: (item) => item.country, itemToValue: (item) => item.code, }) ``` ### Type Safety The `Combobox.RootComponent` type enables you to create typed wrapper components that maintain full type safety for collection items. ```tsx const Combobox: ArkCombobox.RootComponent = (props) => { return {/* ... */} } ``` Use the wrapper with full type inference on `onValueChange` and other callbacks: ```tsx const App = () => { const { collection } = useListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, ], }) return ( { // e.items is typed as Array<{ label: string, value: string }> console.log(e.items) }} > {/* ... */} ) } ``` ### Large Datasets The recommended way of managing large lists is to use the `limit` property on the `useListCollection` hook. This will limit the number of rendered items in the DOM to improve performance. ```tsx {3} const { collection } = useListCollection({ initialItems: items, limit: 10, }) ``` ### Available Size The following css variables are exposed to the `Combobox.Positioner` which you can use to style the `Combobox.Content` ```css /* width of the combobox control */ --reference-width: ; /* width of the available viewport */ --available-width: ; /* height of the available viewport */ --available-height: ; ``` For example, if you want to make sure the maximum height doesn't exceed the available height, you can use the following: ```css [data-scope='combobox'][data-part='content'] { max-height: calc(var(--available-height) - 100px); } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input | | `alwaysSubmitOnEnter` | `boolean` | No | Whether to always submit on Enter key press, even if popup is open. Useful for single-field autocomplete forms where Enter should submit the form. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the input on mount | | `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. | | `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. | | `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. | | `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. | | `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. | | `disabled` | `boolean` | No | Whether the combobox is disabled | | `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer | | `form` | `string` | No | The associate form of the combobox. | | `highlightedValue` | `string` | No | The controlled highlighted value of the combobox | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string control: string input: string content: string trigger: string clearTrigger: string item: (id: string, index?: number | undefined) => string positioner: string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the combobox. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inputBehavior` | `'none' | 'autohighlight' | 'autocomplete'` | No | Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated | | `inputValue` | `string` | No | The controlled value of the combobox's input | | `invalid` | `boolean` | No | Whether the combobox is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items | | `multiple` | `boolean` | No | Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. | | `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when an item is highlighted using the pointer or keyboard navigation. | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Function called when the input's value changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when a new item is selected | | `open` | `boolean` | No | The controlled open state of the combobox | | `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes | | `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input | | `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press | | `placeholder` | `string` | No | The placeholder text of the combobox's input | | `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it | | `required` | `boolean` | No | Whether the combobox is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionBehavior` | `'clear' | 'replace' | 'preserve'` | No | The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the combobox's selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested comboboxs | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-autofocus]` | | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-group | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-value]` | The value of the item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | label | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | list | | `[data-empty]` | Present when the content is empty | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseComboboxReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `focusable` | `boolean` | No | Whether the trigger is focusable | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | | `[data-focusable]` | | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input | | `alwaysSubmitOnEnter` | `boolean` | No | Whether to always submit on Enter key press, even if popup is open. Useful for single-field autocomplete forms where Enter should submit the form. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the input on mount | | `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. | | `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. | | `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. | | `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. | | `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. | | `disabled` | `boolean` | No | Whether the combobox is disabled | | `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer | | `form` | `string` | No | The associate form of the combobox. | | `highlightedValue` | `string` | No | The controlled highlighted value of the combobox | | `ids` | `Partial<{ root: string label: string control: string input: string content: string trigger: string clearTrigger: string item: (id: string, index?: number | undefined) => string positioner: string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the combobox. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inputBehavior` | `'none' | 'autohighlight' | 'autocomplete'` | No | Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated | | `inputValue` | `string` | No | The controlled value of the combobox's input | | `invalid` | `boolean` | No | Whether the combobox is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items | | `multiple` | `boolean` | No | Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. | | `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when an item is highlighted using the pointer or keyboard navigation. | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Function called when the input's value changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when a new item is selected | | `open` | `boolean` | No | The controlled open state of the combobox | | `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes | | `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input | | `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press | | `placeholder` | `string` | No | The placeholder text of the combobox's input | | `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it | | `required` | `boolean` | No | Whether the combobox is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionBehavior` | `'replace' | 'clear' | 'preserve'` | No | The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the combobox's selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested comboboxs | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-autofocus]` | | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-group | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-value]` | The value of the item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | label | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | list | | `[data-empty]` | Present when the content is empty | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseComboboxReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `focusable` | `boolean` | No | Whether the trigger is focusable | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | | `[data-focusable]` | | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input | | `alwaysSubmitOnEnter` | `boolean` | No | Whether to allow bypassing the default two-step behavior (Enter to close combobox, then Enter to submit form) and instead submit the form immediately on Enter press. This is useful for single-field autocomplete forms where Enter should submit the form directly. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the input on mount | | `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. | | `collection` | `ListCollection` | No | The collection of items | | `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. | | `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. | | `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. | | `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. | | `disabled` | `boolean` | No | Whether the combobox is disabled | | `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer | | `form` | `string` | No | The associate form of the combobox. | | `highlightedValue` | `string` | No | The controlled highlighted value of the combobox | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string control: string input: string content: string trigger: string clearTrigger: string item(id: string, index?: number | undefined): string positioner: string itemGroup(id: string | number): string itemGroupLabel(id: string | number): string }>` | No | The ids of the elements in the combobox. Useful for composition. | | `inputBehavior` | `'none' | 'autohighlight' | 'autocomplete'` | No | Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated | | `inputValue` | `string` | No | The controlled value of the combobox's input | | `invalid` | `boolean` | No | Whether the combobox is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items | | `modelValue` | `string[]` | No | The v-model value of the combobox | | `multiple` | `boolean` | No | Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. | | `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item | | `open` | `boolean` | No | The controlled open state of the combobox | | `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes | | `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input | | `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press | | `placeholder` | `string` | No | The placeholder text of the combobox's input | | `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu | | `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it | | `required` | `boolean` | No | Whether the combobox is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionBehavior` | `'clear' | 'replace' | 'preserve'` | No | The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested comboboxs | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-autofocus]` | | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-group | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-value]` | The value of the item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | label | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | list | | `[data-empty]` | Present when the content is empty | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ComboboxApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `focusable` | `boolean` | No | Whether the trigger is focusable | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | | `[data-focusable]` | | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `MaybeFunction>` | Yes | The collection of items | | `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input | | `alwaysSubmitOnEnter` | `boolean` | No | Whether to always submit on Enter key press, even if popup is open. Useful for single-field autocomplete forms where Enter should submit the form. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the input on mount | | `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. | | `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. | | `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. | | `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. | | `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. | | `disabled` | `boolean` | No | Whether the combobox is disabled | | `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer | | `form` | `string` | No | The associate form of the combobox. | | `highlightedValue` | `string` | No | The controlled highlighted value of the combobox | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string control: string input: string content: string trigger: string clearTrigger: string item: (id: string, index?: number | undefined) => string positioner: string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the combobox. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inputBehavior` | `'none' | 'autocomplete' | 'autohighlight'` | No | Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated | | `inputValue` | `string` | No | The controlled value of the combobox's input | | `invalid` | `boolean` | No | Whether the combobox is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items | | `multiple` | `boolean` | No | Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. | | `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when an item is highlighted using the pointer or keyboard navigation. | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Function called when the input's value changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when a new item is selected | | `open` | `boolean` | No | The controlled open state of the combobox | | `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes | | `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input | | `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press | | `placeholder` | `string` | No | The placeholder text of the combobox's input | | `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the combobox is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionBehavior` | `'replace' | 'clear' | 'preserve'` | No | The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the combobox's selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested comboboxs | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseComboboxContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-autofocus]` | | | `[data-state]` | "open" | "closed" | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseComboboxItemContext]>` | Yes | | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | | `ref` | `Element` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-group | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `{}` | No | | | `persistFocus` | `boolean` | No | | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-value]` | The value of the item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | label | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | list | | `[data-empty]` | Present when the content is empty | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseComboboxReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `ref` | `Element` | No | | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | | `[data-focusable]` | | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focused` | `boolean` | Whether the combobox is focused | | `open` | `boolean` | Whether the combobox is open | | `inputValue` | `string` | The value of the combobox input | | `highlightedValue` | `string` | The value of the highlighted item | | `highlightedItem` | `V` | The highlighted item | | `setHighlightValue` | `(value: string) => void` | The value of the combobox input | | `clearHighlightValue` | `VoidFunction` | Function to clear the highlighted value | | `syncSelectedItems` | `VoidFunction` | Function to sync the selected items with the value. Useful when `value` is updated from async sources. | | `selectedItems` | `V[]` | The selected items | | `hasSelectedItems` | `boolean` | Whether there's a selected item | | `value` | `string[]` | The selected item keys | | `valueAsString` | `string` | The string representation of the selected items | | `selectValue` | `(value: string) => void` | Function to select a value | | `setValue` | `(value: string[]) => void` | Function to set the value of the combobox | | `clearValue` | `(value?: string) => void` | Function to clear the value of the combobox | | `focus` | `VoidFunction` | Function to focus on the combobox input | | `setInputValue` | `(value: string, reason?: InputValueChangeReason) => void` | Function to set the input value of the combobox | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a combobox item | | `setOpen` | `(open: boolean, reason?: OpenChangeReason) => void` | Function to open or close the combobox | | `collection` | `ListCollection` | Function to toggle the combobox | | `reposition` | `(options?: Partial) => void` | Function to set the positioning options | | `multiple` | `boolean` | Whether the combobox allows multiple selections | | `disabled` | `boolean` | Whether the combobox is disabled | ## Accessibility Complies with the [Combobox WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/). ### Keyboard Support **`ArrowDown`** Description: When the combobox is closed, opens the listbox and highlights to the first option. When the combobox is open, moves focus to the next option. **`ArrowUp`** Description: When the combobox is closed, opens the listbox and highlights to the last option. When the combobox is open, moves focus to the previous option. **`Home`** Description: When the combobox is open, moves focus to the first option. **`End`** Description: When the combobox is open, moves focus to the last option. **`Escape`** Description: Closes the listbox. **`Enter`** Description: Selects the highlighted option and closes the combobox. **`Esc`** Description: Closes the combobox --- # Combobox (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const Basic = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }, { label: 'Orange', value: 'orange' }, { label: 'Mango', value: 'mango' }, { label: 'Pineapple', value: 'pineapple' }, { label: 'Strawberry', value: 'strawberry' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Favorite Fruit
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const Basic = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Apple', value: 'apple' }, { label: 'Banana', value: 'banana' }, { label: 'Orange', value: 'orange' }, { label: 'Mango', value: 'mango' }, { label: 'Pineapple', value: 'pineapple' }, { label: 'Strawberry', value: 'strawberry' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Favorite Fruit
                    {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Fruit
                    Clear Open
                    No results found {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Auto Highlight Automatically highlight the first matching item as the user types by setting `inputBehavior="autohighlight"`. **Example: auto-highlight** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const AutoHighlight = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Engineering', value: 'engineering' }, { label: 'Marketing', value: 'marketing' }, { label: 'Sales', value: 'sales' }, { label: 'Finance', value: 'finance' }, { label: 'Human Resources', value: 'hr' }, { label: 'Operations', value: 'operations' }, { label: 'Product', value: 'product' }, { label: 'Customer Success', value: 'customer-success' }, { label: 'Legal', value: 'legal' }, { label: 'Information Technology', value: 'information-technology' }, { label: 'Design', value: 'design' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Department
                    No results found {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const AutoHighlight = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Engineering', value: 'engineering' }, { label: 'Marketing', value: 'marketing' }, { label: 'Sales', value: 'sales' }, { label: 'Finance', value: 'finance' }, { label: 'Human Resources', value: 'hr' }, { label: 'Operations', value: 'operations' }, { label: 'Product', value: 'product' }, { label: 'Customer Success', value: 'customer-success' }, { label: 'Legal', value: 'legal' }, { label: 'Information Technology', value: 'information-technology' }, { label: 'Design', value: 'design' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Department
                    Clear Open
                    No results found {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Department
                    Clear Open
                    No results found {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Inline Autocomplete Complete the input value with the first matching item by setting `inputBehavior="autocomplete"`. Use with `startsWith` filter for best results. **Example: inline-autocomplete** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const InlineAutocomplete = () => { const { startsWith } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Whale', value: 'whale' }, { label: 'Dolphin', value: 'dolphin' }, { label: 'Shark', value: 'shark' }, { label: 'Octopus', value: 'octopus' }, { label: 'Jellyfish', value: 'jellyfish' }, { label: 'Seahorse', value: 'seahorse' }, ], filter: startsWith, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Sea Creature
                    No results found {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const InlineAutocomplete = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Whale', value: 'whale' }, { label: 'Dolphin', value: 'dolphin' }, { label: 'Shark', value: 'shark' }, { label: 'Octopus', value: 'octopus' }, { label: 'Jellyfish', value: 'jellyfish' }, { label: 'Seahorse', value: 'seahorse' }, ], filter: filterFn().startsWith, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Sea Creature
                    Clear Open
                    No results found {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Sea Creature
                    Clear Open
                    No results found {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Grouping To group related combobox items, use the `groupBy` prop on the collection and `collection.group()` to iterate the groups. **Example: grouping** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const Grouping = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: contains, groupBy: (item) => item.continent, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {collection.group().map(([continent, group]) => ( {continent} {group.map((item) => ( {item.label} ))} ))}
                    ) } const initialItems = [ { label: 'Canada', value: 'ca', continent: 'North America' }, { label: 'United States', value: 'us', continent: 'North America' }, { label: 'Mexico', value: 'mx', continent: 'North America' }, { label: 'United Kingdom', value: 'uk', continent: 'Europe' }, { label: 'Germany', value: 'de', continent: 'Europe' }, { label: 'France', value: 'fr', continent: 'Europe' }, { label: 'Japan', value: 'jp', continent: 'Asia' }, { label: 'South Korea', value: 'kr', continent: 'Asia' }, { label: 'China', value: 'cn', continent: 'Asia' }, ] ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' const initialItems = [ { label: 'Canada', value: 'ca', continent: 'North America' }, { label: 'United States', value: 'us', continent: 'North America' }, { label: 'Mexico', value: 'mx', continent: 'North America' }, { label: 'United Kingdom', value: 'uk', continent: 'Europe' }, { label: 'Germany', value: 'de', continent: 'Europe' }, { label: 'France', value: 'fr', continent: 'Europe' }, { label: 'Japan', value: 'jp', continent: 'Asia' }, { label: 'South Korea', value: 'kr', continent: 'Asia' }, { label: 'China', value: 'cn', continent: 'Asia' }, ] export const Grouping = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: filterFn().contains, groupBy: (item) => item.continent, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {([continent, group]) => ( {continent} {(item) => ( {item.label} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Country
                    Clear Open
                    {#each collection().group() as [continent, group]} {continent} {#each group as item} {item.label} {/each} {/each}
                    ``` ### Field The `Field` component helps manage form-related state and accessibility attributes of a combobox. It includes handling ARIA labels, helper text, and error text to ensure proper accessibility. **Example: with-field** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { Field } from '@ark-ui/react/field' import { useFilter } from '@ark-ui/react/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' import field from 'styles/field.module.css' export const WithField = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Department
                    {collection.items.map((item) => ( {item.label} ))}
                    Select your primary department Department is required
                    ) } const initialItems = [ { label: 'Engineering', value: 'engineering' }, { label: 'Design', value: 'design' }, { label: 'Marketing', value: 'marketing' }, { label: 'Sales', value: 'sales' }, { label: 'Human Resources', value: 'hr' }, { label: 'Finance', value: 'finance' }, ] ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { Field } from '@ark-ui/solid/field' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import styles from 'styles/combobox.module.css' import field from 'styles/field.module.css' const initialItems = [ { label: 'Engineering', value: 'engineering' }, { label: 'Design', value: 'design' }, { label: 'Marketing', value: 'marketing' }, { label: 'Sales', value: 'sales' }, { label: 'Human Resources', value: 'hr' }, { label: 'Finance', value: 'finance' }, ] export const WithField = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Department
                    Clear Open
                    {(item) => ( {item.label} )}
                    Select your primary department Department is required
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Department
                    Clear Open
                    {#each collection().items as item (item.value)} {item.label} {/each}
                    Select your primary department Department is required
                    ``` ### Context Use the `Combobox.Context` component to access the combobox state and display information like the selected value. **Example: context** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const Context = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Small', value: 'sm' }, { label: 'Medium', value: 'md' }, { label: 'Large', value: 'lg' }, { label: 'Extra Large', value: 'xl' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( {(combobox) =>

                    Selected: {combobox.valueAsString || 'None'}

                    }
                    Size
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const Context = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'Small', value: 'sm' }, { label: 'Medium', value: 'md' }, { label: 'Large', value: 'lg' }, { label: 'Extra Large', value: 'xl' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( {(context) =>

                    Selected: {context().valueAsString || 'None'}

                    }
                    Size
                    {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(combobox)}

                    Selected: {combobox().valueAsString || 'None'}

                    {/snippet}
                    Size
                    Clear Open
                    {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Root Provider An alternative way to control the combobox is to use the `RootProvider` component and the `useCombobox` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { Combobox, useCombobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/combobox.module.css' const initialItems = [ { label: 'Designer', value: 'designer' }, { label: 'Developer', value: 'developer' }, { label: 'Product Manager', value: 'pm' }, { label: 'Data Scientist', value: 'data-scientist' }, { label: 'DevOps Engineer', value: 'devops' }, { label: 'Marketing Lead', value: 'marketing' }, ] export const RootProvider = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: contains, }) const combobox = useCombobox({ collection, onInputValueChange(details) { filter(details.inputValue) }, }) return (
                    Job Title
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useCombobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/combobox.module.css' const initialItems = [ { label: 'Designer', value: 'designer' }, { label: 'Developer', value: 'developer' }, { label: 'Product Manager', value: 'pm' }, { label: 'Data Scientist', value: 'data-scientist' }, { label: 'DevOps Engineer', value: 'devops' }, { label: 'Marketing Lead', value: 'marketing' }, ] export const RootProvider = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: filterFn().contains, }) const combobox = useCombobox({ get collection() { return collection() }, onInputValueChange(details) { filter(details.inputValue) }, }) return (
                    Job Title
                    {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Job Title
                    Clear Open
                    {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### Links Use the `asChild` prop to render the combobox items as links. **Example: links** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const Links = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Developer Resources
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } const initialItems = [ { label: 'GitHub', href: 'https://github.com', value: 'github' }, { label: 'Stack Overflow', href: 'https://stackoverflow.com', value: 'stackoverflow' }, { label: 'MDN Web Docs', href: 'https://developer.mozilla.org', value: 'mdn' }, { label: 'npm', href: 'https://www.npmjs.com', value: 'npm' }, { label: 'TypeScript', href: 'https://www.typescriptlang.org', value: 'typescript' }, { label: 'React', href: 'https://react.dev', value: 'react' }, ] ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' const initialItems = [ { label: 'GitHub', href: 'https://github.com', value: 'github' }, { label: 'Stack Overflow', href: 'https://stackoverflow.com', value: 'stackoverflow' }, { label: 'MDN Web Docs', href: 'https://developer.mozilla.org', value: 'mdn' }, { label: 'npm', href: 'https://www.npmjs.com', value: 'npm' }, { label: 'TypeScript', href: 'https://www.typescriptlang.org', value: 'typescript' }, { label: 'React', href: 'https://react.dev', value: 'react' }, ] export const Links = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems, filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Developer Resources
                    {(item) => ( }> {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Developer Resources
                    Open
                    {#each collection().items as item (item.value)} {#snippet asChild(props)}
                    {item.label} {/snippet} {/each} ``` ### Rehydrate When a combobox has a `defaultValue` or `value` but the `collection` is not loaded yet, you can rehydrate the value to populate the input. **Example: rehydrate-value** #### React ```tsx import { Combobox, useCombobox, useComboboxContext, useListCollection } from '@ark-ui/react/combobox' import { Portal } from '@ark-ui/react/portal' import { CheckIcon } from 'lucide-react' import { useRef, useState } from 'react' import { useAsync } from 'react-use' import styles from 'styles/combobox.module.css' function ComboboxRehydrateValue() { const combobox = useComboboxContext() const hydrated = useRef(false) if (combobox.value.length && combobox.collection.size && !hydrated.current) { combobox.syncSelectedItems() hydrated.current = true } return null } export const RehydrateValue = () => { const [inputValue, setInputValue] = useState('') const { collection, set } = useListCollection({ initialItems: [], itemToString: (item) => item.name, itemToValue: (item) => item.name, }) const combobox = useCombobox({ collection, defaultValue: ['C-3PO'], placeholder: 'Example: Dexter', inputValue, onInputValueChange: (e) => setInputValue(e.inputValue), }) const state = useAsync(async () => { const response = await fetch(`https://swapi.py4e.com/api/people/?search=${inputValue}`) const data = await response.json() set(data.results) }, [inputValue, set]) return ( Search Star Wars Characters {state.loading ? ( Loading... ) : state.error ? ( {state.error.message} ) : ( collection.items.map((item) => ( {item.name} - {item.height}cm / {item.mass}kg )) )} ) } interface Character { name: string height: string mass: string created: string edited: string url: string } ``` #### Solid ```tsx import { Combobox, useCombobox, useComboboxContext, useListCollection } from '@ark-ui/solid/combobox' import { For, createEffect, createRenderEffect, createSignal, on } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' import { useAsync } from './use-async' function ComboboxRehydrateValue() { const combobox = useComboboxContext() let hydrated = false createRenderEffect(() => { if (combobox().value.length && combobox().collection.size && !hydrated) { combobox().syncSelectedItems() hydrated = true } }) return null } export const RehydrateValue = () => { const [inputValue, setInputValue] = createSignal('') const { collection, set } = useListCollection({ initialItems: [], itemToString: (item) => item.name, itemToValue: (item) => item.name, }) const combobox = useCombobox(() => ({ collection: collection(), defaultValue: ['C-3PO'], placeholder: 'Example: Dexter', inputValue: inputValue(), onInputValueChange: (e) => setInputValue(e.inputValue), })) const state = useAsync(async (signal) => { const response = await fetch(`https://swapi.py4e.com/api/people/?search=${inputValue()}`, { signal }) const data = await response.json() set(data.results) }) createEffect(on(inputValue, () => state.load())) return ( Search Star Wars Characters {state.loading() ? ( Loading... ) : state.error() ? ( {state.error()?.message} ) : ( {(item) => ( {item.name} - {item.height}cm / {item.mass}kg )} )} ) } interface Character { name: string height: string mass: string created: string edited: string url: string } ``` #### Vue ```vue ``` #### Svelte ```svelte Search Star Wars Characters {#if _state.loading()} Loading... {:else if _state.error()} {_state.error()?.message} {:else} {#each collection().items as item (item.name)} {item.name} - {item.height}cm / {item.mass}kg {/each} {/if} ``` ### Highlight Text Highlight the matching search text in combobox items based on the user's input. **Example: highlight-matching-text** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { Highlight } from '@ark-ui/react/highlight' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const HighlightMatchingText = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'John Smith', value: 'john-smith' }, { label: 'Jane Doe', value: 'jane-doe' }, { label: 'Bob Johnson', value: 'bob-johnson' }, { label: 'Alice Williams', value: 'alice-williams' }, { label: 'Charlie Brown', value: 'charlie-brown' }, { label: 'Diana Ross', value: 'diana-ross' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Assignee
                    {collection.items.map((item) => ( {(context) => } ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { Highlight } from '@ark-ui/solid/highlight' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const HighlightMatchingText = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { label: 'John Smith', value: 'john-smith' }, { label: 'Jane Doe', value: 'jane-doe' }, { label: 'Bob Johnson', value: 'bob-johnson' }, { label: 'Alice Williams', value: 'alice-williams' }, { label: 'Charlie Brown', value: 'charlie-brown' }, { label: 'Diana Ross', value: 'diana-ross' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Assignee
                    Clear Open
                    {(item) => ( {(context) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Assignee
                    Clear Open
                    {#each collection().items as item (item.value)} {#snippet render(context)} {/snippet} {/each}
                    ``` ### Dynamic Generate combobox items dynamically based on user input. This is useful for creating suggestions or autocomplete functionality. **Example: dynamic** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' const suggestList = ['gmail.com', 'yahoo.com', 'ark-ui.com'] export const Dynamic = () => { const { collection, set } = useListCollection({ initialItems: [], }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { if (details.reason === 'input-change') { const items = suggestList.map((item) => `${details.inputValue}@${item}`) set(items) } } return ( Email
                    {collection.items.map((item) => ( {item} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' const suggestList = ['gmail.com', 'yahoo.com', 'ark-ui.com'] export const Dynamic = () => { const { collection, set } = useListCollection({ initialItems: [], }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { if (details.reason === 'input-change') { const items = suggestList.map((item) => `${details.inputValue}@${item}`) set(items) } } return ( Email
                    Open
                    {(item) => ( {item} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Email
                    Open
                    {#each collection().items as item (item)} {item} {/each}
                    ``` ### 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. **Example: creatable** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import { flushSync } from 'react-dom' import styles from 'styles/combobox.module.css' interface Item { label: string value: string __new__?: boolean } const NEW_OPTION_VALUE = '[[new]]' const createNewOption = (value: string): Item => ({ label: value, value: NEW_OPTION_VALUE }) const isNewOptionValue = (value: string) => value === NEW_OPTION_VALUE const replaceNewOptionValue = (values: string[], value: string) => values.map((v) => (v === NEW_OPTION_VALUE ? value : v)) const getNewOptionData = (inputValue: string): Item => ({ label: inputValue, value: inputValue, __new__: true }) export const Creatable = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter, upsert, update, remove } = useListCollection({ initialItems: [ { label: 'Bug', value: 'bug' }, { label: 'Feature', value: 'feature' }, { label: 'Enhancement', value: 'enhancement' }, { label: 'Documentation', value: 'docs' }, ], filter: contains, }) const isValidNewOption = (inputValue: string) => { const exactOptionMatch = collection.filter((item) => item.toLowerCase() === inputValue.toLowerCase()).size > 0 return !exactOptionMatch && inputValue.trim().length > 0 } const [selectedValue, setSelectedValue] = useState([]) const [inputValue, setInputValue] = useState('') const handleInputChange = ({ inputValue, reason }: Combobox.InputValueChangeDetails) => { if (reason === 'input-change' || reason === 'item-select') { flushSync(() => { if (isValidNewOption(inputValue)) { upsert(NEW_OPTION_VALUE, createNewOption(inputValue)) } else if (inputValue.trim().length === 0) { remove(NEW_OPTION_VALUE) } }) filter(inputValue) } setInputValue(inputValue) } const handleOpenChange = ({ reason }: Combobox.OpenChangeDetails) => { if (reason === 'trigger-click') { filter('') } } const handleValueChange = ({ value }: Combobox.ValueChangeDetails) => { setSelectedValue(replaceNewOptionValue(value, inputValue)) if (value.includes(NEW_OPTION_VALUE)) { console.log('New Option Created', inputValue) update(NEW_OPTION_VALUE, getNewOptionData(inputValue)) } } return ( Label
                    {collection.items.map((item) => ( {isNewOptionValue(item.value) ? ( + Create "{item.label}" ) : ( {item.label} {item.__new__ ? '(new)' : ''} )} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { createSignal, For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' interface Item { label: string value: string __new__?: boolean } const NEW_OPTION_VALUE = '[[new]]' const createNewOption = (value: string): Item => ({ label: value, value: NEW_OPTION_VALUE }) const isNewOptionValue = (value: string) => value === NEW_OPTION_VALUE const replaceNewOptionValue = (values: string[], value: string) => values.map((v) => (v === NEW_OPTION_VALUE ? value : v)) const getNewOptionData = (inputValue: string): Item => ({ label: inputValue, value: inputValue, __new__: true }) export const Creatable = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter, upsert, update, remove } = useListCollection({ initialItems: [ { label: 'Bug', value: 'bug' }, { label: 'Feature', value: 'feature' }, { label: 'Enhancement', value: 'enhancement' }, { label: 'Documentation', value: 'docs' }, ], filter: filterFn().contains, }) const isValidNewOption = (inputValue: string) => { const exactOptionMatch = collection().items.filter((item) => item.label.toLowerCase() === inputValue.toLowerCase()).length > 0 return !exactOptionMatch && inputValue.trim().length > 0 } const [selectedValue, setSelectedValue] = createSignal([]) const [inputValue, setInputValue] = createSignal('') const handleInputChange = ({ inputValue: newInputValue, reason }: Combobox.InputValueChangeDetails) => { if (reason === 'input-change' || reason === 'item-select') { if (isValidNewOption(newInputValue)) { upsert(NEW_OPTION_VALUE, createNewOption(newInputValue)) } else if (newInputValue.trim().length === 0) { remove(NEW_OPTION_VALUE) } filter(newInputValue) } setInputValue(newInputValue) } const handleOpenChange = ({ reason }: Combobox.OpenChangeDetails) => { if (reason === 'trigger-click') { filter('') } } const handleValueChange = ({ value }: Combobox.ValueChangeDetails) => { setSelectedValue(replaceNewOptionValue(value, inputValue())) if (value.includes(NEW_OPTION_VALUE)) { console.log('New Option Created', inputValue()) update(NEW_OPTION_VALUE, getNewOptionData(inputValue())) } } return ( Label
                    Clear Open
                    {(item) => ( {isNewOptionValue(item.value) ? ( + Create "{item.label}" ) : ( {item.label} {item.__new__ ? '(new)' : ''} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    Clear Open
                    {#each collection().items as item (item.value)} {#if isNewOptionValue(item.value)} + Create "{item.label}" {:else} {item.label} {item.__new__ ? '(new)' : ''} {/if} {/each}
                    ``` ### Multiple Selection Enable multiple selection by setting the `multiple` prop. Selected items can be displayed as tags above the input. **Example: multiple** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import { useRef } from 'react' import styles from 'styles/combobox.module.css' export const Multiple = () => { const { contains } = useFilter({ sensitivity: 'base' }) const selectedValue = useRef([]) const { collection, filter, remove } = useListCollection({ initialItems: [ { label: 'JavaScript', value: 'js' }, { label: 'TypeScript', value: 'ts' }, { label: 'Python', value: 'python' }, { label: 'Go', value: 'go' }, { label: 'Rust', value: 'rust' }, { label: 'Java', value: 'java' }, ], filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } const handleValueChange = (details: Combobox.ValueChangeDetails) => { selectedValue.current = details.value remove(...details.value) } return ( Skills {(combobox) => (
                    {combobox.selectedItems.length === 0 && None selected} {combobox.selectedItems.map((item: any) => ( {item.label} ))}
                    )}
                    No skills found {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-solid' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const Multiple = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter, remove } = useListCollection({ initialItems: [ { label: 'JavaScript', value: 'js' }, { label: 'TypeScript', value: 'ts' }, { label: 'Python', value: 'python' }, { label: 'Go', value: 'go' }, { label: 'Rust', value: 'rust' }, { label: 'Java', value: 'java' }, ], filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } const handleValueChange = (details: Combobox.ValueChangeDetails) => { remove(...details.value) } return ( Skills {(context) => (
                    {context().selectedItems.length === 0 && None selected} {(item: any) => {item.label}}
                    )}
                    No skills found {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Skills
                    {#if selectedItems.length === 0} None selected {/if} {#each selectedItems as item (item.value)} {item.label} {/each}
                    Open
                    No skills found {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ### 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. **Example: async-search** #### React ```tsx import { useAsyncList } from '@ark-ui/react/collection' import { Combobox, createListCollection } from '@ark-ui/react/combobox' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, LoaderIcon, XIcon } from 'lucide-react' import { startTransition } from 'react' import styles from 'styles/combobox.module.css' interface Movie { id: string title: string year: number director: string genre: string } export const AsyncSearch = () => { const list = useAsyncList({ async load({ filterText, signal }) { if (!filterText) return { items: [] } await new Promise((resolve) => setTimeout(resolve, 300)) if (signal?.aborted) return { items: [] } const items = allMovies.filter( (movie) => movie.title.toLowerCase().includes(filterText.toLowerCase()) || movie.director.toLowerCase().includes(filterText.toLowerCase()) || movie.genre.toLowerCase().includes(filterText.toLowerCase()), ) return { items } }, }) const collection = createListCollection({ items: list.items, itemToString: (item) => item.title, itemToValue: (item) => item.id, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { if (details.reason === 'input-change') { startTransition(() => { list.setFilterText(details.inputValue) }) } } return ( Movie
                    {list.loading ? (
                    Searching...
                    ) : list.error ? (
                    {list.error.message}
                    ) : list.items.length === 0 ? (
                    {list.filterText ? 'No results found' : 'Start typing to search movies...'}
                    ) : ( collection.items.map((movie) => ( {movie.title} {movie.year} · {movie.director} )) )}
                    ) } const allMovies: Movie[] = [ { id: 'inception', title: 'Inception', year: 2010, director: 'Christopher Nolan', genre: 'Sci-Fi' }, { id: 'the-dark-knight', title: 'The Dark Knight', year: 2008, director: 'Christopher Nolan', genre: 'Action' }, { id: 'pulp-fiction', title: 'Pulp Fiction', year: 1994, director: 'Quentin Tarantino', genre: 'Crime' }, { id: 'the-godfather', title: 'The Godfather', year: 1972, director: 'Francis Ford Coppola', genre: 'Crime' }, { id: 'forrest-gump', title: 'Forrest Gump', year: 1994, director: 'Robert Zemeckis', genre: 'Drama' }, { id: 'the-matrix', title: 'The Matrix', year: 1999, director: 'The Wachowskis', genre: 'Sci-Fi' }, { id: 'interstellar', title: 'Interstellar', year: 2014, director: 'Christopher Nolan', genre: 'Sci-Fi' }, { id: 'parasite', title: 'Parasite', year: 2019, director: 'Bong Joon-ho', genre: 'Thriller' }, { id: 'the-shawshank-redemption', title: 'The Shawshank Redemption', year: 1994, director: 'Frank Darabont', genre: 'Drama', }, { id: 'fight-club', title: 'Fight Club', year: 1999, director: 'David Fincher', genre: 'Drama' }, { id: 'goodfellas', title: 'Goodfellas', year: 1990, director: 'Martin Scorsese', genre: 'Crime' }, { id: 'the-silence-of-the-lambs', title: 'The Silence of the Lambs', year: 1991, director: 'Jonathan Demme', genre: 'Thriller', }, ] ``` ### 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. **Example: virtualized** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { useVirtualizer } from '@tanstack/react-virtual' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import { useRef } from 'react' import { flushSync } from 'react-dom' import styles from 'styles/combobox.module.css' export const Virtualized = () => { const contentRef = useRef(null) const { startsWith } = useFilter({ sensitivity: 'base' }) const { collection, filter, reset } = useListCollection({ initialItems: countries, filter: startsWith, }) const virtualizer = useVirtualizer({ count: collection.size, getScrollElement: () => contentRef.current, estimateSize: () => 32, overscan: 10, }) const handleScrollToIndex: Combobox.RootProps['scrollToIndexFn'] = (details) => { flushSync(() => { virtualizer.scrollToIndex(details.index, { align: 'center', behavior: 'auto', }) }) } const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {virtualizer.getVirtualItems().map((virtualItem) => { const item = collection.items[virtualItem.index] return ( {item.emoji} {item.label} ) })}
                    ) } interface Country { value: string label: string emoji: string } const countries: Country[] = [ { value: 'AD', label: 'Andorra', emoji: '🇦🇩' }, { value: 'AE', label: 'United Arab Emirates', emoji: '🇦🇪' }, { value: 'AF', label: 'Afghanistan', emoji: '🇦🇫' }, { value: 'AG', label: 'Antigua and Barbuda', emoji: '🇦🇬' }, { value: 'AI', label: 'Anguilla', emoji: '🇦🇮' }, { value: 'AL', label: 'Albania', emoji: '🇦🇱' }, { value: 'AM', label: 'Armenia', emoji: '🇦🇲' }, { value: 'AO', label: 'Angola', emoji: '🇦🇴' }, { value: 'AQ', label: 'Antarctica', emoji: '🇦🇶' }, { value: 'AR', label: 'Argentina', emoji: '🇦🇷' }, { value: 'AS', label: 'American Samoa', emoji: '🇦🇸' }, { value: 'AT', label: 'Austria', emoji: '🇦🇹' }, { value: 'AU', label: 'Australia', emoji: '🇦🇺' }, { value: 'AW', label: 'Aruba', emoji: '🇦🇼' }, { value: 'AX', label: 'Åland Islands', emoji: '🇦🇽' }, { value: 'AZ', label: 'Azerbaijan', emoji: '🇦🇿' }, { value: 'BA', label: 'Bosnia and Herzegovina', emoji: '🇧🇦' }, { value: 'BB', label: 'Barbados', emoji: '🇧🇧' }, { value: 'BD', label: 'Bangladesh', emoji: '🇧🇩' }, { value: 'BE', label: 'Belgium', emoji: '🇧🇪' }, { value: 'BF', label: 'Burkina Faso', emoji: '🇧🇫' }, { value: 'BG', label: 'Bulgaria', emoji: '🇧🇬' }, { value: 'BH', label: 'Bahrain', emoji: '🇧🇭' }, { value: 'BI', label: 'Burundi', emoji: '🇧🇮' }, { value: 'BJ', label: 'Benin', emoji: '🇧🇯' }, { value: 'BL', label: 'Saint Barthélemy', emoji: '🇧🇱' }, { value: 'BM', label: 'Bermuda', emoji: '🇧🇲' }, { value: 'BN', label: 'Brunei', emoji: '🇧🇳' }, { value: 'BO', label: 'Bolivia', emoji: '🇧🇴' }, { value: 'BR', label: 'Brazil', emoji: '🇧🇷' }, { value: 'BS', label: 'Bahamas', emoji: '🇧🇸' }, { value: 'BT', label: 'Bhutan', emoji: '🇧🇹' }, { value: 'BW', label: 'Botswana', emoji: '🇧🇼' }, { value: 'BY', label: 'Belarus', emoji: '🇧🇾' }, { value: 'BZ', label: 'Belize', emoji: '🇧🇿' }, { value: 'CA', label: 'Canada', emoji: '🇨🇦' }, { value: 'CD', label: 'Congo', emoji: '🇨🇩' }, { value: 'CF', label: 'Central African Republic', emoji: '🇨🇫' }, { value: 'CH', label: 'Switzerland', emoji: '🇨🇭' }, { value: 'CI', label: "Côte d'Ivoire", emoji: '🇨🇮' }, { value: 'CK', label: 'Cook Islands', emoji: '🇨🇰' }, { value: 'CL', label: 'Chile', emoji: '🇨🇱' }, { value: 'CM', label: 'Cameroon', emoji: '🇨🇲' }, { value: 'CN', label: 'China', emoji: '🇨🇳' }, { value: 'CO', label: 'Colombia', emoji: '🇨🇴' }, { value: 'CR', label: 'Costa Rica', emoji: '🇨🇷' }, { value: 'CU', label: 'Cuba', emoji: '🇨🇺' }, { value: 'CV', label: 'Cabo Verde', emoji: '🇨🇻' }, { value: 'CY', label: 'Cyprus', emoji: '🇨🇾' }, { value: 'CZ', label: 'Czech Republic', emoji: '🇨🇿' }, { value: 'DE', label: 'Germany', emoji: '🇩🇪' }, { value: 'DJ', label: 'Djibouti', emoji: '🇩🇯' }, { value: 'DK', label: 'Denmark', emoji: '🇩🇰' }, { value: 'DM', label: 'Dominica', emoji: '🇩🇲' }, { value: 'DO', label: 'Dominican Republic', emoji: '🇩🇴' }, { value: 'DZ', label: 'Algeria', emoji: '🇩🇿' }, { value: 'EC', label: 'Ecuador', emoji: '🇪🇨' }, { value: 'EE', label: 'Estonia', emoji: '🇪🇪' }, { value: 'EG', label: 'Egypt', emoji: '🇪🇬' }, { value: 'ER', label: 'Eritrea', emoji: '🇪🇷' }, { value: 'ES', label: 'Spain', emoji: '🇪🇸' }, { value: 'ET', label: 'Ethiopia', emoji: '🇪🇹' }, { value: 'FI', label: 'Finland', emoji: '🇫🇮' }, { value: 'FJ', label: 'Fiji', emoji: '🇫🇯' }, { value: 'FK', label: 'Falkland Islands', emoji: '🇫🇰' }, { value: 'FM', label: 'Micronesia', emoji: '🇫🇲' }, { value: 'FO', label: 'Faroe Islands', emoji: '🇫🇴' }, { value: 'FR', label: 'France', emoji: '🇫🇷' }, { value: 'GA', label: 'Gabon', emoji: '🇬🇦' }, { value: 'GB', label: 'United Kingdom', emoji: '🇬🇧' }, { value: 'GD', label: 'Grenada', emoji: '🇬🇩' }, { value: 'GE', label: 'Georgia', emoji: '🇬🇪' }, { value: 'GH', label: 'Ghana', emoji: '🇬🇭' }, { value: 'GI', label: 'Gibraltar', emoji: '🇬🇮' }, { value: 'GL', label: 'Greenland', emoji: '🇬🇱' }, { value: 'GM', label: 'Gambia', emoji: '🇬🇲' }, { value: 'GN', label: 'Guinea', emoji: '🇬🇳' }, { value: 'GQ', label: 'Equatorial Guinea', emoji: '🇬🇶' }, { value: 'GR', label: 'Greece', emoji: '🇬🇷' }, { value: 'GT', label: 'Guatemala', emoji: '🇬🇹' }, { value: 'GU', label: 'Guam', emoji: '🇬🇺' }, { value: 'GW', label: 'Guinea-Bissau', emoji: '🇬🇼' }, { value: 'GY', label: 'Guyana', emoji: '🇬🇾' }, { value: 'HK', label: 'Hong Kong', emoji: '🇭🇰' }, { value: 'HN', label: 'Honduras', emoji: '🇭🇳' }, { value: 'HR', label: 'Croatia', emoji: '🇭🇷' }, { value: 'HT', label: 'Haiti', emoji: '🇭🇹' }, { value: 'HU', label: 'Hungary', emoji: '🇭🇺' }, { value: 'ID', label: 'Indonesia', emoji: '🇮🇩' }, { value: 'IE', label: 'Ireland', emoji: '🇮🇪' }, { value: 'IL', label: 'Israel', emoji: '🇮🇱' }, { value: 'IM', label: 'Isle of Man', emoji: '🇮🇲' }, { value: 'IN', label: 'India', emoji: '🇮🇳' }, { value: 'IQ', label: 'Iraq', emoji: '🇮🇶' }, { value: 'IR', label: 'Iran', emoji: '🇮🇷' }, { value: 'IS', label: 'Iceland', emoji: '🇮🇸' }, { value: 'IT', label: 'Italy', emoji: '🇮🇹' }, { value: 'JE', label: 'Jersey', emoji: '🇯🇪' }, { value: 'JM', label: 'Jamaica', emoji: '🇯🇲' }, { value: 'JO', label: 'Jordan', emoji: '🇯🇴' }, { value: 'JP', label: 'Japan', emoji: '🇯🇵' }, { value: 'KE', label: 'Kenya', emoji: '🇰🇪' }, { value: 'KG', label: 'Kyrgyzstan', emoji: '🇰🇬' }, { value: 'KH', label: 'Cambodia', emoji: '🇰🇭' }, { value: 'KI', label: 'Kiribati', emoji: '🇰🇮' }, { value: 'KM', label: 'Comoros', emoji: '🇰🇲' }, { value: 'KN', label: 'Saint Kitts and Nevis', emoji: '🇰🇳' }, { value: 'KP', label: 'North Korea', emoji: '🇰🇵' }, { value: 'KR', label: 'South Korea', emoji: '🇰🇷' }, { value: 'KW', label: 'Kuwait', emoji: '🇰🇼' }, { value: 'KY', label: 'Cayman Islands', emoji: '🇰🇾' }, { value: 'KZ', label: 'Kazakhstan', emoji: '🇰🇿' }, { value: 'LA', label: 'Laos', emoji: '🇱🇦' }, { value: 'LB', label: 'Lebanon', emoji: '🇱🇧' }, { value: 'LC', label: 'Saint Lucia', emoji: '🇱🇨' }, { value: 'LI', label: 'Liechtenstein', emoji: '🇱🇮' }, { value: 'LK', label: 'Sri Lanka', emoji: '🇱🇰' }, { value: 'LR', label: 'Liberia', emoji: '🇱🇷' }, { value: 'LS', label: 'Lesotho', emoji: '🇱🇸' }, { value: 'LT', label: 'Lithuania', emoji: '🇱🇹' }, { value: 'LU', label: 'Luxembourg', emoji: '🇱🇺' }, { value: 'LV', label: 'Latvia', emoji: '🇱🇻' }, { value: 'LY', label: 'Libya', emoji: '🇱🇾' }, { value: 'MA', label: 'Morocco', emoji: '🇲🇦' }, { value: 'MC', label: 'Monaco', emoji: '🇲🇨' }, { value: 'MD', label: 'Moldova', emoji: '🇲🇩' }, { value: 'ME', label: 'Montenegro', emoji: '🇲🇪' }, { value: 'MG', label: 'Madagascar', emoji: '🇲🇬' }, { value: 'MH', label: 'Marshall Islands', emoji: '🇲🇭' }, { value: 'MK', label: 'North Macedonia', emoji: '🇲🇰' }, { value: 'ML', label: 'Mali', emoji: '🇲🇱' }, { value: 'MM', label: 'Myanmar', emoji: '🇲🇲' }, { value: 'MN', label: 'Mongolia', emoji: '🇲🇳' }, { value: 'MO', label: 'Macao', emoji: '🇲🇴' }, { value: 'MR', label: 'Mauritania', emoji: '🇲🇷' }, { value: 'MS', label: 'Montserrat', emoji: '🇲🇸' }, { value: 'MT', label: 'Malta', emoji: '🇲🇹' }, { value: 'MU', label: 'Mauritius', emoji: '🇲🇺' }, { value: 'MV', label: 'Maldives', emoji: '🇲🇻' }, { value: 'MW', label: 'Malawi', emoji: '🇲🇼' }, { value: 'MX', label: 'Mexico', emoji: '🇲🇽' }, { value: 'MY', label: 'Malaysia', emoji: '🇲🇾' }, { value: 'MZ', label: 'Mozambique', emoji: '🇲🇿' }, { value: 'NA', label: 'Namibia', emoji: '🇳🇦' }, { value: 'NC', label: 'New Caledonia', emoji: '🇳🇨' }, { value: 'NE', label: 'Niger', emoji: '🇳🇪' }, { value: 'NF', label: 'Norfolk Island', emoji: '🇳🇫' }, { value: 'NG', label: 'Nigeria', emoji: '🇳🇬' }, { value: 'NI', label: 'Nicaragua', emoji: '🇳🇮' }, { value: 'NL', label: 'Netherlands', emoji: '🇳🇱' }, { value: 'NO', label: 'Norway', emoji: '🇳🇴' }, { value: 'NP', label: 'Nepal', emoji: '🇳🇵' }, { value: 'NR', label: 'Nauru', emoji: '🇳🇷' }, { value: 'NU', label: 'Niue', emoji: '🇳🇺' }, { value: 'NZ', label: 'New Zealand', emoji: '🇳🇿' }, { value: 'OM', label: 'Oman', emoji: '🇴🇲' }, { value: 'PA', label: 'Panama', emoji: '🇵🇦' }, { value: 'PE', label: 'Peru', emoji: '🇵🇪' }, { value: 'PF', label: 'French Polynesia', emoji: '🇵🇫' }, { value: 'PG', label: 'Papua New Guinea', emoji: '🇵🇬' }, { value: 'PH', label: 'Philippines', emoji: '🇵🇭' }, { value: 'PK', label: 'Pakistan', emoji: '🇵🇰' }, { value: 'PL', label: 'Poland', emoji: '🇵🇱' }, { value: 'PR', label: 'Puerto Rico', emoji: '🇵🇷' }, { value: 'PS', label: 'Palestine', emoji: '🇵🇸' }, { value: 'PT', label: 'Portugal', emoji: '🇵🇹' }, { value: 'PW', label: 'Palau', emoji: '🇵🇼' }, { value: 'PY', label: 'Paraguay', emoji: '🇵🇾' }, { value: 'QA', label: 'Qatar', emoji: '🇶🇦' }, { value: 'RO', label: 'Romania', emoji: '🇷🇴' }, { value: 'RS', label: 'Serbia', emoji: '🇷🇸' }, { value: 'RU', label: 'Russia', emoji: '🇷🇺' }, { value: 'RW', label: 'Rwanda', emoji: '🇷🇼' }, { value: 'SA', label: 'Saudi Arabia', emoji: '🇸🇦' }, { value: 'SB', label: 'Solomon Islands', emoji: '🇸🇧' }, { value: 'SC', label: 'Seychelles', emoji: '🇸🇨' }, { value: 'SD', label: 'Sudan', emoji: '🇸🇩' }, { value: 'SE', label: 'Sweden', emoji: '🇸🇪' }, { value: 'SG', label: 'Singapore', emoji: '🇸🇬' }, { value: 'SI', label: 'Slovenia', emoji: '🇸🇮' }, { value: 'SK', label: 'Slovakia', emoji: '🇸🇰' }, { value: 'SL', label: 'Sierra Leone', emoji: '🇸🇱' }, { value: 'SM', label: 'San Marino', emoji: '🇸🇲' }, { value: 'SN', label: 'Senegal', emoji: '🇸🇳' }, { value: 'SO', label: 'Somalia', emoji: '🇸🇴' }, { value: 'SR', label: 'Suriname', emoji: '🇸🇷' }, { value: 'SS', label: 'South Sudan', emoji: '🇸🇸' }, { value: 'ST', label: 'Sao Tome and Principe', emoji: '🇸🇹' }, { value: 'SV', label: 'El Salvador', emoji: '🇸🇻' }, { value: 'SY', label: 'Syria', emoji: '🇸🇾' }, { value: 'SZ', label: 'Eswatini', emoji: '🇸🇿' }, { value: 'TC', label: 'Turks and Caicos Islands', emoji: '🇹🇨' }, { value: 'TD', label: 'Chad', emoji: '🇹🇩' }, { value: 'TG', label: 'Togo', emoji: '🇹🇬' }, { value: 'TH', label: 'Thailand', emoji: '🇹🇭' }, { value: 'TJ', label: 'Tajikistan', emoji: '🇹🇯' }, { value: 'TK', label: 'Tokelau', emoji: '🇹🇰' }, { value: 'TL', label: 'Timor-Leste', emoji: '🇹🇱' }, { value: 'TM', label: 'Turkmenistan', emoji: '🇹🇲' }, { value: 'TN', label: 'Tunisia', emoji: '🇹🇳' }, { value: 'TO', label: 'Tonga', emoji: '🇹🇴' }, { value: 'TR', label: 'Türkiye', emoji: '🇹🇷' }, { value: 'TT', label: 'Trinidad and Tobago', emoji: '🇹🇹' }, { value: 'TV', label: 'Tuvalu', emoji: '🇹🇻' }, { value: 'TW', label: 'Taiwan', emoji: '🇹🇼' }, { value: 'TZ', label: 'Tanzania', emoji: '🇹🇿' }, { value: 'UA', label: 'Ukraine', emoji: '🇺🇦' }, { value: 'UG', label: 'Uganda', emoji: '🇺🇬' }, { value: 'US', label: 'United States', emoji: '🇺🇸' }, { value: 'UY', label: 'Uruguay', emoji: '🇺🇾' }, { value: 'UZ', label: 'Uzbekistan', emoji: '🇺🇿' }, { value: 'VA', label: 'Vatican City', emoji: '🇻🇦' }, { value: 'VC', label: 'Saint Vincent and the Grenadines', emoji: '🇻🇨' }, { value: 'VE', label: 'Venezuela', emoji: '🇻🇪' }, { value: 'VG', label: 'British Virgin Islands', emoji: '🇻🇬' }, { value: 'VI', label: 'U.S. Virgin Islands', emoji: '🇻🇮' }, { value: 'VN', label: 'Vietnam', emoji: '🇻🇳' }, { value: 'VU', label: 'Vanuatu', emoji: '🇻🇺' }, { value: 'WF', label: 'Wallis and Futuna', emoji: '🇼🇫' }, { value: 'WS', label: 'Samoa', emoji: '🇼🇸' }, { value: 'YE', label: 'Yemen', emoji: '🇾🇪' }, { value: 'YT', label: 'Mayotte', emoji: '🇾🇹' }, { value: 'ZA', label: 'South Africa', emoji: '🇿🇦' }, { value: 'ZM', label: 'Zambia', emoji: '🇿🇲' }, { value: 'ZW', label: 'Zimbabwe', emoji: '🇿🇼' }, ] ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { createVirtualizer } from '@tanstack/solid-virtual' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const Virtualized = () => { let contentRef: HTMLDivElement | undefined const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter, reset } = useListCollection({ initialItems: countries, filter: filterFn().startsWith, }) const virtualizer = createVirtualizer({ get count() { return collection().size }, getScrollElement: () => contentRef ?? null, estimateSize: () => 32, overscan: 10, }) const handleScrollToIndex: Combobox.RootProps['scrollToIndexFn'] = (details) => { virtualizer.scrollToIndex(details.index, { align: 'center', behavior: 'auto', }) } const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {virtualizer.getVirtualItems().map((virtualItem) => { const item = collection().items[virtualItem.index] return ( {item.emoji} {item.label} ) })}
                    ) } interface Country { value: string label: string emoji: string } const countries: Country[] = [ { value: 'AD', label: 'Andorra', emoji: '🇦🇩' }, { value: 'AE', label: 'United Arab Emirates', emoji: '🇦🇪' }, { value: 'AF', label: 'Afghanistan', emoji: '🇦🇫' }, { value: 'AG', label: 'Antigua and Barbuda', emoji: '🇦🇬' }, { value: 'AI', label: 'Anguilla', emoji: '🇦🇮' }, { value: 'AL', label: 'Albania', emoji: '🇦🇱' }, { value: 'AM', label: 'Armenia', emoji: '🇦🇲' }, { value: 'AO', label: 'Angola', emoji: '🇦🇴' }, { value: 'AQ', label: 'Antarctica', emoji: '🇦🇶' }, { value: 'AR', label: 'Argentina', emoji: '🇦🇷' }, { value: 'AS', label: 'American Samoa', emoji: '🇦🇸' }, { value: 'AT', label: 'Austria', emoji: '🇦🇹' }, { value: 'AU', label: 'Australia', emoji: '🇦🇺' }, { value: 'AW', label: 'Aruba', emoji: '🇦🇼' }, { value: 'AX', label: 'Åland Islands', emoji: '🇦🇽' }, { value: 'AZ', label: 'Azerbaijan', emoji: '🇦🇿' }, { value: 'BA', label: 'Bosnia and Herzegovina', emoji: '🇧🇦' }, { value: 'BB', label: 'Barbados', emoji: '🇧🇧' }, { value: 'BD', label: 'Bangladesh', emoji: '🇧🇩' }, { value: 'BE', label: 'Belgium', emoji: '🇧🇪' }, { value: 'BF', label: 'Burkina Faso', emoji: '🇧🇫' }, { value: 'BG', label: 'Bulgaria', emoji: '🇧🇬' }, { value: 'BH', label: 'Bahrain', emoji: '🇧🇭' }, { value: 'BI', label: 'Burundi', emoji: '🇧🇮' }, { value: 'BJ', label: 'Benin', emoji: '🇧🇯' }, { value: 'BL', label: 'Saint Barthélemy', emoji: '🇧🇱' }, { value: 'BM', label: 'Bermuda', emoji: '🇧🇲' }, { value: 'BN', label: 'Brunei', emoji: '🇧🇳' }, { value: 'BO', label: 'Bolivia', emoji: '🇧🇴' }, { value: 'BR', label: 'Brazil', emoji: '🇧🇷' }, { value: 'BS', label: 'Bahamas', emoji: '🇧🇸' }, { value: 'BT', label: 'Bhutan', emoji: '🇧🇹' }, { value: 'BW', label: 'Botswana', emoji: '🇧🇼' }, { value: 'BY', label: 'Belarus', emoji: '🇧🇾' }, { value: 'BZ', label: 'Belize', emoji: '🇧🇿' }, { value: 'CA', label: 'Canada', emoji: '🇨🇦' }, { value: 'CD', label: 'Congo', emoji: '🇨🇩' }, { value: 'CF', label: 'Central African Republic', emoji: '🇨🇫' }, { value: 'CH', label: 'Switzerland', emoji: '🇨🇭' }, { value: 'CI', label: "Côte d'Ivoire", emoji: '🇨🇮' }, { value: 'CK', label: 'Cook Islands', emoji: '🇨🇰' }, { value: 'CL', label: 'Chile', emoji: '🇨🇱' }, { value: 'CM', label: 'Cameroon', emoji: '🇨🇲' }, { value: 'CN', label: 'China', emoji: '🇨🇳' }, { value: 'CO', label: 'Colombia', emoji: '🇨🇴' }, { value: 'CR', label: 'Costa Rica', emoji: '🇨🇷' }, { value: 'CU', label: 'Cuba', emoji: '🇨🇺' }, { value: 'CV', label: 'Cabo Verde', emoji: '🇨🇻' }, { value: 'CY', label: 'Cyprus', emoji: '🇨🇾' }, { value: 'CZ', label: 'Czech Republic', emoji: '🇨🇿' }, { value: 'DE', label: 'Germany', emoji: '🇩🇪' }, { value: 'DJ', label: 'Djibouti', emoji: '🇩🇯' }, { value: 'DK', label: 'Denmark', emoji: '🇩🇰' }, { value: 'DM', label: 'Dominica', emoji: '🇩🇲' }, { value: 'DO', label: 'Dominican Republic', emoji: '🇩🇴' }, { value: 'DZ', label: 'Algeria', emoji: '🇩🇿' }, { value: 'EC', label: 'Ecuador', emoji: '🇪🇨' }, { value: 'EE', label: 'Estonia', emoji: '🇪🇪' }, { value: 'EG', label: 'Egypt', emoji: '🇪🇬' }, { value: 'ER', label: 'Eritrea', emoji: '🇪🇷' }, { value: 'ES', label: 'Spain', emoji: '🇪🇸' }, { value: 'ET', label: 'Ethiopia', emoji: '🇪🇹' }, { value: 'FI', label: 'Finland', emoji: '🇫🇮' }, { value: 'FJ', label: 'Fiji', emoji: '🇫🇯' }, { value: 'FK', label: 'Falkland Islands', emoji: '🇫🇰' }, { value: 'FM', label: 'Micronesia', emoji: '🇫🇲' }, { value: 'FO', label: 'Faroe Islands', emoji: '🇫🇴' }, { value: 'FR', label: 'France', emoji: '🇫🇷' }, { value: 'GA', label: 'Gabon', emoji: '🇬🇦' }, { value: 'GB', label: 'United Kingdom', emoji: '🇬🇧' }, { value: 'GD', label: 'Grenada', emoji: '🇬🇩' }, { value: 'GE', label: 'Georgia', emoji: '🇬🇪' }, { value: 'GH', label: 'Ghana', emoji: '🇬🇭' }, { value: 'GI', label: 'Gibraltar', emoji: '🇬🇮' }, { value: 'GL', label: 'Greenland', emoji: '🇬🇱' }, { value: 'GM', label: 'Gambia', emoji: '🇬🇲' }, { value: 'GN', label: 'Guinea', emoji: '🇬🇳' }, { value: 'GQ', label: 'Equatorial Guinea', emoji: '🇬🇶' }, { value: 'GR', label: 'Greece', emoji: '🇬🇷' }, { value: 'GT', label: 'Guatemala', emoji: '🇬🇹' }, { value: 'GU', label: 'Guam', emoji: '🇬🇺' }, { value: 'GW', label: 'Guinea-Bissau', emoji: '🇬🇼' }, { value: 'GY', label: 'Guyana', emoji: '🇬🇾' }, { value: 'HK', label: 'Hong Kong', emoji: '🇭🇰' }, { value: 'HN', label: 'Honduras', emoji: '🇭🇳' }, { value: 'HR', label: 'Croatia', emoji: '🇭🇷' }, { value: 'HT', label: 'Haiti', emoji: '🇭🇹' }, { value: 'HU', label: 'Hungary', emoji: '🇭🇺' }, { value: 'ID', label: 'Indonesia', emoji: '🇮🇩' }, { value: 'IE', label: 'Ireland', emoji: '🇮🇪' }, { value: 'IL', label: 'Israel', emoji: '🇮🇱' }, { value: 'IM', label: 'Isle of Man', emoji: '🇮🇲' }, { value: 'IN', label: 'India', emoji: '🇮🇳' }, { value: 'IQ', label: 'Iraq', emoji: '🇮🇶' }, { value: 'IR', label: 'Iran', emoji: '🇮🇷' }, { value: 'IS', label: 'Iceland', emoji: '🇮🇸' }, { value: 'IT', label: 'Italy', emoji: '🇮🇹' }, { value: 'JE', label: 'Jersey', emoji: '🇯🇪' }, { value: 'JM', label: 'Jamaica', emoji: '🇯🇲' }, { value: 'JO', label: 'Jordan', emoji: '🇯🇴' }, { value: 'JP', label: 'Japan', emoji: '🇯🇵' }, { value: 'KE', label: 'Kenya', emoji: '🇰🇪' }, { value: 'KG', label: 'Kyrgyzstan', emoji: '🇰🇬' }, { value: 'KH', label: 'Cambodia', emoji: '🇰🇭' }, { value: 'KI', label: 'Kiribati', emoji: '🇰🇮' }, { value: 'KM', label: 'Comoros', emoji: '🇰🇲' }, { value: 'KN', label: 'Saint Kitts and Nevis', emoji: '🇰🇳' }, { value: 'KP', label: 'North Korea', emoji: '🇰🇵' }, { value: 'KR', label: 'South Korea', emoji: '🇰🇷' }, { value: 'KW', label: 'Kuwait', emoji: '🇰🇼' }, { value: 'KY', label: 'Cayman Islands', emoji: '🇰🇾' }, { value: 'KZ', label: 'Kazakhstan', emoji: '🇰🇿' }, { value: 'LA', label: 'Laos', emoji: '🇱🇦' }, { value: 'LB', label: 'Lebanon', emoji: '🇱🇧' }, { value: 'LC', label: 'Saint Lucia', emoji: '🇱🇨' }, { value: 'LI', label: 'Liechtenstein', emoji: '🇱🇮' }, { value: 'LK', label: 'Sri Lanka', emoji: '🇱🇰' }, { value: 'LR', label: 'Liberia', emoji: '🇱🇷' }, { value: 'LS', label: 'Lesotho', emoji: '🇱🇸' }, { value: 'LT', label: 'Lithuania', emoji: '🇱🇹' }, { value: 'LU', label: 'Luxembourg', emoji: '🇱🇺' }, { value: 'LV', label: 'Latvia', emoji: '🇱🇻' }, { value: 'LY', label: 'Libya', emoji: '🇱🇾' }, { value: 'MA', label: 'Morocco', emoji: '🇲🇦' }, { value: 'MC', label: 'Monaco', emoji: '🇲🇨' }, { value: 'MD', label: 'Moldova', emoji: '🇲🇩' }, { value: 'ME', label: 'Montenegro', emoji: '🇲🇪' }, { value: 'MG', label: 'Madagascar', emoji: '🇲🇬' }, { value: 'MH', label: 'Marshall Islands', emoji: '🇲🇭' }, { value: 'MK', label: 'North Macedonia', emoji: '🇲🇰' }, { value: 'ML', label: 'Mali', emoji: '🇲🇱' }, { value: 'MM', label: 'Myanmar', emoji: '🇲🇲' }, { value: 'MN', label: 'Mongolia', emoji: '🇲🇳' }, { value: 'MO', label: 'Macao', emoji: '🇲🇴' }, { value: 'MR', label: 'Mauritania', emoji: '🇲🇷' }, { value: 'MS', label: 'Montserrat', emoji: '🇲🇸' }, { value: 'MT', label: 'Malta', emoji: '🇲🇹' }, { value: 'MU', label: 'Mauritius', emoji: '🇲🇺' }, { value: 'MV', label: 'Maldives', emoji: '🇲🇻' }, { value: 'MW', label: 'Malawi', emoji: '🇲🇼' }, { value: 'MX', label: 'Mexico', emoji: '🇲🇽' }, { value: 'MY', label: 'Malaysia', emoji: '🇲🇾' }, { value: 'MZ', label: 'Mozambique', emoji: '🇲🇿' }, { value: 'NA', label: 'Namibia', emoji: '🇳🇦' }, { value: 'NC', label: 'New Caledonia', emoji: '🇳🇨' }, { value: 'NE', label: 'Niger', emoji: '🇳🇪' }, { value: 'NF', label: 'Norfolk Island', emoji: '🇳🇫' }, { value: 'NG', label: 'Nigeria', emoji: '🇳🇬' }, { value: 'NI', label: 'Nicaragua', emoji: '🇳🇮' }, { value: 'NL', label: 'Netherlands', emoji: '🇳🇱' }, { value: 'NO', label: 'Norway', emoji: '🇳🇴' }, { value: 'NP', label: 'Nepal', emoji: '🇳🇵' }, { value: 'NR', label: 'Nauru', emoji: '🇳🇷' }, { value: 'NU', label: 'Niue', emoji: '🇳🇺' }, { value: 'NZ', label: 'New Zealand', emoji: '🇳🇿' }, { value: 'OM', label: 'Oman', emoji: '🇴🇲' }, { value: 'PA', label: 'Panama', emoji: '🇵🇦' }, { value: 'PE', label: 'Peru', emoji: '🇵🇪' }, { value: 'PF', label: 'French Polynesia', emoji: '🇵🇫' }, { value: 'PG', label: 'Papua New Guinea', emoji: '🇵🇬' }, { value: 'PH', label: 'Philippines', emoji: '🇵🇭' }, { value: 'PK', label: 'Pakistan', emoji: '🇵🇰' }, { value: 'PL', label: 'Poland', emoji: '🇵🇱' }, { value: 'PR', label: 'Puerto Rico', emoji: '🇵🇷' }, { value: 'PS', label: 'Palestine', emoji: '🇵🇸' }, { value: 'PT', label: 'Portugal', emoji: '🇵🇹' }, { value: 'PW', label: 'Palau', emoji: '🇵🇼' }, { value: 'PY', label: 'Paraguay', emoji: '🇵🇾' }, { value: 'QA', label: 'Qatar', emoji: '🇶🇦' }, { value: 'RO', label: 'Romania', emoji: '🇷🇴' }, { value: 'RS', label: 'Serbia', emoji: '🇷🇸' }, { value: 'RU', label: 'Russia', emoji: '🇷🇺' }, { value: 'RW', label: 'Rwanda', emoji: '🇷🇼' }, { value: 'SA', label: 'Saudi Arabia', emoji: '🇸🇦' }, { value: 'SB', label: 'Solomon Islands', emoji: '🇸🇧' }, { value: 'SC', label: 'Seychelles', emoji: '🇸🇨' }, { value: 'SD', label: 'Sudan', emoji: '🇸🇩' }, { value: 'SE', label: 'Sweden', emoji: '🇸🇪' }, { value: 'SG', label: 'Singapore', emoji: '🇸🇬' }, { value: 'SI', label: 'Slovenia', emoji: '🇸🇮' }, { value: 'SK', label: 'Slovakia', emoji: '🇸🇰' }, { value: 'SL', label: 'Sierra Leone', emoji: '🇸🇱' }, { value: 'SM', label: 'San Marino', emoji: '🇸🇲' }, { value: 'SN', label: 'Senegal', emoji: '🇸🇳' }, { value: 'SO', label: 'Somalia', emoji: '🇸🇴' }, { value: 'SR', label: 'Suriname', emoji: '🇸🇷' }, { value: 'SS', label: 'South Sudan', emoji: '🇸🇸' }, { value: 'ST', label: 'Sao Tome and Principe', emoji: '🇸🇹' }, { value: 'SV', label: 'El Salvador', emoji: '🇸🇻' }, { value: 'SY', label: 'Syria', emoji: '🇸🇾' }, { value: 'SZ', label: 'Eswatini', emoji: '🇸🇿' }, { value: 'TC', label: 'Turks and Caicos Islands', emoji: '🇹🇨' }, { value: 'TD', label: 'Chad', emoji: '🇹🇩' }, { value: 'TG', label: 'Togo', emoji: '🇹🇬' }, { value: 'TH', label: 'Thailand', emoji: '🇹🇭' }, { value: 'TJ', label: 'Tajikistan', emoji: '🇹🇯' }, { value: 'TK', label: 'Tokelau', emoji: '🇹🇰' }, { value: 'TL', label: 'Timor-Leste', emoji: '🇹🇱' }, { value: 'TM', label: 'Turkmenistan', emoji: '🇹🇲' }, { value: 'TN', label: 'Tunisia', emoji: '🇹🇳' }, { value: 'TO', label: 'Tonga', emoji: '🇹🇴' }, { value: 'TR', label: 'Türkiye', emoji: '🇹🇷' }, { value: 'TT', label: 'Trinidad and Tobago', emoji: '🇹🇹' }, { value: 'TV', label: 'Tuvalu', emoji: '🇹🇻' }, { value: 'TW', label: 'Taiwan', emoji: '🇹🇼' }, { value: 'TZ', label: 'Tanzania', emoji: '🇹🇿' }, { value: 'UA', label: 'Ukraine', emoji: '🇺🇦' }, { value: 'UG', label: 'Uganda', emoji: '🇺🇬' }, { value: 'US', label: 'United States', emoji: '🇺🇸' }, { value: 'UY', label: 'Uruguay', emoji: '🇺🇾' }, { value: 'UZ', label: 'Uzbekistan', emoji: '🇺🇿' }, { value: 'VA', label: 'Vatican City', emoji: '🇻🇦' }, { value: 'VC', label: 'Saint Vincent and the Grenadines', emoji: '🇻🇨' }, { value: 'VE', label: 'Venezuela', emoji: '🇻🇪' }, { value: 'VG', label: 'British Virgin Islands', emoji: '🇻🇬' }, { value: 'VI', label: 'U.S. Virgin Islands', emoji: '🇻🇮' }, { value: 'VN', label: 'Vietnam', emoji: '🇻🇳' }, { value: 'VU', label: 'Vanuatu', emoji: '🇻🇺' }, { value: 'WF', label: 'Wallis and Futuna', emoji: '🇼🇫' }, { value: 'WS', label: 'Samoa', emoji: '🇼🇸' }, { value: 'YE', label: 'Yemen', emoji: '🇾🇪' }, { value: 'YT', label: 'Mayotte', emoji: '🇾🇹' }, { value: 'ZA', label: 'South Africa', emoji: '🇿🇦' }, { value: 'ZM', label: 'Zambia', emoji: '🇿🇲' }, { value: 'ZW', label: 'Zimbabwe', emoji: '🇿🇼' }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte Country
                    Open
                    {#each $virtualizer.getVirtualItems() as virtualItem (virtualItem.key)} {@const item = collection().items[virtualItem.index]} {item.label} {/each}
                    ``` ### Custom Object Use the `itemToString` and `itemToValue` props to map custom objects to the required interface. **Example: custom-object** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' export const CustomObject = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { country: 'United States', code: 'US', flag: '🇺🇸' }, { country: 'Canada', code: 'CA', flag: '🇨🇦' }, { country: 'Australia', code: 'AU', flag: '🇦🇺' }, ], itemToString: (item) => item.country, itemToValue: (item) => item.code, filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    {collection.items.map((item) => ( {item.flag} {item.country} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' export const CustomObject = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: [ { country: 'United States', code: 'US', flag: '🇺🇸' }, { country: 'Canada', code: 'CA', flag: '🇨🇦' }, { country: 'Australia', code: 'AU', flag: '🇦🇺' }, ], itemToString: (item) => item.country, itemToValue: (item) => item.code, filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( Country
                    Clear Open
                    {(item) => ( {item.flag} {item.country} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Country
                    Clear Open
                    {#each collection().items as item (item.code)} {item.flag} {item.country} {/each}
                    ``` ### Limit Results Use the `limit` property on `useListCollection` to limit the number of rendered items in the DOM. **Example: limit-results** #### React ```tsx import { Combobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { CheckIcon, ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/combobox.module.css' const cities = [ { label: 'New York', value: 'new-york' }, { label: 'Los Angeles', value: 'los-angeles' }, { label: 'Chicago', value: 'chicago' }, { label: 'Houston', value: 'houston' }, { label: 'Phoenix', value: 'phoenix' }, { label: 'Philadelphia', value: 'philadelphia' }, { label: 'San Antonio', value: 'san-antonio' }, { label: 'San Diego', value: 'san-diego' }, { label: 'Dallas', value: 'dallas' }, { label: 'San Jose', value: 'san-jose' }, { label: 'Austin', value: 'austin' }, { label: 'Jacksonville', value: 'jacksonville' }, { label: 'Fort Worth', value: 'fort-worth' }, { label: 'Columbus', value: 'columbus' }, { label: 'Charlotte', value: 'charlotte' }, { label: 'San Francisco', value: 'san-francisco' }, { label: 'Indianapolis', value: 'indianapolis' }, { label: 'Seattle', value: 'seattle' }, { label: 'Denver', value: 'denver' }, { label: 'Boston', value: 'boston' }, ] export const LimitResults = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: cities, limit: 5, filter: contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( City
                    {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Combobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { For } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/combobox.module.css' const cities = [ { label: 'New York', value: 'new-york' }, { label: 'Los Angeles', value: 'los-angeles' }, { label: 'Chicago', value: 'chicago' }, { label: 'Houston', value: 'houston' }, { label: 'Phoenix', value: 'phoenix' }, { label: 'Philadelphia', value: 'philadelphia' }, { label: 'San Antonio', value: 'san-antonio' }, { label: 'San Diego', value: 'san-diego' }, { label: 'Dallas', value: 'dallas' }, { label: 'San Jose', value: 'san-jose' }, { label: 'Austin', value: 'austin' }, { label: 'Jacksonville', value: 'jacksonville' }, { label: 'Fort Worth', value: 'fort-worth' }, { label: 'Columbus', value: 'columbus' }, { label: 'Charlotte', value: 'charlotte' }, { label: 'San Francisco', value: 'san-francisco' }, { label: 'Indianapolis', value: 'indianapolis' }, { label: 'Seattle', value: 'seattle' }, { label: 'Denver', value: 'denver' }, { label: 'Boston', value: 'boston' }, ] export const LimitResults = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: cities, limit: 5, filter: filterFn().contains, }) const handleInputChange = (details: Combobox.InputValueChangeDetails) => { filter(details.inputValue) } return ( City
                    Open
                    {(item) => ( {item.label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte City
                    Open
                    {#each collection().items as item (item.value)} {item.label} {/each}
                    ``` ## Guides ### Router Links Customize the `navigate` prop on `Combobox.Root` to integrate with your router. Using Tanstack Router: ```tsx import { Combobox } from '@ark-ui//combobox' import { useNavigate } from '@tanstack/react-router' function Demo() { const navigate = useNavigate() return ( { navigate({ to: e.node.href }) }} > {/* ... */} ) } ``` ### Custom Objects By default, the combobox collection expects an array of objects with `label` and `value` properties. In some cases, you may need to deal with custom objects. Use the `itemToString` and `itemToValue` props to map the custom object to the required interface. ```tsx const items = [ { country: 'United States', code: 'US', flag: '🇺🇸' }, { country: 'Canada', code: 'CA', flag: '🇨🇦' }, { country: 'Australia', code: 'AU', flag: '🇦🇺' }, // ... ] const { collection } = useListCollection({ initialItems: items, itemToString: (item) => item.country, itemToValue: (item) => item.code, }) ``` ### Type Safety The `Combobox.RootComponent` type enables you to create typed wrapper components that maintain full type safety for collection items. ```tsx const Combobox: ArkCombobox.RootComponent = (props) => { return {/* ... */} } ``` Use the wrapper with full type inference on `onValueChange` and other callbacks: ```tsx const App = () => { const { collection } = useListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, ], }) return ( { // e.items is typed as Array<{ label: string, value: string }> console.log(e.items) }} > {/* ... */} ) } ``` ### Large Datasets The recommended way of managing large lists is to use the `limit` property on the `useListCollection` hook. This will limit the number of rendered items in the DOM to improve performance. ```tsx {3} const { collection } = useListCollection({ initialItems: items, limit: 10, }) ``` ### Available Size The following css variables are exposed to the `Combobox.Positioner` which you can use to style the `Combobox.Content` ```css /* width of the combobox control */ --reference-width: ; /* width of the available viewport */ --available-width: ; /* height of the available viewport */ --available-height: ; ``` For example, if you want to make sure the maximum height doesn't exceed the available height, you can use the following: ```css [data-scope='combobox'][data-part='content'] { max-height: calc(var(--available-height) - 100px); } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input | | `alwaysSubmitOnEnter` | `boolean` | No | Whether to always submit on Enter key press, even if popup is open. Useful for single-field autocomplete forms where Enter should submit the form. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the input on mount | | `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. | | `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. | | `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. | | `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. | | `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. | | `disabled` | `boolean` | No | Whether the combobox is disabled | | `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer | | `form` | `string` | No | The associate form of the combobox. | | `highlightedValue` | `string` | No | The controlled highlighted value of the combobox | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string control: string input: string content: string trigger: string clearTrigger: string item: (id: string, index?: number | undefined) => string positioner: string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the combobox. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inputBehavior` | `'none' | 'autohighlight' | 'autocomplete'` | No | Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated | | `inputValue` | `string` | No | The controlled value of the combobox's input | | `invalid` | `boolean` | No | Whether the combobox is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items | | `multiple` | `boolean` | No | Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. | | `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when an item is highlighted using the pointer or keyboard navigation. | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Function called when the input's value changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when a new item is selected | | `open` | `boolean` | No | The controlled open state of the combobox | | `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes | | `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input | | `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press | | `placeholder` | `string` | No | The placeholder text of the combobox's input | | `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it | | `required` | `boolean` | No | Whether the combobox is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionBehavior` | `'clear' | 'replace' | 'preserve'` | No | The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the combobox's selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested comboboxs | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-autofocus]` | | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-group | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-value]` | The value of the item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | label | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | list | | `[data-empty]` | Present when the content is empty | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseComboboxReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `focusable` | `boolean` | No | Whether the trigger is focusable | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | | `[data-focusable]` | | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input | | `alwaysSubmitOnEnter` | `boolean` | No | Whether to always submit on Enter key press, even if popup is open. Useful for single-field autocomplete forms where Enter should submit the form. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the input on mount | | `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. | | `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. | | `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. | | `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. | | `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. | | `disabled` | `boolean` | No | Whether the combobox is disabled | | `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer | | `form` | `string` | No | The associate form of the combobox. | | `highlightedValue` | `string` | No | The controlled highlighted value of the combobox | | `ids` | `Partial<{ root: string label: string control: string input: string content: string trigger: string clearTrigger: string item: (id: string, index?: number | undefined) => string positioner: string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the combobox. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inputBehavior` | `'none' | 'autohighlight' | 'autocomplete'` | No | Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated | | `inputValue` | `string` | No | The controlled value of the combobox's input | | `invalid` | `boolean` | No | Whether the combobox is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items | | `multiple` | `boolean` | No | Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. | | `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when an item is highlighted using the pointer or keyboard navigation. | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Function called when the input's value changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when a new item is selected | | `open` | `boolean` | No | The controlled open state of the combobox | | `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes | | `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input | | `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press | | `placeholder` | `string` | No | The placeholder text of the combobox's input | | `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it | | `required` | `boolean` | No | Whether the combobox is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionBehavior` | `'replace' | 'clear' | 'preserve'` | No | The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the combobox's selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested comboboxs | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-autofocus]` | | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-group | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-value]` | The value of the item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | label | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | list | | `[data-empty]` | Present when the content is empty | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseComboboxReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `focusable` | `boolean` | No | Whether the trigger is focusable | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | | `[data-focusable]` | | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input | | `alwaysSubmitOnEnter` | `boolean` | No | Whether to allow bypassing the default two-step behavior (Enter to close combobox, then Enter to submit form) and instead submit the form immediately on Enter press. This is useful for single-field autocomplete forms where Enter should submit the form directly. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the input on mount | | `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. | | `collection` | `ListCollection` | No | The collection of items | | `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. | | `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. | | `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. | | `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. | | `disabled` | `boolean` | No | Whether the combobox is disabled | | `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer | | `form` | `string` | No | The associate form of the combobox. | | `highlightedValue` | `string` | No | The controlled highlighted value of the combobox | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string control: string input: string content: string trigger: string clearTrigger: string item(id: string, index?: number | undefined): string positioner: string itemGroup(id: string | number): string itemGroupLabel(id: string | number): string }>` | No | The ids of the elements in the combobox. Useful for composition. | | `inputBehavior` | `'none' | 'autohighlight' | 'autocomplete'` | No | Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated | | `inputValue` | `string` | No | The controlled value of the combobox's input | | `invalid` | `boolean` | No | Whether the combobox is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items | | `modelValue` | `string[]` | No | The v-model value of the combobox | | `multiple` | `boolean` | No | Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. | | `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item | | `open` | `boolean` | No | The controlled open state of the combobox | | `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes | | `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input | | `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press | | `placeholder` | `string` | No | The placeholder text of the combobox's input | | `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu | | `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it | | `required` | `boolean` | No | Whether the combobox is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionBehavior` | `'clear' | 'replace' | 'preserve'` | No | The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested comboboxs | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-autofocus]` | | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-group | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-value]` | The value of the item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | label | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | list | | `[data-empty]` | Present when the content is empty | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ComboboxApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `focusable` | `boolean` | No | Whether the trigger is focusable | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | | `[data-focusable]` | | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `MaybeFunction>` | Yes | The collection of items | | `allowCustomValue` | `boolean` | No | Whether to allow typing custom values in the input | | `alwaysSubmitOnEnter` | `boolean` | No | Whether to always submit on Enter key press, even if popup is open. Useful for single-field autocomplete forms where Enter should submit the form. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the input on mount | | `closeOnSelect` | `boolean` | No | Whether to close the combobox when an item is selected. | | `composite` | `boolean` | No | Whether the combobox is a composed with other composite widgets like tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. | | `defaultInputValue` | `string` | No | The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. | | `defaultOpen` | `boolean` | No | The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. | | `defaultValue` | `string[]` | No | The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. | | `disabled` | `boolean` | No | Whether the combobox is disabled | | `disableLayer` | `boolean` | No | Whether to disable registering this a dismissable layer | | `form` | `string` | No | The associate form of the combobox. | | `highlightedValue` | `string` | No | The controlled highlighted value of the combobox | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string control: string input: string content: string trigger: string clearTrigger: string item: (id: string, index?: number | undefined) => string positioner: string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the combobox. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inputBehavior` | `'none' | 'autocomplete' | 'autohighlight'` | No | Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated | | `inputValue` | `string` | No | The controlled value of the combobox's input | | `invalid` | `boolean` | No | Whether the combobox is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the items | | `multiple` | `boolean` | No | Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. | | `name` | `string` | No | The `name` attribute of the combobox's input. Useful for form submission | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when an item is highlighted using the pointer or keyboard navigation. | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Function called when the input's value changes | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when a new item is selected | | `open` | `boolean` | No | The controlled open state of the combobox | | `openOnChange` | `boolean | ((details: InputValueChangeDetails) => boolean)` | No | Whether to show the combobox when the input value changes | | `openOnClick` | `boolean` | No | Whether to open the combobox popup on initial click on the input | | `openOnKeyPress` | `boolean` | No | Whether to open the combobox on arrow key press | | `placeholder` | `string` | No | The placeholder text of the combobox's input | | `positioning` | `PositioningOptions` | No | The positioning options to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the combobox is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionBehavior` | `'replace' | 'clear' | 'preserve'` | No | The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the combobox's selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested comboboxs | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseComboboxContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-autofocus]` | | | `[data-state]` | "open" | "closed" | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseComboboxItemContext]>` | Yes | | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | | `ref` | `Element` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-group | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `{}` | No | | | `persistFocus` | `boolean` | No | | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-value]` | The value of the item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | label | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-focus]` | Present when focused | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | list | | `[data-empty]` | Present when the content is empty | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseComboboxReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `ref` | `Element` | No | | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | combobox | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | | `[data-focusable]` | | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focused` | `boolean` | Whether the combobox is focused | | `open` | `boolean` | Whether the combobox is open | | `inputValue` | `string` | The value of the combobox input | | `highlightedValue` | `string` | The value of the highlighted item | | `highlightedItem` | `V` | The highlighted item | | `setHighlightValue` | `(value: string) => void` | The value of the combobox input | | `clearHighlightValue` | `VoidFunction` | Function to clear the highlighted value | | `syncSelectedItems` | `VoidFunction` | Function to sync the selected items with the value. Useful when `value` is updated from async sources. | | `selectedItems` | `V[]` | The selected items | | `hasSelectedItems` | `boolean` | Whether there's a selected item | | `value` | `string[]` | The selected item keys | | `valueAsString` | `string` | The string representation of the selected items | | `selectValue` | `(value: string) => void` | Function to select a value | | `setValue` | `(value: string[]) => void` | Function to set the value of the combobox | | `clearValue` | `(value?: string) => void` | Function to clear the value of the combobox | | `focus` | `VoidFunction` | Function to focus on the combobox input | | `setInputValue` | `(value: string, reason?: InputValueChangeReason) => void` | Function to set the input value of the combobox | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a combobox item | | `setOpen` | `(open: boolean, reason?: OpenChangeReason) => void` | Function to open or close the combobox | | `collection` | `ListCollection` | Function to toggle the combobox | | `reposition` | `(options?: Partial) => void` | Function to set the positioning options | | `multiple` | `boolean` | Whether the combobox allows multiple selections | | `disabled` | `boolean` | Whether the combobox is disabled | ## Accessibility Complies with the [Combobox WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/). ### Keyboard Support **`ArrowDown`** Description: When the combobox is closed, opens the listbox and highlights to the first option. When the combobox is open, moves focus to the next option. **`ArrowUp`** Description: When the combobox is closed, opens the listbox and highlights to the last option. When the combobox is open, moves focus to the previous option. **`Home`** Description: When the combobox is open, moves focus to the first option. **`End`** Description: When the combobox is open, moves focus to the last option. **`Escape`** Description: Closes the listbox. **`Enter`** Description: Selects the highlighted option and closes the combobox. **`Esc`** Description: Closes the combobox --- # Date Picker (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Basic = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Basic = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Default Value Use the `defaultValue` prop with `parseDate` to set the initial date value. **Example: default-value** #### React ```tsx import { DatePicker, parseDate } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const DefaultValue = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker, parseDate } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const DefaultValue = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Controlled Use the `value` and `onValueChange` props to control the date picker's value programmatically. **Example: controlled** #### React ```tsx import { DatePicker, parseDate } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Controlled = () => { const [value, setValue] = useState([parseDate('2022-01-01')]) return ( setValue(e.value)}> Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker, parseDate } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Controlled = () => { const [value, setValue] = createSignal([parseDate('2022-01-01')]) return ( setValue(e.value)}> Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: root-provider** #### React ```tsx import { DatePicker, useDatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const RootProvider = () => { const datePicker = useDatePicker() return (
                    Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker, useDatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const RootProvider = () => { const datePicker = useDatePicker() return ( <> Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Default View Use the `defaultView` prop to set which view (day, month, or year) the calendar opens to initially. **Example: default-view** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const DefaultView = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const DefaultView = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: month-year-select** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import styles from 'styles/date-picker.module.css' export const MonthYearSelect = () => { return ( Label {(datePicker) => ( <>
                    {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/date-picker.module.css' export const MonthYearSelect = () => { return ( Label {(context) => ( <>
                    {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(datePicker)}
                    {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet}
                    ``` ### 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`. **Example: range-selection** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const RangeSelection = () => { return ( Label Clear Last 7 days {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon } from 'lucide-solid' import { Index, createMemo } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const RangeSelection = () => { return ( Label Clear Last 7 days
                    {(context) => ( {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => { const offset = createMemo(() => context().getOffset({ months: 1 })) return ( {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear Last 7 days {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Multiple Use the `selectionMode="multiple"` prop to allow selecting multiple dates. This example also shows how to display selected dates as removable tags. **Example: multi-selection** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import type { DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const formatWithDay = (date: DateValue) => { const jsDate = date.toDate('UTC') return jsDate.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric', }) } export const MultiSelection = () => { return ( Label {(datePicker) => (
                    {datePicker.value.length === 0 ? ( Select dates... ) : ( datePicker.value.map((date, index) => ( {formatWithDay(date)} )) )}
                    )}
                    Clear
                    {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { For, Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MultiSelection = () => { return ( Label {(context) => (
                    {context().value.length === 0 ? ( Select dates... ) : ( {(date, index) => ( {date.toDate('UTC').toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric', })} )} )}
                    )}
                    Clear
                    {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: multiple-months** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MultipleMonths = () => { return ( Label Clear
                    {(datePicker) => ( {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => { const offset = datePicker.getOffset({ months: 1 }) return ( {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {offset.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} ) }}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index, createMemo } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MultipleMonths = () => { return ( Label Clear
                    {(datePicker) => ( {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(datePicker) => { const offset = createMemo(() => datePicker().getOffset({ months: 1 })) return ( {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear
                    {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay, id (id)} {weekDay.short} {/each} {#each datePicker().weeks as week, id} {#each week as day, id (id)} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {@const offset = datePicker().getOffset({ months: 1 })} {#each datePicker().weekDays as weekDay, id (id)} {weekDay.short} {/each} {#each offset.weeks as week, id (id)} {#each week as day, id (id)} {day.day} {/each} {/each} {/snippet}
                    ``` ### Presets Use the `DatePicker.PresetTrigger` component to add quick-select preset options like "Last 7 days" or "This month". **Example: presets** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Presets = () => { return ( Label Clear
                    Last 7 days Last 30 days This month Last month
                    {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Presets = () => { return ( Label Clear
                    Last 7 days Last 30 days This month
                    {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear
                    Last 7 days Last 30 days This month
                    {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet}
                    ``` ### Min and Max Use the `min` and `max` props with `parseDate` to restrict the selectable date range. Dates outside this range will be disabled. **Example: min-max** #### React ```tsx import { DatePicker, parseDate } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MinMax = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker, parseDate } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MinMax = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Unavailable Use the `isDateUnavailable` prop to mark specific dates as unavailable. This example disables weekends. **Example: unavailable** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import type { DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const isWeekend = (date: DateValue) => { const dayOfWeek = date.toDate('UTC').getDay() return dayOfWeek === 0 || dayOfWeek === 6 } export const Unavailable = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import type { DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const isWeekend = (date: DateValue) => { const dayOfWeek = date.toDate('UTC').getDay() return dayOfWeek === 0 || dayOfWeek === 6 } export const Unavailable = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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.). **Example: locale** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Locale = () => { return ( Datum auswählen Löschen {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Locale = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: month-picker** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => { const month = date.month.toString().padStart(2, '0') const year = date.year.toString() return `${month}/${year}` } const parse = (string: string) => { const fullRegex = /^(\d{1,2})\/(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, month, year] = fullMatch.map(Number) return new CalendarDate(year, month, 1) } } export const MonthPicker = () => { return ( Label Clear {(datePicker) => ( {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => { const month = date.month.toString().padStart(2, '0') const year = date.year.toString() return `${month}/${year}` } const parse = (string: string) => { const fullRegex = /^(\d{1,2})\/(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, month, year] = fullMatch.map(Number) return new CalendarDate(year, month, 1) } } export const MonthPicker = () => { return ( Label Clear {(context) => ( {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: year-picker** #### React ```tsx import { DatePicker, parseDate } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import type { DateValue } from '@internationalized/date' import { CalendarIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => date.year.toString() const parse = (string: string | undefined) => { if (string === '' || !string) return const year = Number(string) if (year < 100) { const currentYear = new Date().getFullYear() const currentCentury = Math.floor(currentYear / 100) * 100 return parseDate(new Date(currentCentury + year, 0)) } return parseDate(new Date(Number(string), 0)) } export const YearPicker = () => { return ( Label Clear {(datePicker) => ( {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker, parseDate } from '@ark-ui/solid/date-picker' import type { DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => date.year.toString() const parse = (string: string | undefined) => { if (string === '' || !string) return const year = Number(string) if (year < 100) { const currentYear = new Date().getFullYear() const currentCentury = Math.floor(currentYear / 100) * 100 return parseDate(new Date(currentCentury + year, 0)) } return parseDate(new Date(Number(string), 0)) } export const YearPicker = () => { return ( Label Clear {(context) => ( {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: inline** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import styles from 'styles/date-picker.module.css' export const Inline = () => { return (
                    {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/date-picker.module.css' export const Inline = () => { return ( {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: format-parse** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const parse = (value: string) => { const fullRegex = /^(\d{1,2})\/(\d{1,2})\/(\d{2})$/ const fullMatch = value.match(fullRegex) if (fullMatch) { const [_, day, month, year] = fullMatch.map(Number) try { return new CalendarDate(year + 2000, month, day) } catch { return undefined } } const partialRegex = /^(\d{1,2})\/(\d{1,2})$/ const partialMatch = value.match(partialRegex) if (partialMatch) { const [_, day, month] = partialMatch.map(Number) const currentYear = new Date().getFullYear() try { return new CalendarDate(currentYear, month, day) } catch { return undefined } } const dayRegex = /^(\d{1,2})$/ const dayMatch = value.match(dayRegex) if (dayMatch) { const [_, day] = dayMatch.map(Number) const currentYear = new Date().getFullYear() return new CalendarDate(currentYear, 1, day) } return undefined } const format = (date: DateValue) => { const day = date.day.toString().padStart(2, '0') const month = date.month.toString().padStart(2, '0') const year = (date.year % 100).toString().padStart(2, '0') return `${day}/${month}/${year}` } export const FormatParse = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` ### 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. **Example: month-picker-range** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => { const month = date.month.toString().padStart(2, '0') const year = date.year.toString() return `${month}/${year}` } const parse = (string: string) => { const fullRegex = /^(\d{1,2})\/(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, month, year] = fullMatch.map(Number) return new CalendarDate(year, month, 1) } } export const MonthPickerRange = () => { return ( Label Clear {(datePicker) => ( {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => { const month = date.month.toString().padStart(2, '0') const year = date.year.toString() return `${month}/${year}` } const parse = (string: string) => { const fullRegex = /^(\d{1,2})\/(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, month, year] = fullMatch.map(Number) return new CalendarDate(year, month, 1) } } export const MonthPickerRange = () => { return ( Label Clear {(context) => ( {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: year-picker-range** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => date.year.toString() const parse = (string: string) => { const fullRegex = /^(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, year] = fullMatch.map(Number) return new CalendarDate(year, 1, 1) } } export const YearPickerRange = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.getDecade().start} - {datePicker.getDecade().end} {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => date.year.toString() const parse = (string: string | undefined) => { if (!string) return const fullRegex = /^(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, year] = fullMatch.map(Number) return new CalendarDate(year, 1, 1) } } export const YearPickerRange = () => { return ( Label Clear {(context) => ( <> {context().getDecade().start} - {context().getDecade().end} {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {datePicker().getDecade().start} - {datePicker().getDecade().end} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: with-time** #### React ```tsx import { CalendarDateTime, DateFormatter, getLocalTimeZone } from '@internationalized/date' import { DatePicker, type DatePickerValueChangeDetails } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const formatter = new DateFormatter('en-US', { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit', }) export const WithTime = () => { const [value, setValue] = useState([new CalendarDateTime(2025, 1, 29, 14, 30)]) const timeValue = value[0] ? `${String(value[0].hour).padStart(2, '0')}:${String(value[0].minute).padStart(2, '0')}` : '' const onTimeChange = (e: React.ChangeEvent) => { const [hours, minutes] = e.currentTarget.value.split(':').map(Number) setValue((prev) => { const current = prev[0] ?? new CalendarDateTime(2025, 1, 1, 0, 0) return [current.set({ hour: hours, minute: minutes })] }) } const onDateChange = (details: DatePickerValueChangeDetails) => { const newDate = details.value[0] if (!newDate) return setValue([]) const prevTime = value[0] ?? { hour: 0, minute: 0 } setValue([new CalendarDateTime(newDate.year, newDate.month, newDate.day, prevTime.hour, prevTime.minute)]) } return ( Date and time {value[0] ? formatter.format(value[0].toDate(getLocalTimeZone())) : 'Select date and time'} {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} ) } ``` #### Solid ```tsx import { CalendarDateTime, DateFormatter, getLocalTimeZone } from '@internationalized/date' import { DatePicker, type DatePickerValueChangeDetails } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const formatter = new DateFormatter('en-US', { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit', }) export const WithTime = () => { const [value, setValue] = createSignal([new CalendarDateTime(2025, 1, 29, 14, 30)]) const timeValue = () => { const v = value()[0] return v ? `${String(v.hour).padStart(2, '0')}:${String(v.minute).padStart(2, '0')}` : '' } const onTimeChange = (e: Event & { currentTarget: HTMLInputElement }) => { const [hours, minutes] = e.currentTarget.value.split(':').map(Number) setValue((prev) => { const current = prev[0] ?? new CalendarDateTime(2025, 1, 1, 0, 0) return [current.set({ hour: hours, minute: minutes })] }) } const onDateChange = (details: DatePickerValueChangeDetails) => { const newDate = details.value[0] if (!newDate) return setValue([]) const prevTime = value()[0] ?? { hour: 0, minute: 0 } setValue([new CalendarDateTime(newDate.year, newDate.month, newDate.day, prevTime.hour, prevTime.minute)]) } return ( Date and time {value()[0] ? formatter.format(value()[0].toDate(getLocalTimeZone())) : 'Select date and time'} {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Date and time {value[0] ? formatter.format(value[0].toDate(getLocalTimeZone())) : 'Select date and time'} {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the calendar should close after the date selection is complete. This is ignored when the selection mode is `multiple`. | | `defaultFocusedValue` | `DateValue` | No | The initial focused date when rendered. Use when you don't need to control the focused date of the date picker. | | `defaultOpen` | `boolean` | No | The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker. | | `defaultValue` | `DateValue[]` | No | The initial selected date(s) when rendered. Use when you don't need to control the selected date(s) of the date picker. | | `defaultView` | `DateView` | No | The default view of the calendar | | `disabled` | `boolean` | No | Whether the calendar is disabled. | | `fixedWeeks` | `boolean` | No | Whether the calendar should have a fixed number of weeks. This renders the calendar with 6 weeks instead of 5 or 6. | | `focusedValue` | `DateValue` | No | The controlled focused date. | | `format` | `(date: DateValue, details: LocaleDetails) => string` | No | The format of the date to display in the input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; label: (index: number) => string; table: (id: string) => string; tableHeader: (id: string) => string; tableBody: (id: string) => string; tableRow: (id: string) => string; content: string; ... 10 more ...; positioner: string; }>` | No | The ids of the elements in the date picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inline` | `boolean` | No | Whether to render the date picker inline | | `isDateUnavailable` | `(date: DateValue, locale: string) => boolean` | No | Returns whether a date of the calendar is available. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `locale` | `string` | No | The locale (BCP 47 language tag) to use when formatting the date. | | `max` | `DateValue` | No | The maximum date that can be selected. | | `maxView` | `DateView` | No | The maximum view of the calendar | | `min` | `DateValue` | No | The minimum date that can be selected. | | `minView` | `DateView` | No | The minimum view of the calendar | | `name` | `string` | No | The `name` attribute of the input element. | | `numOfMonths` | `number` | No | The number of months to display. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function called when the focused date changes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the calendar opens or closes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when the value changes. | | `onViewChange` | `(details: ViewChangeDetails) => void` | No | Function called when the view changes. | | `open` | `boolean` | No | The controlled open state of the date picker | | `outsideDaySelectable` | `boolean` | No | Whether day outside the visible range can be selected. | | `parse` | `(value: string, details: LocaleDetails) => DateValue | undefined` | No | Function to parse the date from the input back to a DateValue. | | `placeholder` | `string` | No | The placeholder text to display in the input. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the date picker content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the calendar is read-only. | | `selectionMode` | `SelectionMode` | No | The selection mode of the calendar. - `single` - only one date can be selected - `multiple` - multiple dates can be selected - `range` - a range of dates can be selected | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `startOfWeek` | `number` | No | The first day of the week. `0` - Sunday `1` - Monday `2` - Tuesday `3` - Wednesday `4` - Thursday `5` - Friday `6` - Saturday | | `timeZone` | `string` | No | The time zone to use | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `DateValue[]` | No | The controlled selected date(s). | | `view` | `DateView` | No | The view of the calendar | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | | `[data-inline]` | Present when the content is inline | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested date-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fixOnBlur` | `boolean` | No | Whether to fix the input value on blur. | | `index` | `number` | No | The index of the input to focus. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | input | | `[data-index]` | The index of the item | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | label | | `[data-state]` | "open" | "closed" | | `[data-index]` | The index of the item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **MonthSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **PresetTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PresetTriggerValue` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RangeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDatePickerReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **TableBody Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableBody Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-body | | `[data-view]` | The view of the tablebody | | `[data-disabled]` | Present when disabled | **TableCell Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number | DateValue` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `disabled` | `boolean` | No | | | `visibleRange` | `VisibleRange` | No | | **TableCellTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-head | | `[data-view]` | The view of the tablehead | | `[data-disabled]` | Present when disabled | **TableHeader Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHeader Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-header | | `[data-view]` | The view of the tableheader | | `[data-disabled]` | Present when disabled | **Table Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | **Table Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table | | `[data-columns]` | | | `[data-view]` | The view of the table | **TableRow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableRow Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-row | | `[data-disabled]` | Present when disabled | | `[data-view]` | The view of the tablerow | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | **ViewControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-control | | `[data-view]` | The view of the viewcontrol | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `view` | `DateView` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **View Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view | | `[data-view]` | The view of the view | **ViewTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-trigger | | `[data-view]` | The view of the viewtrigger | **YearSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the calendar should close after the date selection is complete. This is ignored when the selection mode is `multiple`. | | `defaultFocusedValue` | `DateValue` | No | The initial focused date when rendered. Use when you don't need to control the focused date of the date picker. | | `defaultOpen` | `boolean` | No | The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker. | | `defaultValue` | `DateValue[]` | No | The initial selected date(s) when rendered. Use when you don't need to control the selected date(s) of the date picker. | | `defaultView` | `DateView` | No | The default view of the calendar | | `disabled` | `boolean` | No | Whether the calendar is disabled. | | `fixedWeeks` | `boolean` | No | Whether the calendar should have a fixed number of weeks. This renders the calendar with 6 weeks instead of 5 or 6. | | `focusedValue` | `DateValue` | No | The controlled focused date. | | `format` | `(date: DateValue, details: LocaleDetails) => string` | No | The format of the date to display in the input. | | `ids` | `Partial<{ root: string; label: (index: number) => string; table: (id: string) => string; tableHeader: (id: string) => string; tableBody: (id: string) => string; tableRow: (id: string) => string; content: string; ... 10 more ...; positioner: string; }>` | No | The ids of the elements in the date picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inline` | `boolean` | No | Whether to render the date picker inline | | `isDateUnavailable` | `(date: DateValue, locale: string) => boolean` | No | Returns whether a date of the calendar is available. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `locale` | `string` | No | The locale (BCP 47 language tag) to use when formatting the date. | | `max` | `DateValue` | No | The maximum date that can be selected. | | `maxView` | `DateView` | No | The maximum view of the calendar | | `min` | `DateValue` | No | The minimum date that can be selected. | | `minView` | `DateView` | No | The minimum view of the calendar | | `name` | `string` | No | The `name` attribute of the input element. | | `numOfMonths` | `number` | No | The number of months to display. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function called when the focused date changes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the calendar opens or closes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when the value changes. | | `onViewChange` | `(details: ViewChangeDetails) => void` | No | Function called when the view changes. | | `open` | `boolean` | No | The controlled open state of the date picker | | `outsideDaySelectable` | `boolean` | No | Whether day outside the visible range can be selected. | | `parse` | `(value: string, details: LocaleDetails) => DateValue | undefined` | No | Function to parse the date from the input back to a DateValue. | | `placeholder` | `string` | No | The placeholder text to display in the input. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the date picker content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the calendar is read-only. | | `selectionMode` | `SelectionMode` | No | The selection mode of the calendar. - `single` - only one date can be selected - `multiple` - multiple dates can be selected - `range` - a range of dates can be selected | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `startOfWeek` | `number` | No | The first day of the week. `0` - Sunday `1` - Monday `2` - Tuesday `3` - Wednesday `4` - Thursday `5` - Friday `6` - Saturday | | `timeZone` | `string` | No | The time zone to use | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `DateValue[]` | No | The controlled selected date(s). | | `view` | `DateView` | No | The view of the calendar | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | | `[data-inline]` | Present when the content is inline | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested date-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fixOnBlur` | `boolean` | No | Whether to fix the input value on blur. | | `index` | `number` | No | The index of the input to focus. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | input | | `[data-index]` | The index of the item | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | label | | `[data-state]` | "open" | "closed" | | `[data-index]` | The index of the item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **MonthSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **PresetTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PresetTriggerValue` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RangeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDatePickerReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **TableBody Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'tbody'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableBody Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-body | | `[data-view]` | The view of the tablebody | | `[data-disabled]` | Present when disabled | **TableCell Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number | DateValue` | Yes | | | `asChild` | `(props: ParentProps<'td'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `disabled` | `boolean` | No | | | `visibleRange` | `VisibleRange` | No | | **TableCellTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'thead'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-head | | `[data-view]` | The view of the tablehead | | `[data-disabled]` | Present when disabled | **TableHeader Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'th'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHeader Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-header | | `[data-view]` | The view of the tableheader | | `[data-disabled]` | Present when disabled | **Table Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'table'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | **Table Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table | | `[data-columns]` | | | `[data-view]` | The view of the table | **TableRow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'tr'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableRow Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-row | | `[data-disabled]` | Present when disabled | | `[data-view]` | The view of the tablerow | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | **ViewControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-control | | `[data-view]` | The view of the viewcontrol | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `view` | `DateView` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **View Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view | | `[data-view]` | The view of the view | **ViewTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-trigger | | `[data-view]` | The view of the viewtrigger | **YearSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the calendar should close after the date selection is complete. This is ignored when the selection mode is `multiple`. | | `defaultFocusedValue` | `DateValue` | No | The initial focused date when rendered. Use when you don't need to control the focused date of the date picker. | | `defaultOpen` | `boolean` | No | The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker. | | `defaultValue` | `DateValue[]` | No | The initial selected date(s) when rendered. Use when you don't need to control the selected date(s) of the date picker. | | `defaultView` | `DateView` | No | The default view of the calendar | | `disabled` | `boolean` | No | Whether the calendar is disabled. | | `fixedWeeks` | `boolean` | No | Whether the calendar should have a fixed number of weeks. This renders the calendar with 6 weeks instead of 5 or 6. | | `focusedValue` | `DateValue` | No | The controlled focused date. | | `format` | `(date: DateValue, details: LocaleDetails) => string` | No | The format of the date to display in the input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; label(index: number): string; table(id: string): string; tableHeader(id: string): string; tableBody(id: string): string; tableRow(id: string): string; content: string; ... 10 more ...; positioner: string; }>` | No | The ids of the elements in the date picker. Useful for composition. | | `inline` | `boolean` | No | Whether the date picker is inline | | `isDateUnavailable` | `(date: DateValue, locale: string) => boolean` | No | Returns whether a date of the calendar is available. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `locale` | `string` | No | The locale (BCP 47 language tag) to use when formatting the date. | | `max` | `DateValue` | No | The maximum date that can be selected. | | `maxView` | `DateView` | No | The maximum view of the calendar | | `min` | `DateValue` | No | The minimum date that can be selected. | | `minView` | `DateView` | No | The minimum view of the calendar | | `modelValue` | `DateValue[]` | No | The v-model value of the date picker | | `name` | `string` | No | The `name` attribute of the input element. | | `numOfMonths` | `number` | No | The number of months to display. | | `open` | `boolean` | No | The controlled open state of the date picker | | `outsideDaySelectable` | `boolean` | No | Whether day outside the visible range can be selected. | | `parse` | `(value: string, details: LocaleDetails) => DateValue | undefined` | No | Function to parse the date from the input back to a DateValue. | | `placeholder` | `string` | No | The placeholder text to display in the input. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the date picker content | | `readOnly` | `boolean` | No | Whether the calendar is read-only. | | `selectionMode` | `SelectionMode` | No | The selection mode of the calendar. - `single` - only one date can be selected - `multiple` - multiple dates can be selected - `range` - a range of dates can be selected | | `startOfWeek` | `number` | No | The first day of the week. `0` - Sunday `1` - Monday `2` - Tuesday `3` - Wednesday `4` - Thursday `5` - Friday `6` - Saturday | | `timeZone` | `string` | No | The time zone to use | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `view` | `DateView` | No | The view of the calendar | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | | `[data-inline]` | Present when the content is inline | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested date-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fixOnBlur` | `boolean` | No | Whether to fix the input value on blur. | | `index` | `number` | No | The index of the input to focus. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | input | | `[data-index]` | The index of the item | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | label | | `[data-state]` | "open" | "closed" | | `[data-index]` | The index of the item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **MonthSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **PresetTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PresetTriggerValue` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RangeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `DatePickerApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **TableBody Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableBody Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-body | | `[data-view]` | The view of the tablebody | | `[data-disabled]` | Present when disabled | **TableCell Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `Reactive` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `disabled` | `boolean` | No | | | `visibleRange` | `VisibleRange` | No | | **TableCellTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-head | | `[data-view]` | The view of the tablehead | | `[data-disabled]` | Present when disabled | **TableHeader Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHeader Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-header | | `[data-view]` | The view of the tableheader | | `[data-disabled]` | Present when disabled | **Table Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `id` | `string` | No | | | `view` | `DateView` | No | | **Table Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table | | `[data-columns]` | | | `[data-view]` | The view of the table | **TableRow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableRow Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-row | | `[data-disabled]` | Present when disabled | | `[data-view]` | The view of the tablerow | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | **ViewControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-control | | `[data-view]` | The view of the viewcontrol | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `view` | `DateView` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **View Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view | | `[data-view]` | The view of the view | **ViewTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-trigger | | `[data-view]` | The view of the viewtrigger | **YearSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the calendar should close after the date selection is complete. This is ignored when the selection mode is `multiple`. | | `defaultFocusedValue` | `DateValue` | No | The initial focused date when rendered. Use when you don't need to control the focused date of the date picker. | | `defaultOpen` | `boolean` | No | The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker. | | `defaultValue` | `DateValue[]` | No | The initial selected date(s) when rendered. Use when you don't need to control the selected date(s) of the date picker. | | `defaultView` | `DateView` | No | The default view of the calendar | | `disabled` | `boolean` | No | Whether the calendar is disabled. | | `fixedWeeks` | `boolean` | No | Whether the calendar should have a fixed number of weeks. This renders the calendar with 6 weeks instead of 5 or 6. | | `focusedValue` | `DateValue` | No | The controlled focused date. | | `format` | `(date: DateValue, details: LocaleDetails) => string` | No | The format of the date to display in the input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; label: (index: number) => string; table: (id: string) => string; tableHeader: (id: string) => string; tableBody: (id: string) => string; tableRow: (id: string) => string; content: string; ... 10 more ...; positioner: string; }>` | No | The ids of the elements in the date picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inline` | `boolean` | No | Whether to render the date picker inline | | `isDateUnavailable` | `(date: DateValue, locale: string) => boolean` | No | Returns whether a date of the calendar is available. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `locale` | `string` | No | The locale (BCP 47 language tag) to use when formatting the date. | | `max` | `DateValue` | No | The maximum date that can be selected. | | `maxView` | `DateView` | No | The maximum view of the calendar | | `min` | `DateValue` | No | The minimum date that can be selected. | | `minView` | `DateView` | No | The minimum view of the calendar | | `name` | `string` | No | The `name` attribute of the input element. | | `numOfMonths` | `number` | No | The number of months to display. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function called when the focused date changes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the calendar opens or closes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when the value changes. | | `onViewChange` | `(details: ViewChangeDetails) => void` | No | Function called when the view changes. | | `open` | `boolean` | No | The controlled open state of the date picker | | `outsideDaySelectable` | `boolean` | No | Whether day outside the visible range can be selected. | | `parse` | `(value: string, details: LocaleDetails) => DateValue | undefined` | No | Function to parse the date from the input back to a DateValue. | | `placeholder` | `string` | No | The placeholder text to display in the input. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the date picker content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the calendar is read-only. | | `ref` | `Element` | No | | | `selectionMode` | `SelectionMode` | No | The selection mode of the calendar. - `single` - only one date can be selected - `multiple` - multiple dates can be selected - `range` - a range of dates can be selected | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `startOfWeek` | `number` | No | The first day of the week. `0` - Sunday `1` - Monday `2` - Tuesday `3` - Wednesday `4` - Thursday `5` - Friday `6` - Saturday | | `timeZone` | `string` | No | The time zone to use | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `DateValue[]` | No | The controlled selected date(s). | | `view` | `DateView` | No | The view of the calendar | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | | `[data-inline]` | Present when the content is inline | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested date-pickers | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseDatePickerContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fixOnBlur` | `boolean` | No | Whether to fix the input value on blur. | | `index` | `number` | No | The index of the input to focus. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | input | | `[data-index]` | The index of the item | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | label | | `[data-state]` | "open" | "closed" | | `[data-index]` | The index of the item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **MonthSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **PresetTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PresetTriggerValue` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RangeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDatePickerReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **TableBody Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'tbody'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableBody Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-body | | `[data-view]` | The view of the tablebody | | `[data-disabled]` | Present when disabled | **TableCell Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number | DateValue` | Yes | | | `asChild` | `Snippet<[PropsFn<'td'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `disabled` | `boolean` | No | | | `ref` | `Element` | No | | | `visibleRange` | `VisibleRange` | No | | **TableCellTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableHead Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'thead'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableHead Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-head | | `[data-view]` | The view of the tablehead | | `[data-disabled]` | Present when disabled | **TableHeader Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'th'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableHeader Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-header | | `[data-view]` | The view of the tableheader | | `[data-disabled]` | Present when disabled | **Table Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'table'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | **Table Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table | | `[data-columns]` | | | `[data-view]` | The view of the table | **TableRow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'tr'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableRow Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-row | | `[data-disabled]` | Present when disabled | | `[data-view]` | The view of the tablerow | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | **ViewControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ViewControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-control | | `[data-view]` | The view of the viewcontrol | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `view` | `DateView` | No | | **View Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view | | `[data-view]` | The view of the view | **ViewTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ViewTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-trigger | | `[data-view]` | The view of the viewtrigger | **YearSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focused` | `boolean` | Whether the input is focused | | `open` | `boolean` | Whether the date picker is open | | `disabled` | `boolean` | Whether the date picker is disabled | | `invalid` | `boolean` | Whether the date picker is invalid | | `inline` | `boolean` | Whether the date picker is rendered inline | | `view` | `DateView` | The current view of the date picker | | `getDaysInWeek` | `(week: number, from?: DateValue) => DateValue[]` | Returns an array of days in the week index counted from the provided start date, or the first visible date if not given. | | `getOffset` | `(duration: DateDuration) => DateValueOffset` | Returns the offset of the month based on the provided number of months. | | `getRangePresetValue` | `(value: DateRangePreset) => DateValue[]` | Returns the range of dates based on the provided date range preset. | | `getMonthWeeks` | `(from?: DateValue) => DateValue[][]` | Returns the weeks of the month from the provided date. Represented as an array of arrays of dates. | | `isUnavailable` | `(date: DateValue) => boolean` | Returns whether the provided date is available (or can be selected) | | `weeks` | `DateValue[][]` | The weeks of the month. Represented as an array of arrays of dates. | | `weekDays` | `WeekDay[]` | The days of the week. Represented as an array of strings. | | `visibleRange` | `VisibleRange` | The visible range of dates. | | `visibleRangeText` | `VisibleRangeText` | The human readable text for the visible range of dates. | | `value` | `DateValue[]` | The selected date. | | `valueAsDate` | `Date[]` | The selected date as a Date object. | | `valueAsString` | `string[]` | The selected date as a string. | | `focusedValue` | `DateValue` | The focused date. | | `focusedValueAsDate` | `Date` | The focused date as a Date object. | | `focusedValueAsString` | `string` | The focused date as a string. | | `selectToday` | `VoidFunction` | Sets the selected date to today. | | `setValue` | `(values: DateValue[]) => void` | Sets the selected date to the given date. | | `setFocusedValue` | `(value: DateValue) => void` | Sets the focused date to the given date. | | `clearValue` | `VoidFunction` | Clears the selected date(s). | | `setOpen` | `(open: boolean) => void` | Function to open or close the calendar. | | `focusMonth` | `(month: number) => void` | Function to set the selected month. | | `focusYear` | `(year: number) => void` | Function to set the selected year. | | `getYears` | `() => Cell[]` | Returns the months of the year | | `getYearsGrid` | `(props?: YearGridProps) => YearGridValue` | Returns the years of the decade based on the columns. Represented as an array of arrays of years. | | `getDecade` | `() => Range` | Returns the start and end years of the decade. | | `getMonths` | `(props?: MonthFormatOptions) => Cell[]` | Returns the months of the year | | `getMonthsGrid` | `(props?: MonthGridProps) => MonthGridValue` | Returns the months of the year based on the columns. Represented as an array of arrays of months. | | `format` | `(value: DateValue, opts?: Intl.DateTimeFormatOptions) => string` | Formats the given date value based on the provided options. | | `setView` | `(view: DateView) => void` | Sets the view of the date picker. | | `goToNext` | `VoidFunction` | Goes to the next month/year/decade. | | `goToPrev` | `VoidFunction` | Goes to the previous month/year/decade. | | `getDayTableCellState` | `(props: DayTableCellProps) => DayTableCellState` | Returns the state details for a given cell. | | `getMonthTableCellState` | `(props: TableCellProps) => TableCellState` | Returns the state details for a given month cell. | | `getYearTableCellState` | `(props: TableCellProps) => TableCellState` | Returns the state details for a given year cell. | ## Accessibility ### Keyboard Support **`ArrowLeft`** Description: Moves focus to the previous day within the current week. **`ArrowRight`** Description: Moves focus to the next day within the current week. **`ArrowUp`** Description: Moves focus to the same day of the week in the previous week. **`ArrowDown`** Description: Moves focus to the same day of the week in the next week. **`Home`** Description: Moves focus to the first day of the current month. **`End`** Description: Moves focus to the last day of the current month. **`PageUp`** Description: Moves focus to the same day of the month in the previous month. **`PageDown`** Description: Moves focus to the same day of the month in the next month. **`Enter`** Description: Selects the focused date and closes the date picker. **`Esc`** Description: Closes the date picker without selecting any date. --- # Date Picker (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Basic = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Basic = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Default Value Use the `defaultValue` prop with `parseDate` to set the initial date value. **Example: default-value** #### React ```tsx import { DatePicker, parseDate } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const DefaultValue = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker, parseDate } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const DefaultValue = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Controlled Use the `value` and `onValueChange` props to control the date picker's value programmatically. **Example: controlled** #### React ```tsx import { DatePicker, parseDate } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Controlled = () => { const [value, setValue] = useState([parseDate('2022-01-01')]) return ( setValue(e.value)}> Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker, parseDate } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Controlled = () => { const [value, setValue] = createSignal([parseDate('2022-01-01')]) return ( setValue(e.value)}> Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: root-provider** #### React ```tsx import { DatePicker, useDatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const RootProvider = () => { const datePicker = useDatePicker() return (
                    Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker, useDatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const RootProvider = () => { const datePicker = useDatePicker() return ( <> Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Default View Use the `defaultView` prop to set which view (day, month, or year) the calendar opens to initially. **Example: default-view** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const DefaultView = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const DefaultView = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: month-year-select** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import styles from 'styles/date-picker.module.css' export const MonthYearSelect = () => { return ( Label {(datePicker) => ( <>
                    {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/date-picker.module.css' export const MonthYearSelect = () => { return ( Label {(context) => ( <>
                    {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(datePicker)}
                    {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet}
                    ``` ### 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`. **Example: range-selection** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const RangeSelection = () => { return ( Label Clear Last 7 days {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon } from 'lucide-solid' import { Index, createMemo } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const RangeSelection = () => { return ( Label Clear Last 7 days
                    {(context) => ( {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => { const offset = createMemo(() => context().getOffset({ months: 1 })) return ( {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear Last 7 days {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Multiple Use the `selectionMode="multiple"` prop to allow selecting multiple dates. This example also shows how to display selected dates as removable tags. **Example: multi-selection** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import type { DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const formatWithDay = (date: DateValue) => { const jsDate = date.toDate('UTC') return jsDate.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric', }) } export const MultiSelection = () => { return ( Label {(datePicker) => (
                    {datePicker.value.length === 0 ? ( Select dates... ) : ( datePicker.value.map((date, index) => ( {formatWithDay(date)} )) )}
                    )}
                    Clear
                    {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { For, Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MultiSelection = () => { return ( Label {(context) => (
                    {context().value.length === 0 ? ( Select dates... ) : ( {(date, index) => ( {date.toDate('UTC').toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric', })} )} )}
                    )}
                    Clear
                    {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: multiple-months** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MultipleMonths = () => { return ( Label Clear
                    {(datePicker) => ( {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => { const offset = datePicker.getOffset({ months: 1 }) return ( {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {offset.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} ) }}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index, createMemo } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MultipleMonths = () => { return ( Label Clear
                    {(datePicker) => ( {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(datePicker) => { const offset = createMemo(() => datePicker().getOffset({ months: 1 })) return ( {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear
                    {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay, id (id)} {weekDay.short} {/each} {#each datePicker().weeks as week, id} {#each week as day, id (id)} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {@const offset = datePicker().getOffset({ months: 1 })} {#each datePicker().weekDays as weekDay, id (id)} {weekDay.short} {/each} {#each offset.weeks as week, id (id)} {#each week as day, id (id)} {day.day} {/each} {/each} {/snippet}
                    ``` ### Presets Use the `DatePicker.PresetTrigger` component to add quick-select preset options like "Last 7 days" or "This month". **Example: presets** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Presets = () => { return ( Label Clear
                    Last 7 days Last 30 days This month Last month
                    {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Presets = () => { return ( Label Clear
                    Last 7 days Last 30 days This month
                    {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear
                    Last 7 days Last 30 days This month
                    {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet}
                    ``` ### Min and Max Use the `min` and `max` props with `parseDate` to restrict the selectable date range. Dates outside this range will be disabled. **Example: min-max** #### React ```tsx import { DatePicker, parseDate } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MinMax = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker, parseDate } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MinMax = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Unavailable Use the `isDateUnavailable` prop to mark specific dates as unavailable. This example disables weekends. **Example: unavailable** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import type { DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const isWeekend = (date: DateValue) => { const dayOfWeek = date.toDate('UTC').getDay() return dayOfWeek === 0 || dayOfWeek === 6 } export const Unavailable = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import type { DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const isWeekend = (date: DateValue) => { const dayOfWeek = date.toDate('UTC').getDay() return dayOfWeek === 0 || dayOfWeek === 6 } export const Unavailable = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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.). **Example: locale** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Locale = () => { return ( Datum auswählen Löschen {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Locale = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: month-picker** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => { const month = date.month.toString().padStart(2, '0') const year = date.year.toString() return `${month}/${year}` } const parse = (string: string) => { const fullRegex = /^(\d{1,2})\/(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, month, year] = fullMatch.map(Number) return new CalendarDate(year, month, 1) } } export const MonthPicker = () => { return ( Label Clear {(datePicker) => ( {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => { const month = date.month.toString().padStart(2, '0') const year = date.year.toString() return `${month}/${year}` } const parse = (string: string) => { const fullRegex = /^(\d{1,2})\/(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, month, year] = fullMatch.map(Number) return new CalendarDate(year, month, 1) } } export const MonthPicker = () => { return ( Label Clear {(context) => ( {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: year-picker** #### React ```tsx import { DatePicker, parseDate } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import type { DateValue } from '@internationalized/date' import { CalendarIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => date.year.toString() const parse = (string: string | undefined) => { if (string === '' || !string) return const year = Number(string) if (year < 100) { const currentYear = new Date().getFullYear() const currentCentury = Math.floor(currentYear / 100) * 100 return parseDate(new Date(currentCentury + year, 0)) } return parseDate(new Date(Number(string), 0)) } export const YearPicker = () => { return ( Label Clear {(datePicker) => ( {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker, parseDate } from '@ark-ui/solid/date-picker' import type { DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => date.year.toString() const parse = (string: string | undefined) => { if (string === '' || !string) return const year = Number(string) if (year < 100) { const currentYear = new Date().getFullYear() const currentCentury = Math.floor(currentYear / 100) * 100 return parseDate(new Date(currentCentury + year, 0)) } return parseDate(new Date(Number(string), 0)) } export const YearPicker = () => { return ( Label Clear {(context) => ( {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: inline** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import styles from 'styles/date-picker.module.css' export const Inline = () => { return (
                    {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/date-picker.module.css' export const Inline = () => { return ( {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: format-parse** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const parse = (value: string) => { const fullRegex = /^(\d{1,2})\/(\d{1,2})\/(\d{2})$/ const fullMatch = value.match(fullRegex) if (fullMatch) { const [_, day, month, year] = fullMatch.map(Number) try { return new CalendarDate(year + 2000, month, day) } catch { return undefined } } const partialRegex = /^(\d{1,2})\/(\d{1,2})$/ const partialMatch = value.match(partialRegex) if (partialMatch) { const [_, day, month] = partialMatch.map(Number) const currentYear = new Date().getFullYear() try { return new CalendarDate(currentYear, month, day) } catch { return undefined } } const dayRegex = /^(\d{1,2})$/ const dayMatch = value.match(dayRegex) if (dayMatch) { const [_, day] = dayMatch.map(Number) const currentYear = new Date().getFullYear() return new CalendarDate(currentYear, 1, day) } return undefined } const format = (date: DateValue) => { const day = date.day.toString().padStart(2, '0') const month = date.month.toString().padStart(2, '0') const year = (date.year % 100).toString().padStart(2, '0') return `${day}/${month}/${year}` } export const FormatParse = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` ### 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. **Example: month-picker-range** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => { const month = date.month.toString().padStart(2, '0') const year = date.year.toString() return `${month}/${year}` } const parse = (string: string) => { const fullRegex = /^(\d{1,2})\/(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, month, year] = fullMatch.map(Number) return new CalendarDate(year, month, 1) } } export const MonthPickerRange = () => { return ( Label Clear {(datePicker) => ( {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => { const month = date.month.toString().padStart(2, '0') const year = date.year.toString() return `${month}/${year}` } const parse = (string: string) => { const fullRegex = /^(\d{1,2})\/(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, month, year] = fullMatch.map(Number) return new CalendarDate(year, month, 1) } } export const MonthPickerRange = () => { return ( Label Clear {(context) => ( {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: year-picker-range** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => date.year.toString() const parse = (string: string) => { const fullRegex = /^(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, year] = fullMatch.map(Number) return new CalendarDate(year, 1, 1) } } export const YearPickerRange = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.getDecade().start} - {datePicker.getDecade().end} {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => date.year.toString() const parse = (string: string | undefined) => { if (!string) return const fullRegex = /^(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, year] = fullMatch.map(Number) return new CalendarDate(year, 1, 1) } } export const YearPickerRange = () => { return ( Label Clear {(context) => ( <> {context().getDecade().start} - {context().getDecade().end} {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {datePicker().getDecade().start} - {datePicker().getDecade().end} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: with-time** #### React ```tsx import { CalendarDateTime, DateFormatter, getLocalTimeZone } from '@internationalized/date' import { DatePicker, type DatePickerValueChangeDetails } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const formatter = new DateFormatter('en-US', { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit', }) export const WithTime = () => { const [value, setValue] = useState([new CalendarDateTime(2025, 1, 29, 14, 30)]) const timeValue = value[0] ? `${String(value[0].hour).padStart(2, '0')}:${String(value[0].minute).padStart(2, '0')}` : '' const onTimeChange = (e: React.ChangeEvent) => { const [hours, minutes] = e.currentTarget.value.split(':').map(Number) setValue((prev) => { const current = prev[0] ?? new CalendarDateTime(2025, 1, 1, 0, 0) return [current.set({ hour: hours, minute: minutes })] }) } const onDateChange = (details: DatePickerValueChangeDetails) => { const newDate = details.value[0] if (!newDate) return setValue([]) const prevTime = value[0] ?? { hour: 0, minute: 0 } setValue([new CalendarDateTime(newDate.year, newDate.month, newDate.day, prevTime.hour, prevTime.minute)]) } return ( Date and time {value[0] ? formatter.format(value[0].toDate(getLocalTimeZone())) : 'Select date and time'} {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} ) } ``` #### Solid ```tsx import { CalendarDateTime, DateFormatter, getLocalTimeZone } from '@internationalized/date' import { DatePicker, type DatePickerValueChangeDetails } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const formatter = new DateFormatter('en-US', { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit', }) export const WithTime = () => { const [value, setValue] = createSignal([new CalendarDateTime(2025, 1, 29, 14, 30)]) const timeValue = () => { const v = value()[0] return v ? `${String(v.hour).padStart(2, '0')}:${String(v.minute).padStart(2, '0')}` : '' } const onTimeChange = (e: Event & { currentTarget: HTMLInputElement }) => { const [hours, minutes] = e.currentTarget.value.split(':').map(Number) setValue((prev) => { const current = prev[0] ?? new CalendarDateTime(2025, 1, 1, 0, 0) return [current.set({ hour: hours, minute: minutes })] }) } const onDateChange = (details: DatePickerValueChangeDetails) => { const newDate = details.value[0] if (!newDate) return setValue([]) const prevTime = value()[0] ?? { hour: 0, minute: 0 } setValue([new CalendarDateTime(newDate.year, newDate.month, newDate.day, prevTime.hour, prevTime.minute)]) } return ( Date and time {value()[0] ? formatter.format(value()[0].toDate(getLocalTimeZone())) : 'Select date and time'} {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Date and time {value[0] ? formatter.format(value[0].toDate(getLocalTimeZone())) : 'Select date and time'} {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the calendar should close after the date selection is complete. This is ignored when the selection mode is `multiple`. | | `defaultFocusedValue` | `DateValue` | No | The initial focused date when rendered. Use when you don't need to control the focused date of the date picker. | | `defaultOpen` | `boolean` | No | The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker. | | `defaultValue` | `DateValue[]` | No | The initial selected date(s) when rendered. Use when you don't need to control the selected date(s) of the date picker. | | `defaultView` | `DateView` | No | The default view of the calendar | | `disabled` | `boolean` | No | Whether the calendar is disabled. | | `fixedWeeks` | `boolean` | No | Whether the calendar should have a fixed number of weeks. This renders the calendar with 6 weeks instead of 5 or 6. | | `focusedValue` | `DateValue` | No | The controlled focused date. | | `format` | `(date: DateValue, details: LocaleDetails) => string` | No | The format of the date to display in the input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; label: (index: number) => string; table: (id: string) => string; tableHeader: (id: string) => string; tableBody: (id: string) => string; tableRow: (id: string) => string; content: string; ... 10 more ...; positioner: string; }>` | No | The ids of the elements in the date picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inline` | `boolean` | No | Whether to render the date picker inline | | `isDateUnavailable` | `(date: DateValue, locale: string) => boolean` | No | Returns whether a date of the calendar is available. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `locale` | `string` | No | The locale (BCP 47 language tag) to use when formatting the date. | | `max` | `DateValue` | No | The maximum date that can be selected. | | `maxView` | `DateView` | No | The maximum view of the calendar | | `min` | `DateValue` | No | The minimum date that can be selected. | | `minView` | `DateView` | No | The minimum view of the calendar | | `name` | `string` | No | The `name` attribute of the input element. | | `numOfMonths` | `number` | No | The number of months to display. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function called when the focused date changes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the calendar opens or closes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when the value changes. | | `onViewChange` | `(details: ViewChangeDetails) => void` | No | Function called when the view changes. | | `open` | `boolean` | No | The controlled open state of the date picker | | `outsideDaySelectable` | `boolean` | No | Whether day outside the visible range can be selected. | | `parse` | `(value: string, details: LocaleDetails) => DateValue | undefined` | No | Function to parse the date from the input back to a DateValue. | | `placeholder` | `string` | No | The placeholder text to display in the input. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the date picker content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the calendar is read-only. | | `selectionMode` | `SelectionMode` | No | The selection mode of the calendar. - `single` - only one date can be selected - `multiple` - multiple dates can be selected - `range` - a range of dates can be selected | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `startOfWeek` | `number` | No | The first day of the week. `0` - Sunday `1` - Monday `2` - Tuesday `3` - Wednesday `4` - Thursday `5` - Friday `6` - Saturday | | `timeZone` | `string` | No | The time zone to use | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `DateValue[]` | No | The controlled selected date(s). | | `view` | `DateView` | No | The view of the calendar | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | | `[data-inline]` | Present when the content is inline | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested date-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fixOnBlur` | `boolean` | No | Whether to fix the input value on blur. | | `index` | `number` | No | The index of the input to focus. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | input | | `[data-index]` | The index of the item | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | label | | `[data-state]` | "open" | "closed" | | `[data-index]` | The index of the item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **MonthSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **PresetTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PresetTriggerValue` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RangeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDatePickerReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **TableBody Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableBody Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-body | | `[data-view]` | The view of the tablebody | | `[data-disabled]` | Present when disabled | **TableCell Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number | DateValue` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `disabled` | `boolean` | No | | | `visibleRange` | `VisibleRange` | No | | **TableCellTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-head | | `[data-view]` | The view of the tablehead | | `[data-disabled]` | Present when disabled | **TableHeader Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHeader Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-header | | `[data-view]` | The view of the tableheader | | `[data-disabled]` | Present when disabled | **Table Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | **Table Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table | | `[data-columns]` | | | `[data-view]` | The view of the table | **TableRow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableRow Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-row | | `[data-disabled]` | Present when disabled | | `[data-view]` | The view of the tablerow | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | **ViewControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-control | | `[data-view]` | The view of the viewcontrol | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `view` | `DateView` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **View Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view | | `[data-view]` | The view of the view | **ViewTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-trigger | | `[data-view]` | The view of the viewtrigger | **YearSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the calendar should close after the date selection is complete. This is ignored when the selection mode is `multiple`. | | `defaultFocusedValue` | `DateValue` | No | The initial focused date when rendered. Use when you don't need to control the focused date of the date picker. | | `defaultOpen` | `boolean` | No | The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker. | | `defaultValue` | `DateValue[]` | No | The initial selected date(s) when rendered. Use when you don't need to control the selected date(s) of the date picker. | | `defaultView` | `DateView` | No | The default view of the calendar | | `disabled` | `boolean` | No | Whether the calendar is disabled. | | `fixedWeeks` | `boolean` | No | Whether the calendar should have a fixed number of weeks. This renders the calendar with 6 weeks instead of 5 or 6. | | `focusedValue` | `DateValue` | No | The controlled focused date. | | `format` | `(date: DateValue, details: LocaleDetails) => string` | No | The format of the date to display in the input. | | `ids` | `Partial<{ root: string; label: (index: number) => string; table: (id: string) => string; tableHeader: (id: string) => string; tableBody: (id: string) => string; tableRow: (id: string) => string; content: string; ... 10 more ...; positioner: string; }>` | No | The ids of the elements in the date picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inline` | `boolean` | No | Whether to render the date picker inline | | `isDateUnavailable` | `(date: DateValue, locale: string) => boolean` | No | Returns whether a date of the calendar is available. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `locale` | `string` | No | The locale (BCP 47 language tag) to use when formatting the date. | | `max` | `DateValue` | No | The maximum date that can be selected. | | `maxView` | `DateView` | No | The maximum view of the calendar | | `min` | `DateValue` | No | The minimum date that can be selected. | | `minView` | `DateView` | No | The minimum view of the calendar | | `name` | `string` | No | The `name` attribute of the input element. | | `numOfMonths` | `number` | No | The number of months to display. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function called when the focused date changes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the calendar opens or closes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when the value changes. | | `onViewChange` | `(details: ViewChangeDetails) => void` | No | Function called when the view changes. | | `open` | `boolean` | No | The controlled open state of the date picker | | `outsideDaySelectable` | `boolean` | No | Whether day outside the visible range can be selected. | | `parse` | `(value: string, details: LocaleDetails) => DateValue | undefined` | No | Function to parse the date from the input back to a DateValue. | | `placeholder` | `string` | No | The placeholder text to display in the input. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the date picker content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the calendar is read-only. | | `selectionMode` | `SelectionMode` | No | The selection mode of the calendar. - `single` - only one date can be selected - `multiple` - multiple dates can be selected - `range` - a range of dates can be selected | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `startOfWeek` | `number` | No | The first day of the week. `0` - Sunday `1` - Monday `2` - Tuesday `3` - Wednesday `4` - Thursday `5` - Friday `6` - Saturday | | `timeZone` | `string` | No | The time zone to use | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `DateValue[]` | No | The controlled selected date(s). | | `view` | `DateView` | No | The view of the calendar | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | | `[data-inline]` | Present when the content is inline | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested date-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fixOnBlur` | `boolean` | No | Whether to fix the input value on blur. | | `index` | `number` | No | The index of the input to focus. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | input | | `[data-index]` | The index of the item | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | label | | `[data-state]` | "open" | "closed" | | `[data-index]` | The index of the item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **MonthSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **PresetTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PresetTriggerValue` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RangeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDatePickerReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **TableBody Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'tbody'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableBody Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-body | | `[data-view]` | The view of the tablebody | | `[data-disabled]` | Present when disabled | **TableCell Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number | DateValue` | Yes | | | `asChild` | `(props: ParentProps<'td'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `disabled` | `boolean` | No | | | `visibleRange` | `VisibleRange` | No | | **TableCellTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'thead'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-head | | `[data-view]` | The view of the tablehead | | `[data-disabled]` | Present when disabled | **TableHeader Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'th'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHeader Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-header | | `[data-view]` | The view of the tableheader | | `[data-disabled]` | Present when disabled | **Table Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'table'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | **Table Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table | | `[data-columns]` | | | `[data-view]` | The view of the table | **TableRow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'tr'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableRow Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-row | | `[data-disabled]` | Present when disabled | | `[data-view]` | The view of the tablerow | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | **ViewControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-control | | `[data-view]` | The view of the viewcontrol | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `view` | `DateView` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **View Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view | | `[data-view]` | The view of the view | **ViewTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-trigger | | `[data-view]` | The view of the viewtrigger | **YearSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the calendar should close after the date selection is complete. This is ignored when the selection mode is `multiple`. | | `defaultFocusedValue` | `DateValue` | No | The initial focused date when rendered. Use when you don't need to control the focused date of the date picker. | | `defaultOpen` | `boolean` | No | The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker. | | `defaultValue` | `DateValue[]` | No | The initial selected date(s) when rendered. Use when you don't need to control the selected date(s) of the date picker. | | `defaultView` | `DateView` | No | The default view of the calendar | | `disabled` | `boolean` | No | Whether the calendar is disabled. | | `fixedWeeks` | `boolean` | No | Whether the calendar should have a fixed number of weeks. This renders the calendar with 6 weeks instead of 5 or 6. | | `focusedValue` | `DateValue` | No | The controlled focused date. | | `format` | `(date: DateValue, details: LocaleDetails) => string` | No | The format of the date to display in the input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; label(index: number): string; table(id: string): string; tableHeader(id: string): string; tableBody(id: string): string; tableRow(id: string): string; content: string; ... 10 more ...; positioner: string; }>` | No | The ids of the elements in the date picker. Useful for composition. | | `inline` | `boolean` | No | Whether the date picker is inline | | `isDateUnavailable` | `(date: DateValue, locale: string) => boolean` | No | Returns whether a date of the calendar is available. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `locale` | `string` | No | The locale (BCP 47 language tag) to use when formatting the date. | | `max` | `DateValue` | No | The maximum date that can be selected. | | `maxView` | `DateView` | No | The maximum view of the calendar | | `min` | `DateValue` | No | The minimum date that can be selected. | | `minView` | `DateView` | No | The minimum view of the calendar | | `modelValue` | `DateValue[]` | No | The v-model value of the date picker | | `name` | `string` | No | The `name` attribute of the input element. | | `numOfMonths` | `number` | No | The number of months to display. | | `open` | `boolean` | No | The controlled open state of the date picker | | `outsideDaySelectable` | `boolean` | No | Whether day outside the visible range can be selected. | | `parse` | `(value: string, details: LocaleDetails) => DateValue | undefined` | No | Function to parse the date from the input back to a DateValue. | | `placeholder` | `string` | No | The placeholder text to display in the input. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the date picker content | | `readOnly` | `boolean` | No | Whether the calendar is read-only. | | `selectionMode` | `SelectionMode` | No | The selection mode of the calendar. - `single` - only one date can be selected - `multiple` - multiple dates can be selected - `range` - a range of dates can be selected | | `startOfWeek` | `number` | No | The first day of the week. `0` - Sunday `1` - Monday `2` - Tuesday `3` - Wednesday `4` - Thursday `5` - Friday `6` - Saturday | | `timeZone` | `string` | No | The time zone to use | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `view` | `DateView` | No | The view of the calendar | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | | `[data-inline]` | Present when the content is inline | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested date-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fixOnBlur` | `boolean` | No | Whether to fix the input value on blur. | | `index` | `number` | No | The index of the input to focus. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | input | | `[data-index]` | The index of the item | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | label | | `[data-state]` | "open" | "closed" | | `[data-index]` | The index of the item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **MonthSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **PresetTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PresetTriggerValue` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RangeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `DatePickerApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **TableBody Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableBody Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-body | | `[data-view]` | The view of the tablebody | | `[data-disabled]` | Present when disabled | **TableCell Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `Reactive` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `disabled` | `boolean` | No | | | `visibleRange` | `VisibleRange` | No | | **TableCellTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-head | | `[data-view]` | The view of the tablehead | | `[data-disabled]` | Present when disabled | **TableHeader Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHeader Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-header | | `[data-view]` | The view of the tableheader | | `[data-disabled]` | Present when disabled | **Table Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `id` | `string` | No | | | `view` | `DateView` | No | | **Table Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table | | `[data-columns]` | | | `[data-view]` | The view of the table | **TableRow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableRow Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-row | | `[data-disabled]` | Present when disabled | | `[data-view]` | The view of the tablerow | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | **ViewControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-control | | `[data-view]` | The view of the viewcontrol | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `view` | `DateView` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **View Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view | | `[data-view]` | The view of the view | **ViewTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-trigger | | `[data-view]` | The view of the viewtrigger | **YearSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the calendar should close after the date selection is complete. This is ignored when the selection mode is `multiple`. | | `defaultFocusedValue` | `DateValue` | No | The initial focused date when rendered. Use when you don't need to control the focused date of the date picker. | | `defaultOpen` | `boolean` | No | The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker. | | `defaultValue` | `DateValue[]` | No | The initial selected date(s) when rendered. Use when you don't need to control the selected date(s) of the date picker. | | `defaultView` | `DateView` | No | The default view of the calendar | | `disabled` | `boolean` | No | Whether the calendar is disabled. | | `fixedWeeks` | `boolean` | No | Whether the calendar should have a fixed number of weeks. This renders the calendar with 6 weeks instead of 5 or 6. | | `focusedValue` | `DateValue` | No | The controlled focused date. | | `format` | `(date: DateValue, details: LocaleDetails) => string` | No | The format of the date to display in the input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; label: (index: number) => string; table: (id: string) => string; tableHeader: (id: string) => string; tableBody: (id: string) => string; tableRow: (id: string) => string; content: string; ... 10 more ...; positioner: string; }>` | No | The ids of the elements in the date picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inline` | `boolean` | No | Whether to render the date picker inline | | `isDateUnavailable` | `(date: DateValue, locale: string) => boolean` | No | Returns whether a date of the calendar is available. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `locale` | `string` | No | The locale (BCP 47 language tag) to use when formatting the date. | | `max` | `DateValue` | No | The maximum date that can be selected. | | `maxView` | `DateView` | No | The maximum view of the calendar | | `min` | `DateValue` | No | The minimum date that can be selected. | | `minView` | `DateView` | No | The minimum view of the calendar | | `name` | `string` | No | The `name` attribute of the input element. | | `numOfMonths` | `number` | No | The number of months to display. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function called when the focused date changes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the calendar opens or closes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when the value changes. | | `onViewChange` | `(details: ViewChangeDetails) => void` | No | Function called when the view changes. | | `open` | `boolean` | No | The controlled open state of the date picker | | `outsideDaySelectable` | `boolean` | No | Whether day outside the visible range can be selected. | | `parse` | `(value: string, details: LocaleDetails) => DateValue | undefined` | No | Function to parse the date from the input back to a DateValue. | | `placeholder` | `string` | No | The placeholder text to display in the input. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the date picker content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the calendar is read-only. | | `ref` | `Element` | No | | | `selectionMode` | `SelectionMode` | No | The selection mode of the calendar. - `single` - only one date can be selected - `multiple` - multiple dates can be selected - `range` - a range of dates can be selected | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `startOfWeek` | `number` | No | The first day of the week. `0` - Sunday `1` - Monday `2` - Tuesday `3` - Wednesday `4` - Thursday `5` - Friday `6` - Saturday | | `timeZone` | `string` | No | The time zone to use | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `DateValue[]` | No | The controlled selected date(s). | | `view` | `DateView` | No | The view of the calendar | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | | `[data-inline]` | Present when the content is inline | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested date-pickers | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseDatePickerContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fixOnBlur` | `boolean` | No | Whether to fix the input value on blur. | | `index` | `number` | No | The index of the input to focus. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | input | | `[data-index]` | The index of the item | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | label | | `[data-state]` | "open" | "closed" | | `[data-index]` | The index of the item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **MonthSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **PresetTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PresetTriggerValue` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RangeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDatePickerReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **TableBody Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'tbody'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableBody Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-body | | `[data-view]` | The view of the tablebody | | `[data-disabled]` | Present when disabled | **TableCell Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number | DateValue` | Yes | | | `asChild` | `Snippet<[PropsFn<'td'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `disabled` | `boolean` | No | | | `ref` | `Element` | No | | | `visibleRange` | `VisibleRange` | No | | **TableCellTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableHead Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'thead'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableHead Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-head | | `[data-view]` | The view of the tablehead | | `[data-disabled]` | Present when disabled | **TableHeader Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'th'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableHeader Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-header | | `[data-view]` | The view of the tableheader | | `[data-disabled]` | Present when disabled | **Table Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'table'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | **Table Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table | | `[data-columns]` | | | `[data-view]` | The view of the table | **TableRow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'tr'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableRow Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-row | | `[data-disabled]` | Present when disabled | | `[data-view]` | The view of the tablerow | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | **ViewControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ViewControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-control | | `[data-view]` | The view of the viewcontrol | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `view` | `DateView` | No | | **View Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view | | `[data-view]` | The view of the view | **ViewTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ViewTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-trigger | | `[data-view]` | The view of the viewtrigger | **YearSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focused` | `boolean` | Whether the input is focused | | `open` | `boolean` | Whether the date picker is open | | `disabled` | `boolean` | Whether the date picker is disabled | | `invalid` | `boolean` | Whether the date picker is invalid | | `inline` | `boolean` | Whether the date picker is rendered inline | | `view` | `DateView` | The current view of the date picker | | `getDaysInWeek` | `(week: number, from?: DateValue) => DateValue[]` | Returns an array of days in the week index counted from the provided start date, or the first visible date if not given. | | `getOffset` | `(duration: DateDuration) => DateValueOffset` | Returns the offset of the month based on the provided number of months. | | `getRangePresetValue` | `(value: DateRangePreset) => DateValue[]` | Returns the range of dates based on the provided date range preset. | | `getMonthWeeks` | `(from?: DateValue) => DateValue[][]` | Returns the weeks of the month from the provided date. Represented as an array of arrays of dates. | | `isUnavailable` | `(date: DateValue) => boolean` | Returns whether the provided date is available (or can be selected) | | `weeks` | `DateValue[][]` | The weeks of the month. Represented as an array of arrays of dates. | | `weekDays` | `WeekDay[]` | The days of the week. Represented as an array of strings. | | `visibleRange` | `VisibleRange` | The visible range of dates. | | `visibleRangeText` | `VisibleRangeText` | The human readable text for the visible range of dates. | | `value` | `DateValue[]` | The selected date. | | `valueAsDate` | `Date[]` | The selected date as a Date object. | | `valueAsString` | `string[]` | The selected date as a string. | | `focusedValue` | `DateValue` | The focused date. | | `focusedValueAsDate` | `Date` | The focused date as a Date object. | | `focusedValueAsString` | `string` | The focused date as a string. | | `selectToday` | `VoidFunction` | Sets the selected date to today. | | `setValue` | `(values: DateValue[]) => void` | Sets the selected date to the given date. | | `setFocusedValue` | `(value: DateValue) => void` | Sets the focused date to the given date. | | `clearValue` | `VoidFunction` | Clears the selected date(s). | | `setOpen` | `(open: boolean) => void` | Function to open or close the calendar. | | `focusMonth` | `(month: number) => void` | Function to set the selected month. | | `focusYear` | `(year: number) => void` | Function to set the selected year. | | `getYears` | `() => Cell[]` | Returns the months of the year | | `getYearsGrid` | `(props?: YearGridProps) => YearGridValue` | Returns the years of the decade based on the columns. Represented as an array of arrays of years. | | `getDecade` | `() => Range` | Returns the start and end years of the decade. | | `getMonths` | `(props?: MonthFormatOptions) => Cell[]` | Returns the months of the year | | `getMonthsGrid` | `(props?: MonthGridProps) => MonthGridValue` | Returns the months of the year based on the columns. Represented as an array of arrays of months. | | `format` | `(value: DateValue, opts?: Intl.DateTimeFormatOptions) => string` | Formats the given date value based on the provided options. | | `setView` | `(view: DateView) => void` | Sets the view of the date picker. | | `goToNext` | `VoidFunction` | Goes to the next month/year/decade. | | `goToPrev` | `VoidFunction` | Goes to the previous month/year/decade. | | `getDayTableCellState` | `(props: DayTableCellProps) => DayTableCellState` | Returns the state details for a given cell. | | `getMonthTableCellState` | `(props: TableCellProps) => TableCellState` | Returns the state details for a given month cell. | | `getYearTableCellState` | `(props: TableCellProps) => TableCellState` | Returns the state details for a given year cell. | ## Accessibility ### Keyboard Support **`ArrowLeft`** Description: Moves focus to the previous day within the current week. **`ArrowRight`** Description: Moves focus to the next day within the current week. **`ArrowUp`** Description: Moves focus to the same day of the week in the previous week. **`ArrowDown`** Description: Moves focus to the same day of the week in the next week. **`Home`** Description: Moves focus to the first day of the current month. **`End`** Description: Moves focus to the last day of the current month. **`PageUp`** Description: Moves focus to the same day of the month in the previous month. **`PageDown`** Description: Moves focus to the same day of the month in the next month. **`Enter`** Description: Selects the focused date and closes the date picker. **`Esc`** Description: Closes the date picker without selecting any date. --- # Date Picker (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Basic = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Basic = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Default Value Use the `defaultValue` prop with `parseDate` to set the initial date value. **Example: default-value** #### React ```tsx import { DatePicker, parseDate } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const DefaultValue = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker, parseDate } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const DefaultValue = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Controlled Use the `value` and `onValueChange` props to control the date picker's value programmatically. **Example: controlled** #### React ```tsx import { DatePicker, parseDate } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Controlled = () => { const [value, setValue] = useState([parseDate('2022-01-01')]) return ( setValue(e.value)}> Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker, parseDate } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Controlled = () => { const [value, setValue] = createSignal([parseDate('2022-01-01')]) return ( setValue(e.value)}> Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: root-provider** #### React ```tsx import { DatePicker, useDatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const RootProvider = () => { const datePicker = useDatePicker() return (
                    Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker, useDatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const RootProvider = () => { const datePicker = useDatePicker() return ( <> Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Default View Use the `defaultView` prop to set which view (day, month, or year) the calendar opens to initially. **Example: default-view** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const DefaultView = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const DefaultView = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: month-year-select** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import styles from 'styles/date-picker.module.css' export const MonthYearSelect = () => { return ( Label {(datePicker) => ( <>
                    {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/date-picker.module.css' export const MonthYearSelect = () => { return ( Label {(context) => ( <>
                    {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(datePicker)}
                    {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet}
                    ``` ### 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`. **Example: range-selection** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const RangeSelection = () => { return ( Label Clear Last 7 days {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon } from 'lucide-solid' import { Index, createMemo } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const RangeSelection = () => { return ( Label Clear Last 7 days
                    {(context) => ( {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => { const offset = createMemo(() => context().getOffset({ months: 1 })) return ( {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear Last 7 days {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Multiple Use the `selectionMode="multiple"` prop to allow selecting multiple dates. This example also shows how to display selected dates as removable tags. **Example: multi-selection** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import type { DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const formatWithDay = (date: DateValue) => { const jsDate = date.toDate('UTC') return jsDate.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric', }) } export const MultiSelection = () => { return ( Label {(datePicker) => (
                    {datePicker.value.length === 0 ? ( Select dates... ) : ( datePicker.value.map((date, index) => ( {formatWithDay(date)} )) )}
                    )}
                    Clear
                    {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { For, Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MultiSelection = () => { return ( Label {(context) => (
                    {context().value.length === 0 ? ( Select dates... ) : ( {(date, index) => ( {date.toDate('UTC').toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric', })} )} )}
                    )}
                    Clear
                    {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: multiple-months** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MultipleMonths = () => { return ( Label Clear
                    {(datePicker) => ( {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => { const offset = datePicker.getOffset({ months: 1 }) return ( {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {offset.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} ) }}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index, createMemo } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MultipleMonths = () => { return ( Label Clear
                    {(datePicker) => ( {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(datePicker) => { const offset = createMemo(() => datePicker().getOffset({ months: 1 })) return ( {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear
                    {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay, id (id)} {weekDay.short} {/each} {#each datePicker().weeks as week, id} {#each week as day, id (id)} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {@const offset = datePicker().getOffset({ months: 1 })} {#each datePicker().weekDays as weekDay, id (id)} {weekDay.short} {/each} {#each offset.weeks as week, id (id)} {#each week as day, id (id)} {day.day} {/each} {/each} {/snippet}
                    ``` ### Presets Use the `DatePicker.PresetTrigger` component to add quick-select preset options like "Last 7 days" or "This month". **Example: presets** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Presets = () => { return ( Label Clear
                    Last 7 days Last 30 days This month Last month
                    {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Presets = () => { return ( Label Clear
                    Last 7 days Last 30 days This month
                    {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear
                    Last 7 days Last 30 days This month
                    {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet}
                    ``` ### Min and Max Use the `min` and `max` props with `parseDate` to restrict the selectable date range. Dates outside this range will be disabled. **Example: min-max** #### React ```tsx import { DatePicker, parseDate } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MinMax = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker, parseDate } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MinMax = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Unavailable Use the `isDateUnavailable` prop to mark specific dates as unavailable. This example disables weekends. **Example: unavailable** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import type { DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const isWeekend = (date: DateValue) => { const dayOfWeek = date.toDate('UTC').getDay() return dayOfWeek === 0 || dayOfWeek === 6 } export const Unavailable = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import type { DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const isWeekend = (date: DateValue) => { const dayOfWeek = date.toDate('UTC').getDay() return dayOfWeek === 0 || dayOfWeek === 6 } export const Unavailable = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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.). **Example: locale** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Locale = () => { return ( Datum auswählen Löschen {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Locale = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: month-picker** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => { const month = date.month.toString().padStart(2, '0') const year = date.year.toString() return `${month}/${year}` } const parse = (string: string) => { const fullRegex = /^(\d{1,2})\/(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, month, year] = fullMatch.map(Number) return new CalendarDate(year, month, 1) } } export const MonthPicker = () => { return ( Label Clear {(datePicker) => ( {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => { const month = date.month.toString().padStart(2, '0') const year = date.year.toString() return `${month}/${year}` } const parse = (string: string) => { const fullRegex = /^(\d{1,2})\/(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, month, year] = fullMatch.map(Number) return new CalendarDate(year, month, 1) } } export const MonthPicker = () => { return ( Label Clear {(context) => ( {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: year-picker** #### React ```tsx import { DatePicker, parseDate } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import type { DateValue } from '@internationalized/date' import { CalendarIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => date.year.toString() const parse = (string: string | undefined) => { if (string === '' || !string) return const year = Number(string) if (year < 100) { const currentYear = new Date().getFullYear() const currentCentury = Math.floor(currentYear / 100) * 100 return parseDate(new Date(currentCentury + year, 0)) } return parseDate(new Date(Number(string), 0)) } export const YearPicker = () => { return ( Label Clear {(datePicker) => ( {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker, parseDate } from '@ark-ui/solid/date-picker' import type { DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => date.year.toString() const parse = (string: string | undefined) => { if (string === '' || !string) return const year = Number(string) if (year < 100) { const currentYear = new Date().getFullYear() const currentCentury = Math.floor(currentYear / 100) * 100 return parseDate(new Date(currentCentury + year, 0)) } return parseDate(new Date(Number(string), 0)) } export const YearPicker = () => { return ( Label Clear {(context) => ( {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: inline** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import styles from 'styles/date-picker.module.css' export const Inline = () => { return (
                    {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/date-picker.module.css' export const Inline = () => { return ( {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: format-parse** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const parse = (value: string) => { const fullRegex = /^(\d{1,2})\/(\d{1,2})\/(\d{2})$/ const fullMatch = value.match(fullRegex) if (fullMatch) { const [_, day, month, year] = fullMatch.map(Number) try { return new CalendarDate(year + 2000, month, day) } catch { return undefined } } const partialRegex = /^(\d{1,2})\/(\d{1,2})$/ const partialMatch = value.match(partialRegex) if (partialMatch) { const [_, day, month] = partialMatch.map(Number) const currentYear = new Date().getFullYear() try { return new CalendarDate(currentYear, month, day) } catch { return undefined } } const dayRegex = /^(\d{1,2})$/ const dayMatch = value.match(dayRegex) if (dayMatch) { const [_, day] = dayMatch.map(Number) const currentYear = new Date().getFullYear() return new CalendarDate(currentYear, 1, day) } return undefined } const format = (date: DateValue) => { const day = date.day.toString().padStart(2, '0') const month = date.month.toString().padStart(2, '0') const year = (date.year % 100).toString().padStart(2, '0') return `${day}/${month}/${year}` } export const FormatParse = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` ### 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. **Example: month-picker-range** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => { const month = date.month.toString().padStart(2, '0') const year = date.year.toString() return `${month}/${year}` } const parse = (string: string) => { const fullRegex = /^(\d{1,2})\/(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, month, year] = fullMatch.map(Number) return new CalendarDate(year, month, 1) } } export const MonthPickerRange = () => { return ( Label Clear {(datePicker) => ( {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => { const month = date.month.toString().padStart(2, '0') const year = date.year.toString() return `${month}/${year}` } const parse = (string: string) => { const fullRegex = /^(\d{1,2})\/(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, month, year] = fullMatch.map(Number) return new CalendarDate(year, month, 1) } } export const MonthPickerRange = () => { return ( Label Clear {(context) => ( {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: year-picker-range** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => date.year.toString() const parse = (string: string) => { const fullRegex = /^(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, year] = fullMatch.map(Number) return new CalendarDate(year, 1, 1) } } export const YearPickerRange = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.getDecade().start} - {datePicker.getDecade().end} {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => date.year.toString() const parse = (string: string | undefined) => { if (!string) return const fullRegex = /^(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, year] = fullMatch.map(Number) return new CalendarDate(year, 1, 1) } } export const YearPickerRange = () => { return ( Label Clear {(context) => ( <> {context().getDecade().start} - {context().getDecade().end} {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {datePicker().getDecade().start} - {datePicker().getDecade().end} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: with-time** #### React ```tsx import { CalendarDateTime, DateFormatter, getLocalTimeZone } from '@internationalized/date' import { DatePicker, type DatePickerValueChangeDetails } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const formatter = new DateFormatter('en-US', { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit', }) export const WithTime = () => { const [value, setValue] = useState([new CalendarDateTime(2025, 1, 29, 14, 30)]) const timeValue = value[0] ? `${String(value[0].hour).padStart(2, '0')}:${String(value[0].minute).padStart(2, '0')}` : '' const onTimeChange = (e: React.ChangeEvent) => { const [hours, minutes] = e.currentTarget.value.split(':').map(Number) setValue((prev) => { const current = prev[0] ?? new CalendarDateTime(2025, 1, 1, 0, 0) return [current.set({ hour: hours, minute: minutes })] }) } const onDateChange = (details: DatePickerValueChangeDetails) => { const newDate = details.value[0] if (!newDate) return setValue([]) const prevTime = value[0] ?? { hour: 0, minute: 0 } setValue([new CalendarDateTime(newDate.year, newDate.month, newDate.day, prevTime.hour, prevTime.minute)]) } return ( Date and time {value[0] ? formatter.format(value[0].toDate(getLocalTimeZone())) : 'Select date and time'} {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} ) } ``` #### Solid ```tsx import { CalendarDateTime, DateFormatter, getLocalTimeZone } from '@internationalized/date' import { DatePicker, type DatePickerValueChangeDetails } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const formatter = new DateFormatter('en-US', { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit', }) export const WithTime = () => { const [value, setValue] = createSignal([new CalendarDateTime(2025, 1, 29, 14, 30)]) const timeValue = () => { const v = value()[0] return v ? `${String(v.hour).padStart(2, '0')}:${String(v.minute).padStart(2, '0')}` : '' } const onTimeChange = (e: Event & { currentTarget: HTMLInputElement }) => { const [hours, minutes] = e.currentTarget.value.split(':').map(Number) setValue((prev) => { const current = prev[0] ?? new CalendarDateTime(2025, 1, 1, 0, 0) return [current.set({ hour: hours, minute: minutes })] }) } const onDateChange = (details: DatePickerValueChangeDetails) => { const newDate = details.value[0] if (!newDate) return setValue([]) const prevTime = value()[0] ?? { hour: 0, minute: 0 } setValue([new CalendarDateTime(newDate.year, newDate.month, newDate.day, prevTime.hour, prevTime.minute)]) } return ( Date and time {value()[0] ? formatter.format(value()[0].toDate(getLocalTimeZone())) : 'Select date and time'} {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Date and time {value[0] ? formatter.format(value[0].toDate(getLocalTimeZone())) : 'Select date and time'} {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the calendar should close after the date selection is complete. This is ignored when the selection mode is `multiple`. | | `defaultFocusedValue` | `DateValue` | No | The initial focused date when rendered. Use when you don't need to control the focused date of the date picker. | | `defaultOpen` | `boolean` | No | The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker. | | `defaultValue` | `DateValue[]` | No | The initial selected date(s) when rendered. Use when you don't need to control the selected date(s) of the date picker. | | `defaultView` | `DateView` | No | The default view of the calendar | | `disabled` | `boolean` | No | Whether the calendar is disabled. | | `fixedWeeks` | `boolean` | No | Whether the calendar should have a fixed number of weeks. This renders the calendar with 6 weeks instead of 5 or 6. | | `focusedValue` | `DateValue` | No | The controlled focused date. | | `format` | `(date: DateValue, details: LocaleDetails) => string` | No | The format of the date to display in the input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; label: (index: number) => string; table: (id: string) => string; tableHeader: (id: string) => string; tableBody: (id: string) => string; tableRow: (id: string) => string; content: string; ... 10 more ...; positioner: string; }>` | No | The ids of the elements in the date picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inline` | `boolean` | No | Whether to render the date picker inline | | `isDateUnavailable` | `(date: DateValue, locale: string) => boolean` | No | Returns whether a date of the calendar is available. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `locale` | `string` | No | The locale (BCP 47 language tag) to use when formatting the date. | | `max` | `DateValue` | No | The maximum date that can be selected. | | `maxView` | `DateView` | No | The maximum view of the calendar | | `min` | `DateValue` | No | The minimum date that can be selected. | | `minView` | `DateView` | No | The minimum view of the calendar | | `name` | `string` | No | The `name` attribute of the input element. | | `numOfMonths` | `number` | No | The number of months to display. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function called when the focused date changes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the calendar opens or closes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when the value changes. | | `onViewChange` | `(details: ViewChangeDetails) => void` | No | Function called when the view changes. | | `open` | `boolean` | No | The controlled open state of the date picker | | `outsideDaySelectable` | `boolean` | No | Whether day outside the visible range can be selected. | | `parse` | `(value: string, details: LocaleDetails) => DateValue | undefined` | No | Function to parse the date from the input back to a DateValue. | | `placeholder` | `string` | No | The placeholder text to display in the input. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the date picker content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the calendar is read-only. | | `selectionMode` | `SelectionMode` | No | The selection mode of the calendar. - `single` - only one date can be selected - `multiple` - multiple dates can be selected - `range` - a range of dates can be selected | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `startOfWeek` | `number` | No | The first day of the week. `0` - Sunday `1` - Monday `2` - Tuesday `3` - Wednesday `4` - Thursday `5` - Friday `6` - Saturday | | `timeZone` | `string` | No | The time zone to use | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `DateValue[]` | No | The controlled selected date(s). | | `view` | `DateView` | No | The view of the calendar | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | | `[data-inline]` | Present when the content is inline | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested date-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fixOnBlur` | `boolean` | No | Whether to fix the input value on blur. | | `index` | `number` | No | The index of the input to focus. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | input | | `[data-index]` | The index of the item | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | label | | `[data-state]` | "open" | "closed" | | `[data-index]` | The index of the item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **MonthSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **PresetTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PresetTriggerValue` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RangeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDatePickerReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **TableBody Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableBody Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-body | | `[data-view]` | The view of the tablebody | | `[data-disabled]` | Present when disabled | **TableCell Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number | DateValue` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `disabled` | `boolean` | No | | | `visibleRange` | `VisibleRange` | No | | **TableCellTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-head | | `[data-view]` | The view of the tablehead | | `[data-disabled]` | Present when disabled | **TableHeader Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHeader Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-header | | `[data-view]` | The view of the tableheader | | `[data-disabled]` | Present when disabled | **Table Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | **Table Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table | | `[data-columns]` | | | `[data-view]` | The view of the table | **TableRow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableRow Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-row | | `[data-disabled]` | Present when disabled | | `[data-view]` | The view of the tablerow | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | **ViewControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-control | | `[data-view]` | The view of the viewcontrol | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `view` | `DateView` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **View Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view | | `[data-view]` | The view of the view | **ViewTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-trigger | | `[data-view]` | The view of the viewtrigger | **YearSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the calendar should close after the date selection is complete. This is ignored when the selection mode is `multiple`. | | `defaultFocusedValue` | `DateValue` | No | The initial focused date when rendered. Use when you don't need to control the focused date of the date picker. | | `defaultOpen` | `boolean` | No | The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker. | | `defaultValue` | `DateValue[]` | No | The initial selected date(s) when rendered. Use when you don't need to control the selected date(s) of the date picker. | | `defaultView` | `DateView` | No | The default view of the calendar | | `disabled` | `boolean` | No | Whether the calendar is disabled. | | `fixedWeeks` | `boolean` | No | Whether the calendar should have a fixed number of weeks. This renders the calendar with 6 weeks instead of 5 or 6. | | `focusedValue` | `DateValue` | No | The controlled focused date. | | `format` | `(date: DateValue, details: LocaleDetails) => string` | No | The format of the date to display in the input. | | `ids` | `Partial<{ root: string; label: (index: number) => string; table: (id: string) => string; tableHeader: (id: string) => string; tableBody: (id: string) => string; tableRow: (id: string) => string; content: string; ... 10 more ...; positioner: string; }>` | No | The ids of the elements in the date picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inline` | `boolean` | No | Whether to render the date picker inline | | `isDateUnavailable` | `(date: DateValue, locale: string) => boolean` | No | Returns whether a date of the calendar is available. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `locale` | `string` | No | The locale (BCP 47 language tag) to use when formatting the date. | | `max` | `DateValue` | No | The maximum date that can be selected. | | `maxView` | `DateView` | No | The maximum view of the calendar | | `min` | `DateValue` | No | The minimum date that can be selected. | | `minView` | `DateView` | No | The minimum view of the calendar | | `name` | `string` | No | The `name` attribute of the input element. | | `numOfMonths` | `number` | No | The number of months to display. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function called when the focused date changes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the calendar opens or closes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when the value changes. | | `onViewChange` | `(details: ViewChangeDetails) => void` | No | Function called when the view changes. | | `open` | `boolean` | No | The controlled open state of the date picker | | `outsideDaySelectable` | `boolean` | No | Whether day outside the visible range can be selected. | | `parse` | `(value: string, details: LocaleDetails) => DateValue | undefined` | No | Function to parse the date from the input back to a DateValue. | | `placeholder` | `string` | No | The placeholder text to display in the input. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the date picker content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the calendar is read-only. | | `selectionMode` | `SelectionMode` | No | The selection mode of the calendar. - `single` - only one date can be selected - `multiple` - multiple dates can be selected - `range` - a range of dates can be selected | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `startOfWeek` | `number` | No | The first day of the week. `0` - Sunday `1` - Monday `2` - Tuesday `3` - Wednesday `4` - Thursday `5` - Friday `6` - Saturday | | `timeZone` | `string` | No | The time zone to use | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `DateValue[]` | No | The controlled selected date(s). | | `view` | `DateView` | No | The view of the calendar | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | | `[data-inline]` | Present when the content is inline | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested date-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fixOnBlur` | `boolean` | No | Whether to fix the input value on blur. | | `index` | `number` | No | The index of the input to focus. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | input | | `[data-index]` | The index of the item | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | label | | `[data-state]` | "open" | "closed" | | `[data-index]` | The index of the item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **MonthSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **PresetTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PresetTriggerValue` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RangeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDatePickerReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **TableBody Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'tbody'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableBody Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-body | | `[data-view]` | The view of the tablebody | | `[data-disabled]` | Present when disabled | **TableCell Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number | DateValue` | Yes | | | `asChild` | `(props: ParentProps<'td'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `disabled` | `boolean` | No | | | `visibleRange` | `VisibleRange` | No | | **TableCellTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'thead'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-head | | `[data-view]` | The view of the tablehead | | `[data-disabled]` | Present when disabled | **TableHeader Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'th'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHeader Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-header | | `[data-view]` | The view of the tableheader | | `[data-disabled]` | Present when disabled | **Table Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'table'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | **Table Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table | | `[data-columns]` | | | `[data-view]` | The view of the table | **TableRow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'tr'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableRow Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-row | | `[data-disabled]` | Present when disabled | | `[data-view]` | The view of the tablerow | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | **ViewControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-control | | `[data-view]` | The view of the viewcontrol | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `view` | `DateView` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **View Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view | | `[data-view]` | The view of the view | **ViewTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-trigger | | `[data-view]` | The view of the viewtrigger | **YearSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the calendar should close after the date selection is complete. This is ignored when the selection mode is `multiple`. | | `defaultFocusedValue` | `DateValue` | No | The initial focused date when rendered. Use when you don't need to control the focused date of the date picker. | | `defaultOpen` | `boolean` | No | The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker. | | `defaultValue` | `DateValue[]` | No | The initial selected date(s) when rendered. Use when you don't need to control the selected date(s) of the date picker. | | `defaultView` | `DateView` | No | The default view of the calendar | | `disabled` | `boolean` | No | Whether the calendar is disabled. | | `fixedWeeks` | `boolean` | No | Whether the calendar should have a fixed number of weeks. This renders the calendar with 6 weeks instead of 5 or 6. | | `focusedValue` | `DateValue` | No | The controlled focused date. | | `format` | `(date: DateValue, details: LocaleDetails) => string` | No | The format of the date to display in the input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; label(index: number): string; table(id: string): string; tableHeader(id: string): string; tableBody(id: string): string; tableRow(id: string): string; content: string; ... 10 more ...; positioner: string; }>` | No | The ids of the elements in the date picker. Useful for composition. | | `inline` | `boolean` | No | Whether the date picker is inline | | `isDateUnavailable` | `(date: DateValue, locale: string) => boolean` | No | Returns whether a date of the calendar is available. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `locale` | `string` | No | The locale (BCP 47 language tag) to use when formatting the date. | | `max` | `DateValue` | No | The maximum date that can be selected. | | `maxView` | `DateView` | No | The maximum view of the calendar | | `min` | `DateValue` | No | The minimum date that can be selected. | | `minView` | `DateView` | No | The minimum view of the calendar | | `modelValue` | `DateValue[]` | No | The v-model value of the date picker | | `name` | `string` | No | The `name` attribute of the input element. | | `numOfMonths` | `number` | No | The number of months to display. | | `open` | `boolean` | No | The controlled open state of the date picker | | `outsideDaySelectable` | `boolean` | No | Whether day outside the visible range can be selected. | | `parse` | `(value: string, details: LocaleDetails) => DateValue | undefined` | No | Function to parse the date from the input back to a DateValue. | | `placeholder` | `string` | No | The placeholder text to display in the input. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the date picker content | | `readOnly` | `boolean` | No | Whether the calendar is read-only. | | `selectionMode` | `SelectionMode` | No | The selection mode of the calendar. - `single` - only one date can be selected - `multiple` - multiple dates can be selected - `range` - a range of dates can be selected | | `startOfWeek` | `number` | No | The first day of the week. `0` - Sunday `1` - Monday `2` - Tuesday `3` - Wednesday `4` - Thursday `5` - Friday `6` - Saturday | | `timeZone` | `string` | No | The time zone to use | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `view` | `DateView` | No | The view of the calendar | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | | `[data-inline]` | Present when the content is inline | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested date-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fixOnBlur` | `boolean` | No | Whether to fix the input value on blur. | | `index` | `number` | No | The index of the input to focus. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | input | | `[data-index]` | The index of the item | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | label | | `[data-state]` | "open" | "closed" | | `[data-index]` | The index of the item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **MonthSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **PresetTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PresetTriggerValue` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RangeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `DatePickerApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **TableBody Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableBody Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-body | | `[data-view]` | The view of the tablebody | | `[data-disabled]` | Present when disabled | **TableCell Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `Reactive` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `disabled` | `boolean` | No | | | `visibleRange` | `VisibleRange` | No | | **TableCellTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-head | | `[data-view]` | The view of the tablehead | | `[data-disabled]` | Present when disabled | **TableHeader Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHeader Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-header | | `[data-view]` | The view of the tableheader | | `[data-disabled]` | Present when disabled | **Table Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `id` | `string` | No | | | `view` | `DateView` | No | | **Table Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table | | `[data-columns]` | | | `[data-view]` | The view of the table | **TableRow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableRow Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-row | | `[data-disabled]` | Present when disabled | | `[data-view]` | The view of the tablerow | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | **ViewControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-control | | `[data-view]` | The view of the viewcontrol | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `view` | `DateView` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **View Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view | | `[data-view]` | The view of the view | **ViewTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-trigger | | `[data-view]` | The view of the viewtrigger | **YearSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the calendar should close after the date selection is complete. This is ignored when the selection mode is `multiple`. | | `defaultFocusedValue` | `DateValue` | No | The initial focused date when rendered. Use when you don't need to control the focused date of the date picker. | | `defaultOpen` | `boolean` | No | The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker. | | `defaultValue` | `DateValue[]` | No | The initial selected date(s) when rendered. Use when you don't need to control the selected date(s) of the date picker. | | `defaultView` | `DateView` | No | The default view of the calendar | | `disabled` | `boolean` | No | Whether the calendar is disabled. | | `fixedWeeks` | `boolean` | No | Whether the calendar should have a fixed number of weeks. This renders the calendar with 6 weeks instead of 5 or 6. | | `focusedValue` | `DateValue` | No | The controlled focused date. | | `format` | `(date: DateValue, details: LocaleDetails) => string` | No | The format of the date to display in the input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; label: (index: number) => string; table: (id: string) => string; tableHeader: (id: string) => string; tableBody: (id: string) => string; tableRow: (id: string) => string; content: string; ... 10 more ...; positioner: string; }>` | No | The ids of the elements in the date picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inline` | `boolean` | No | Whether to render the date picker inline | | `isDateUnavailable` | `(date: DateValue, locale: string) => boolean` | No | Returns whether a date of the calendar is available. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `locale` | `string` | No | The locale (BCP 47 language tag) to use when formatting the date. | | `max` | `DateValue` | No | The maximum date that can be selected. | | `maxView` | `DateView` | No | The maximum view of the calendar | | `min` | `DateValue` | No | The minimum date that can be selected. | | `minView` | `DateView` | No | The minimum view of the calendar | | `name` | `string` | No | The `name` attribute of the input element. | | `numOfMonths` | `number` | No | The number of months to display. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function called when the focused date changes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the calendar opens or closes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when the value changes. | | `onViewChange` | `(details: ViewChangeDetails) => void` | No | Function called when the view changes. | | `open` | `boolean` | No | The controlled open state of the date picker | | `outsideDaySelectable` | `boolean` | No | Whether day outside the visible range can be selected. | | `parse` | `(value: string, details: LocaleDetails) => DateValue | undefined` | No | Function to parse the date from the input back to a DateValue. | | `placeholder` | `string` | No | The placeholder text to display in the input. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the date picker content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the calendar is read-only. | | `ref` | `Element` | No | | | `selectionMode` | `SelectionMode` | No | The selection mode of the calendar. - `single` - only one date can be selected - `multiple` - multiple dates can be selected - `range` - a range of dates can be selected | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `startOfWeek` | `number` | No | The first day of the week. `0` - Sunday `1` - Monday `2` - Tuesday `3` - Wednesday `4` - Thursday `5` - Friday `6` - Saturday | | `timeZone` | `string` | No | The time zone to use | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `DateValue[]` | No | The controlled selected date(s). | | `view` | `DateView` | No | The view of the calendar | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | | `[data-inline]` | Present when the content is inline | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested date-pickers | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseDatePickerContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fixOnBlur` | `boolean` | No | Whether to fix the input value on blur. | | `index` | `number` | No | The index of the input to focus. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | input | | `[data-index]` | The index of the item | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | label | | `[data-state]` | "open" | "closed" | | `[data-index]` | The index of the item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **MonthSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **PresetTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PresetTriggerValue` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RangeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDatePickerReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **TableBody Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'tbody'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableBody Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-body | | `[data-view]` | The view of the tablebody | | `[data-disabled]` | Present when disabled | **TableCell Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number | DateValue` | Yes | | | `asChild` | `Snippet<[PropsFn<'td'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `disabled` | `boolean` | No | | | `ref` | `Element` | No | | | `visibleRange` | `VisibleRange` | No | | **TableCellTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableHead Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'thead'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableHead Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-head | | `[data-view]` | The view of the tablehead | | `[data-disabled]` | Present when disabled | **TableHeader Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'th'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableHeader Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-header | | `[data-view]` | The view of the tableheader | | `[data-disabled]` | Present when disabled | **Table Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'table'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | **Table Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table | | `[data-columns]` | | | `[data-view]` | The view of the table | **TableRow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'tr'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableRow Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-row | | `[data-disabled]` | Present when disabled | | `[data-view]` | The view of the tablerow | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | **ViewControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ViewControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-control | | `[data-view]` | The view of the viewcontrol | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `view` | `DateView` | No | | **View Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view | | `[data-view]` | The view of the view | **ViewTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ViewTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-trigger | | `[data-view]` | The view of the viewtrigger | **YearSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focused` | `boolean` | Whether the input is focused | | `open` | `boolean` | Whether the date picker is open | | `disabled` | `boolean` | Whether the date picker is disabled | | `invalid` | `boolean` | Whether the date picker is invalid | | `inline` | `boolean` | Whether the date picker is rendered inline | | `view` | `DateView` | The current view of the date picker | | `getDaysInWeek` | `(week: number, from?: DateValue) => DateValue[]` | Returns an array of days in the week index counted from the provided start date, or the first visible date if not given. | | `getOffset` | `(duration: DateDuration) => DateValueOffset` | Returns the offset of the month based on the provided number of months. | | `getRangePresetValue` | `(value: DateRangePreset) => DateValue[]` | Returns the range of dates based on the provided date range preset. | | `getMonthWeeks` | `(from?: DateValue) => DateValue[][]` | Returns the weeks of the month from the provided date. Represented as an array of arrays of dates. | | `isUnavailable` | `(date: DateValue) => boolean` | Returns whether the provided date is available (or can be selected) | | `weeks` | `DateValue[][]` | The weeks of the month. Represented as an array of arrays of dates. | | `weekDays` | `WeekDay[]` | The days of the week. Represented as an array of strings. | | `visibleRange` | `VisibleRange` | The visible range of dates. | | `visibleRangeText` | `VisibleRangeText` | The human readable text for the visible range of dates. | | `value` | `DateValue[]` | The selected date. | | `valueAsDate` | `Date[]` | The selected date as a Date object. | | `valueAsString` | `string[]` | The selected date as a string. | | `focusedValue` | `DateValue` | The focused date. | | `focusedValueAsDate` | `Date` | The focused date as a Date object. | | `focusedValueAsString` | `string` | The focused date as a string. | | `selectToday` | `VoidFunction` | Sets the selected date to today. | | `setValue` | `(values: DateValue[]) => void` | Sets the selected date to the given date. | | `setFocusedValue` | `(value: DateValue) => void` | Sets the focused date to the given date. | | `clearValue` | `VoidFunction` | Clears the selected date(s). | | `setOpen` | `(open: boolean) => void` | Function to open or close the calendar. | | `focusMonth` | `(month: number) => void` | Function to set the selected month. | | `focusYear` | `(year: number) => void` | Function to set the selected year. | | `getYears` | `() => Cell[]` | Returns the months of the year | | `getYearsGrid` | `(props?: YearGridProps) => YearGridValue` | Returns the years of the decade based on the columns. Represented as an array of arrays of years. | | `getDecade` | `() => Range` | Returns the start and end years of the decade. | | `getMonths` | `(props?: MonthFormatOptions) => Cell[]` | Returns the months of the year | | `getMonthsGrid` | `(props?: MonthGridProps) => MonthGridValue` | Returns the months of the year based on the columns. Represented as an array of arrays of months. | | `format` | `(value: DateValue, opts?: Intl.DateTimeFormatOptions) => string` | Formats the given date value based on the provided options. | | `setView` | `(view: DateView) => void` | Sets the view of the date picker. | | `goToNext` | `VoidFunction` | Goes to the next month/year/decade. | | `goToPrev` | `VoidFunction` | Goes to the previous month/year/decade. | | `getDayTableCellState` | `(props: DayTableCellProps) => DayTableCellState` | Returns the state details for a given cell. | | `getMonthTableCellState` | `(props: TableCellProps) => TableCellState` | Returns the state details for a given month cell. | | `getYearTableCellState` | `(props: TableCellProps) => TableCellState` | Returns the state details for a given year cell. | ## Accessibility ### Keyboard Support **`ArrowLeft`** Description: Moves focus to the previous day within the current week. **`ArrowRight`** Description: Moves focus to the next day within the current week. **`ArrowUp`** Description: Moves focus to the same day of the week in the previous week. **`ArrowDown`** Description: Moves focus to the same day of the week in the next week. **`Home`** Description: Moves focus to the first day of the current month. **`End`** Description: Moves focus to the last day of the current month. **`PageUp`** Description: Moves focus to the same day of the month in the previous month. **`PageDown`** Description: Moves focus to the same day of the month in the next month. **`Enter`** Description: Selects the focused date and closes the date picker. **`Esc`** Description: Closes the date picker without selecting any date. --- # Date Picker (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Basic = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Basic = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Default Value Use the `defaultValue` prop with `parseDate` to set the initial date value. **Example: default-value** #### React ```tsx import { DatePicker, parseDate } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const DefaultValue = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker, parseDate } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const DefaultValue = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Controlled Use the `value` and `onValueChange` props to control the date picker's value programmatically. **Example: controlled** #### React ```tsx import { DatePicker, parseDate } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Controlled = () => { const [value, setValue] = useState([parseDate('2022-01-01')]) return ( setValue(e.value)}> Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker, parseDate } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Controlled = () => { const [value, setValue] = createSignal([parseDate('2022-01-01')]) return ( setValue(e.value)}> Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: root-provider** #### React ```tsx import { DatePicker, useDatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const RootProvider = () => { const datePicker = useDatePicker() return (
                    Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker, useDatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const RootProvider = () => { const datePicker = useDatePicker() return ( <> Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Default View Use the `defaultView` prop to set which view (day, month, or year) the calendar opens to initially. **Example: default-view** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const DefaultView = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const DefaultView = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: month-year-select** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import styles from 'styles/date-picker.module.css' export const MonthYearSelect = () => { return ( Label {(datePicker) => ( <>
                    {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/date-picker.module.css' export const MonthYearSelect = () => { return ( Label {(context) => ( <>
                    {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(datePicker)}
                    {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet}
                    ``` ### 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`. **Example: range-selection** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const RangeSelection = () => { return ( Label Clear Last 7 days {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon } from 'lucide-solid' import { Index, createMemo } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const RangeSelection = () => { return ( Label Clear Last 7 days
                    {(context) => ( {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => { const offset = createMemo(() => context().getOffset({ months: 1 })) return ( {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear Last 7 days {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Multiple Use the `selectionMode="multiple"` prop to allow selecting multiple dates. This example also shows how to display selected dates as removable tags. **Example: multi-selection** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import type { DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const formatWithDay = (date: DateValue) => { const jsDate = date.toDate('UTC') return jsDate.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric', }) } export const MultiSelection = () => { return ( Label {(datePicker) => (
                    {datePicker.value.length === 0 ? ( Select dates... ) : ( datePicker.value.map((date, index) => ( {formatWithDay(date)} )) )}
                    )}
                    Clear
                    {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { For, Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MultiSelection = () => { return ( Label {(context) => (
                    {context().value.length === 0 ? ( Select dates... ) : ( {(date, index) => ( {date.toDate('UTC').toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric', })} )} )}
                    )}
                    Clear
                    {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: multiple-months** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MultipleMonths = () => { return ( Label Clear
                    {(datePicker) => ( {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => { const offset = datePicker.getOffset({ months: 1 }) return ( {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {offset.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} ) }}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index, createMemo } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MultipleMonths = () => { return ( Label Clear
                    {(datePicker) => ( {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(datePicker) => { const offset = createMemo(() => datePicker().getOffset({ months: 1 })) return ( {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear
                    {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay, id (id)} {weekDay.short} {/each} {#each datePicker().weeks as week, id} {#each week as day, id (id)} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {@const offset = datePicker().getOffset({ months: 1 })} {#each datePicker().weekDays as weekDay, id (id)} {weekDay.short} {/each} {#each offset.weeks as week, id (id)} {#each week as day, id (id)} {day.day} {/each} {/each} {/snippet}
                    ``` ### Presets Use the `DatePicker.PresetTrigger` component to add quick-select preset options like "Last 7 days" or "This month". **Example: presets** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Presets = () => { return ( Label Clear
                    Last 7 days Last 30 days This month Last month
                    {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Presets = () => { return ( Label Clear
                    Last 7 days Last 30 days This month
                    {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear
                    Last 7 days Last 30 days This month
                    {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet}
                    ``` ### Min and Max Use the `min` and `max` props with `parseDate` to restrict the selectable date range. Dates outside this range will be disabled. **Example: min-max** #### React ```tsx import { DatePicker, parseDate } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MinMax = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker, parseDate } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const MinMax = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### Unavailable Use the `isDateUnavailable` prop to mark specific dates as unavailable. This example disables weekends. **Example: unavailable** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import type { DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const isWeekend = (date: DateValue) => { const dayOfWeek = date.toDate('UTC').getDay() return dayOfWeek === 0 || dayOfWeek === 6 } export const Unavailable = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import type { DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const isWeekend = (date: DateValue) => { const dayOfWeek = date.toDate('UTC').getDay() return dayOfWeek === 0 || dayOfWeek === 6 } export const Unavailable = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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.). **Example: locale** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Locale = () => { return ( Datum auswählen Löschen {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' export const Locale = () => { return ( Label Clear {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: month-picker** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => { const month = date.month.toString().padStart(2, '0') const year = date.year.toString() return `${month}/${year}` } const parse = (string: string) => { const fullRegex = /^(\d{1,2})\/(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, month, year] = fullMatch.map(Number) return new CalendarDate(year, month, 1) } } export const MonthPicker = () => { return ( Label Clear {(datePicker) => ( {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => { const month = date.month.toString().padStart(2, '0') const year = date.year.toString() return `${month}/${year}` } const parse = (string: string) => { const fullRegex = /^(\d{1,2})\/(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, month, year] = fullMatch.map(Number) return new CalendarDate(year, month, 1) } } export const MonthPicker = () => { return ( Label Clear {(context) => ( {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: year-picker** #### React ```tsx import { DatePicker, parseDate } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import type { DateValue } from '@internationalized/date' import { CalendarIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => date.year.toString() const parse = (string: string | undefined) => { if (string === '' || !string) return const year = Number(string) if (year < 100) { const currentYear = new Date().getFullYear() const currentCentury = Math.floor(currentYear / 100) * 100 return parseDate(new Date(currentCentury + year, 0)) } return parseDate(new Date(Number(string), 0)) } export const YearPicker = () => { return ( Label Clear {(datePicker) => ( {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker, parseDate } from '@ark-ui/solid/date-picker' import type { DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => date.year.toString() const parse = (string: string | undefined) => { if (string === '' || !string) return const year = Number(string) if (year < 100) { const currentYear = new Date().getFullYear() const currentCentury = Math.floor(currentYear / 100) * 100 return parseDate(new Date(currentCentury + year, 0)) } return parseDate(new Date(Number(string), 0)) } export const YearPicker = () => { return ( Label Clear {(context) => ( {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: inline** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import styles from 'styles/date-picker.module.css' export const Inline = () => { return (
                    {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )}
                    ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/date-picker.module.css' export const Inline = () => { return ( {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} {(context) => ( <> {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( <> {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: format-parse** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const parse = (value: string) => { const fullRegex = /^(\d{1,2})\/(\d{1,2})\/(\d{2})$/ const fullMatch = value.match(fullRegex) if (fullMatch) { const [_, day, month, year] = fullMatch.map(Number) try { return new CalendarDate(year + 2000, month, day) } catch { return undefined } } const partialRegex = /^(\d{1,2})\/(\d{1,2})$/ const partialMatch = value.match(partialRegex) if (partialMatch) { const [_, day, month] = partialMatch.map(Number) const currentYear = new Date().getFullYear() try { return new CalendarDate(currentYear, month, day) } catch { return undefined } } const dayRegex = /^(\d{1,2})$/ const dayMatch = value.match(dayRegex) if (dayMatch) { const [_, day] = dayMatch.map(Number) const currentYear = new Date().getFullYear() return new CalendarDate(currentYear, 1, day) } return undefined } const format = (date: DateValue) => { const day = date.day.toString().padStart(2, '0') const month = date.month.toString().padStart(2, '0') const year = (date.year % 100).toString().padStart(2, '0') return `${day}/${month}/${year}` } export const FormatParse = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} {(datePicker) => ( <> {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( <> {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` ### 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. **Example: month-picker-range** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => { const month = date.month.toString().padStart(2, '0') const year = date.year.toString() return `${month}/${year}` } const parse = (string: string) => { const fullRegex = /^(\d{1,2})\/(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, month, year] = fullMatch.map(Number) return new CalendarDate(year, month, 1) } } export const MonthPickerRange = () => { return ( Label Clear {(datePicker) => ( {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => ( {months.map((month, id) => ( {month.label} ))} ))} )} {(datePicker) => ( {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => { const month = date.month.toString().padStart(2, '0') const year = date.year.toString() return `${month}/${year}` } const parse = (string: string) => { const fullRegex = /^(\d{1,2})\/(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, month, year] = fullMatch.map(Number) return new CalendarDate(year, month, 1) } } export const MonthPickerRange = () => { return ( Label Clear {(context) => ( {(months) => ( {(month) => ( {month().label} )} )} )} {(context) => ( {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {#each datePicker().getMonthsGrid({ columns: 4, format: 'short' }) as months} {#each months as month} {month.label} {/each} {/each} {/snippet} {#snippet render(datePicker)} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: year-picker-range** #### React ```tsx import { DatePicker } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => date.year.toString() const parse = (string: string) => { const fullRegex = /^(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, year] = fullMatch.map(Number) return new CalendarDate(year, 1, 1) } } export const YearPickerRange = () => { return ( Label Clear {(datePicker) => ( <> {datePicker.getDecade().start} - {datePicker.getDecade().end} {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => ( {years.map((year, id) => ( {year.label} ))} ))} )} ) } ``` #### Solid ```tsx import { DatePicker } from '@ark-ui/solid/date-picker' import { CalendarDate, type DateValue } from '@internationalized/date' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const format = (date: DateValue) => date.year.toString() const parse = (string: string | undefined) => { if (!string) return const fullRegex = /^(\d{4})$/ const fullMatch = string.match(fullRegex) if (fullMatch) { const [_, year] = fullMatch.map(Number) return new CalendarDate(year, 1, 1) } } export const YearPickerRange = () => { return ( Label Clear {(context) => ( <> {context().getDecade().start} - {context().getDecade().end} {(years) => ( {(year) => ( {year().label} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Clear {#snippet render(datePicker)} {datePicker().getDecade().start} - {datePicker().getDecade().end} {#each datePicker().getYearsGrid({ columns: 4 }) as years} {#each years as year} {year.label} {/each} {/each} {/snippet} ``` ### 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. **Example: with-time** #### React ```tsx import { CalendarDateTime, DateFormatter, getLocalTimeZone } from '@internationalized/date' import { DatePicker, type DatePickerValueChangeDetails } from '@ark-ui/react/date-picker' import { Portal } from '@ark-ui/react/portal' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const formatter = new DateFormatter('en-US', { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit', }) export const WithTime = () => { const [value, setValue] = useState([new CalendarDateTime(2025, 1, 29, 14, 30)]) const timeValue = value[0] ? `${String(value[0].hour).padStart(2, '0')}:${String(value[0].minute).padStart(2, '0')}` : '' const onTimeChange = (e: React.ChangeEvent) => { const [hours, minutes] = e.currentTarget.value.split(':').map(Number) setValue((prev) => { const current = prev[0] ?? new CalendarDateTime(2025, 1, 1, 0, 0) return [current.set({ hour: hours, minute: minutes })] }) } const onDateChange = (details: DatePickerValueChangeDetails) => { const newDate = details.value[0] if (!newDate) return setValue([]) const prevTime = value[0] ?? { hour: 0, minute: 0 } setValue([new CalendarDateTime(newDate.year, newDate.month, newDate.day, prevTime.hour, prevTime.minute)]) } return ( Date and time {value[0] ? formatter.format(value[0].toDate(getLocalTimeZone())) : 'Select date and time'} {(datePicker) => ( <> {datePicker.weekDays.map((weekDay, id) => ( {weekDay.short} ))} {datePicker.weeks.map((week, id) => ( {week.map((day, id) => ( {day.day} ))} ))} )} ) } ``` #### Solid ```tsx import { CalendarDateTime, DateFormatter, getLocalTimeZone } from '@internationalized/date' import { DatePicker, type DatePickerValueChangeDetails } from '@ark-ui/solid/date-picker' import { CalendarIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/date-picker.module.css' const formatter = new DateFormatter('en-US', { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit', }) export const WithTime = () => { const [value, setValue] = createSignal([new CalendarDateTime(2025, 1, 29, 14, 30)]) const timeValue = () => { const v = value()[0] return v ? `${String(v.hour).padStart(2, '0')}:${String(v.minute).padStart(2, '0')}` : '' } const onTimeChange = (e: Event & { currentTarget: HTMLInputElement }) => { const [hours, minutes] = e.currentTarget.value.split(':').map(Number) setValue((prev) => { const current = prev[0] ?? new CalendarDateTime(2025, 1, 1, 0, 0) return [current.set({ hour: hours, minute: minutes })] }) } const onDateChange = (details: DatePickerValueChangeDetails) => { const newDate = details.value[0] if (!newDate) return setValue([]) const prevTime = value()[0] ?? { hour: 0, minute: 0 } setValue([new CalendarDateTime(newDate.year, newDate.month, newDate.day, prevTime.hour, prevTime.minute)]) } return ( Date and time {value()[0] ? formatter.format(value()[0].toDate(getLocalTimeZone())) : 'Select date and time'} {(context) => ( <> {(weekDay) => ( {weekDay().short} )} {(week) => ( {(day) => ( {day().day} )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Date and time {value[0] ? formatter.format(value[0].toDate(getLocalTimeZone())) : 'Select date and time'} {#snippet render(datePicker)} {#each datePicker().weekDays as weekDay} {weekDay.short} {/each} {#each datePicker().weeks as week} {#each week as day} {day.day} {/each} {/each} {/snippet} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the calendar should close after the date selection is complete. This is ignored when the selection mode is `multiple`. | | `defaultFocusedValue` | `DateValue` | No | The initial focused date when rendered. Use when you don't need to control the focused date of the date picker. | | `defaultOpen` | `boolean` | No | The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker. | | `defaultValue` | `DateValue[]` | No | The initial selected date(s) when rendered. Use when you don't need to control the selected date(s) of the date picker. | | `defaultView` | `DateView` | No | The default view of the calendar | | `disabled` | `boolean` | No | Whether the calendar is disabled. | | `fixedWeeks` | `boolean` | No | Whether the calendar should have a fixed number of weeks. This renders the calendar with 6 weeks instead of 5 or 6. | | `focusedValue` | `DateValue` | No | The controlled focused date. | | `format` | `(date: DateValue, details: LocaleDetails) => string` | No | The format of the date to display in the input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; label: (index: number) => string; table: (id: string) => string; tableHeader: (id: string) => string; tableBody: (id: string) => string; tableRow: (id: string) => string; content: string; ... 10 more ...; positioner: string; }>` | No | The ids of the elements in the date picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inline` | `boolean` | No | Whether to render the date picker inline | | `isDateUnavailable` | `(date: DateValue, locale: string) => boolean` | No | Returns whether a date of the calendar is available. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `locale` | `string` | No | The locale (BCP 47 language tag) to use when formatting the date. | | `max` | `DateValue` | No | The maximum date that can be selected. | | `maxView` | `DateView` | No | The maximum view of the calendar | | `min` | `DateValue` | No | The minimum date that can be selected. | | `minView` | `DateView` | No | The minimum view of the calendar | | `name` | `string` | No | The `name` attribute of the input element. | | `numOfMonths` | `number` | No | The number of months to display. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function called when the focused date changes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the calendar opens or closes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when the value changes. | | `onViewChange` | `(details: ViewChangeDetails) => void` | No | Function called when the view changes. | | `open` | `boolean` | No | The controlled open state of the date picker | | `outsideDaySelectable` | `boolean` | No | Whether day outside the visible range can be selected. | | `parse` | `(value: string, details: LocaleDetails) => DateValue | undefined` | No | Function to parse the date from the input back to a DateValue. | | `placeholder` | `string` | No | The placeholder text to display in the input. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the date picker content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the calendar is read-only. | | `selectionMode` | `SelectionMode` | No | The selection mode of the calendar. - `single` - only one date can be selected - `multiple` - multiple dates can be selected - `range` - a range of dates can be selected | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `startOfWeek` | `number` | No | The first day of the week. `0` - Sunday `1` - Monday `2` - Tuesday `3` - Wednesday `4` - Thursday `5` - Friday `6` - Saturday | | `timeZone` | `string` | No | The time zone to use | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `DateValue[]` | No | The controlled selected date(s). | | `view` | `DateView` | No | The view of the calendar | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | | `[data-inline]` | Present when the content is inline | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested date-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fixOnBlur` | `boolean` | No | Whether to fix the input value on blur. | | `index` | `number` | No | The index of the input to focus. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | input | | `[data-index]` | The index of the item | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | label | | `[data-state]` | "open" | "closed" | | `[data-index]` | The index of the item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **MonthSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **PresetTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PresetTriggerValue` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RangeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDatePickerReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **TableBody Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableBody Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-body | | `[data-view]` | The view of the tablebody | | `[data-disabled]` | Present when disabled | **TableCell Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number | DateValue` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `disabled` | `boolean` | No | | | `visibleRange` | `VisibleRange` | No | | **TableCellTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-head | | `[data-view]` | The view of the tablehead | | `[data-disabled]` | Present when disabled | **TableHeader Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHeader Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-header | | `[data-view]` | The view of the tableheader | | `[data-disabled]` | Present when disabled | **Table Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | **Table Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table | | `[data-columns]` | | | `[data-view]` | The view of the table | **TableRow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableRow Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-row | | `[data-disabled]` | Present when disabled | | `[data-view]` | The view of the tablerow | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | **ViewControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-control | | `[data-view]` | The view of the viewcontrol | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `view` | `DateView` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **View Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view | | `[data-view]` | The view of the view | **ViewTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-trigger | | `[data-view]` | The view of the viewtrigger | **YearSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the calendar should close after the date selection is complete. This is ignored when the selection mode is `multiple`. | | `defaultFocusedValue` | `DateValue` | No | The initial focused date when rendered. Use when you don't need to control the focused date of the date picker. | | `defaultOpen` | `boolean` | No | The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker. | | `defaultValue` | `DateValue[]` | No | The initial selected date(s) when rendered. Use when you don't need to control the selected date(s) of the date picker. | | `defaultView` | `DateView` | No | The default view of the calendar | | `disabled` | `boolean` | No | Whether the calendar is disabled. | | `fixedWeeks` | `boolean` | No | Whether the calendar should have a fixed number of weeks. This renders the calendar with 6 weeks instead of 5 or 6. | | `focusedValue` | `DateValue` | No | The controlled focused date. | | `format` | `(date: DateValue, details: LocaleDetails) => string` | No | The format of the date to display in the input. | | `ids` | `Partial<{ root: string; label: (index: number) => string; table: (id: string) => string; tableHeader: (id: string) => string; tableBody: (id: string) => string; tableRow: (id: string) => string; content: string; ... 10 more ...; positioner: string; }>` | No | The ids of the elements in the date picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inline` | `boolean` | No | Whether to render the date picker inline | | `isDateUnavailable` | `(date: DateValue, locale: string) => boolean` | No | Returns whether a date of the calendar is available. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `locale` | `string` | No | The locale (BCP 47 language tag) to use when formatting the date. | | `max` | `DateValue` | No | The maximum date that can be selected. | | `maxView` | `DateView` | No | The maximum view of the calendar | | `min` | `DateValue` | No | The minimum date that can be selected. | | `minView` | `DateView` | No | The minimum view of the calendar | | `name` | `string` | No | The `name` attribute of the input element. | | `numOfMonths` | `number` | No | The number of months to display. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function called when the focused date changes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the calendar opens or closes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when the value changes. | | `onViewChange` | `(details: ViewChangeDetails) => void` | No | Function called when the view changes. | | `open` | `boolean` | No | The controlled open state of the date picker | | `outsideDaySelectable` | `boolean` | No | Whether day outside the visible range can be selected. | | `parse` | `(value: string, details: LocaleDetails) => DateValue | undefined` | No | Function to parse the date from the input back to a DateValue. | | `placeholder` | `string` | No | The placeholder text to display in the input. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the date picker content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the calendar is read-only. | | `selectionMode` | `SelectionMode` | No | The selection mode of the calendar. - `single` - only one date can be selected - `multiple` - multiple dates can be selected - `range` - a range of dates can be selected | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `startOfWeek` | `number` | No | The first day of the week. `0` - Sunday `1` - Monday `2` - Tuesday `3` - Wednesday `4` - Thursday `5` - Friday `6` - Saturday | | `timeZone` | `string` | No | The time zone to use | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `DateValue[]` | No | The controlled selected date(s). | | `view` | `DateView` | No | The view of the calendar | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | | `[data-inline]` | Present when the content is inline | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested date-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fixOnBlur` | `boolean` | No | Whether to fix the input value on blur. | | `index` | `number` | No | The index of the input to focus. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | input | | `[data-index]` | The index of the item | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | label | | `[data-state]` | "open" | "closed" | | `[data-index]` | The index of the item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **MonthSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **PresetTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PresetTriggerValue` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RangeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDatePickerReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **TableBody Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'tbody'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableBody Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-body | | `[data-view]` | The view of the tablebody | | `[data-disabled]` | Present when disabled | **TableCell Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number | DateValue` | Yes | | | `asChild` | `(props: ParentProps<'td'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `disabled` | `boolean` | No | | | `visibleRange` | `VisibleRange` | No | | **TableCellTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'thead'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-head | | `[data-view]` | The view of the tablehead | | `[data-disabled]` | Present when disabled | **TableHeader Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'th'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHeader Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-header | | `[data-view]` | The view of the tableheader | | `[data-disabled]` | Present when disabled | **Table Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'table'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | **Table Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table | | `[data-columns]` | | | `[data-view]` | The view of the table | **TableRow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'tr'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableRow Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-row | | `[data-disabled]` | Present when disabled | | `[data-view]` | The view of the tablerow | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | **ViewControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-control | | `[data-view]` | The view of the viewcontrol | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `view` | `DateView` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **View Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view | | `[data-view]` | The view of the view | **ViewTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-trigger | | `[data-view]` | The view of the viewtrigger | **YearSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the calendar should close after the date selection is complete. This is ignored when the selection mode is `multiple`. | | `defaultFocusedValue` | `DateValue` | No | The initial focused date when rendered. Use when you don't need to control the focused date of the date picker. | | `defaultOpen` | `boolean` | No | The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker. | | `defaultValue` | `DateValue[]` | No | The initial selected date(s) when rendered. Use when you don't need to control the selected date(s) of the date picker. | | `defaultView` | `DateView` | No | The default view of the calendar | | `disabled` | `boolean` | No | Whether the calendar is disabled. | | `fixedWeeks` | `boolean` | No | Whether the calendar should have a fixed number of weeks. This renders the calendar with 6 weeks instead of 5 or 6. | | `focusedValue` | `DateValue` | No | The controlled focused date. | | `format` | `(date: DateValue, details: LocaleDetails) => string` | No | The format of the date to display in the input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; label(index: number): string; table(id: string): string; tableHeader(id: string): string; tableBody(id: string): string; tableRow(id: string): string; content: string; ... 10 more ...; positioner: string; }>` | No | The ids of the elements in the date picker. Useful for composition. | | `inline` | `boolean` | No | Whether the date picker is inline | | `isDateUnavailable` | `(date: DateValue, locale: string) => boolean` | No | Returns whether a date of the calendar is available. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `locale` | `string` | No | The locale (BCP 47 language tag) to use when formatting the date. | | `max` | `DateValue` | No | The maximum date that can be selected. | | `maxView` | `DateView` | No | The maximum view of the calendar | | `min` | `DateValue` | No | The minimum date that can be selected. | | `minView` | `DateView` | No | The minimum view of the calendar | | `modelValue` | `DateValue[]` | No | The v-model value of the date picker | | `name` | `string` | No | The `name` attribute of the input element. | | `numOfMonths` | `number` | No | The number of months to display. | | `open` | `boolean` | No | The controlled open state of the date picker | | `outsideDaySelectable` | `boolean` | No | Whether day outside the visible range can be selected. | | `parse` | `(value: string, details: LocaleDetails) => DateValue | undefined` | No | Function to parse the date from the input back to a DateValue. | | `placeholder` | `string` | No | The placeholder text to display in the input. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the date picker content | | `readOnly` | `boolean` | No | Whether the calendar is read-only. | | `selectionMode` | `SelectionMode` | No | The selection mode of the calendar. - `single` - only one date can be selected - `multiple` - multiple dates can be selected - `range` - a range of dates can be selected | | `startOfWeek` | `number` | No | The first day of the week. `0` - Sunday `1` - Monday `2` - Tuesday `3` - Wednesday `4` - Thursday `5` - Friday `6` - Saturday | | `timeZone` | `string` | No | The time zone to use | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `view` | `DateView` | No | The view of the calendar | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | | `[data-inline]` | Present when the content is inline | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested date-pickers | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fixOnBlur` | `boolean` | No | Whether to fix the input value on blur. | | `index` | `number` | No | The index of the input to focus. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | input | | `[data-index]` | The index of the item | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | label | | `[data-state]` | "open" | "closed" | | `[data-index]` | The index of the item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **MonthSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **PresetTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PresetTriggerValue` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RangeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `DatePickerApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **TableBody Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableBody Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-body | | `[data-view]` | The view of the tablebody | | `[data-disabled]` | Present when disabled | **TableCell Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `Reactive` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `disabled` | `boolean` | No | | | `visibleRange` | `VisibleRange` | No | | **TableCellTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHead Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-head | | `[data-view]` | The view of the tablehead | | `[data-disabled]` | Present when disabled | **TableHeader Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableHeader Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-header | | `[data-view]` | The view of the tableheader | | `[data-disabled]` | Present when disabled | **Table Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `id` | `string` | No | | | `view` | `DateView` | No | | **Table Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table | | `[data-columns]` | | | `[data-view]` | The view of the table | **TableRow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TableRow Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-row | | `[data-disabled]` | Present when disabled | | `[data-view]` | The view of the tablerow | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | **ViewControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-control | | `[data-view]` | The view of the viewcontrol | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `view` | `DateView` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **View Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view | | `[data-view]` | The view of the view | **ViewTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ViewTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-trigger | | `[data-view]` | The view of the viewtrigger | **YearSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the calendar should close after the date selection is complete. This is ignored when the selection mode is `multiple`. | | `defaultFocusedValue` | `DateValue` | No | The initial focused date when rendered. Use when you don't need to control the focused date of the date picker. | | `defaultOpen` | `boolean` | No | The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker. | | `defaultValue` | `DateValue[]` | No | The initial selected date(s) when rendered. Use when you don't need to control the selected date(s) of the date picker. | | `defaultView` | `DateView` | No | The default view of the calendar | | `disabled` | `boolean` | No | Whether the calendar is disabled. | | `fixedWeeks` | `boolean` | No | Whether the calendar should have a fixed number of weeks. This renders the calendar with 6 weeks instead of 5 or 6. | | `focusedValue` | `DateValue` | No | The controlled focused date. | | `format` | `(date: DateValue, details: LocaleDetails) => string` | No | The format of the date to display in the input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; label: (index: number) => string; table: (id: string) => string; tableHeader: (id: string) => string; tableBody: (id: string) => string; tableRow: (id: string) => string; content: string; ... 10 more ...; positioner: string; }>` | No | The ids of the elements in the date picker. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `inline` | `boolean` | No | Whether to render the date picker inline | | `isDateUnavailable` | `(date: DateValue, locale: string) => boolean` | No | Returns whether a date of the calendar is available. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `locale` | `string` | No | The locale (BCP 47 language tag) to use when formatting the date. | | `max` | `DateValue` | No | The maximum date that can be selected. | | `maxView` | `DateView` | No | The maximum view of the calendar | | `min` | `DateValue` | No | The minimum date that can be selected. | | `minView` | `DateView` | No | The minimum view of the calendar | | `name` | `string` | No | The `name` attribute of the input element. | | `numOfMonths` | `number` | No | The number of months to display. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function called when the focused date changes. | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the calendar opens or closes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called when the value changes. | | `onViewChange` | `(details: ViewChangeDetails) => void` | No | Function called when the view changes. | | `open` | `boolean` | No | The controlled open state of the date picker | | `outsideDaySelectable` | `boolean` | No | Whether day outside the visible range can be selected. | | `parse` | `(value: string, details: LocaleDetails) => DateValue | undefined` | No | Function to parse the date from the input back to a DateValue. | | `placeholder` | `string` | No | The placeholder text to display in the input. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the date picker content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the calendar is read-only. | | `ref` | `Element` | No | | | `selectionMode` | `SelectionMode` | No | The selection mode of the calendar. - `single` - only one date can be selected - `multiple` - multiple dates can be selected - `range` - a range of dates can be selected | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `startOfWeek` | `number` | No | The first day of the week. `0` - Sunday `1` - Monday `2` - Tuesday `3` - Wednesday `4` - Thursday `5` - Friday `6` - Saturday | | `timeZone` | `string` | No | The time zone to use | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `DateValue[]` | No | The controlled selected date(s). | | `view` | `DateView` | No | The view of the calendar | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | | `[data-inline]` | Present when the content is inline | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested date-pickers | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseDatePickerContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fixOnBlur` | `boolean` | No | Whether to fix the input value on blur. | | `index` | `number` | No | The index of the input to focus. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | input | | `[data-index]` | The index of the item | | `[data-state]` | "open" | "closed" | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | label | | `[data-state]` | "open" | "closed" | | `[data-index]` | The index of the item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | **MonthSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **PresetTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PresetTriggerValue` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RangeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDatePickerReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **TableBody Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'tbody'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableBody Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-body | | `[data-view]` | The view of the tablebody | | `[data-disabled]` | Present when disabled | **TableCell Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number | DateValue` | Yes | | | `asChild` | `Snippet<[PropsFn<'td'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | | `disabled` | `boolean` | No | | | `ref` | `Element` | No | | | `visibleRange` | `VisibleRange` | No | | **TableCellTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableHead Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'thead'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableHead Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-head | | `[data-view]` | The view of the tablehead | | `[data-disabled]` | Present when disabled | **TableHeader Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'th'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableHeader Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-header | | `[data-view]` | The view of the tableheader | | `[data-disabled]` | Present when disabled | **Table Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'table'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `columns` | `number` | No | | **Table Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table | | `[data-columns]` | | | `[data-view]` | The view of the table | **TableRow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'tr'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TableRow Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | table-row | | `[data-disabled]` | Present when disabled | | `[data-view]` | The view of the tablerow | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | **ViewControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ViewControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-control | | `[data-view]` | The view of the viewcontrol | **View Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `view` | `DateView` | No | | **View Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view | | `[data-view]` | The view of the view | **ViewTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ViewTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | date-picker | | `[data-part]` | view-trigger | | `[data-view]` | The view of the viewtrigger | **YearSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focused` | `boolean` | Whether the input is focused | | `open` | `boolean` | Whether the date picker is open | | `disabled` | `boolean` | Whether the date picker is disabled | | `invalid` | `boolean` | Whether the date picker is invalid | | `inline` | `boolean` | Whether the date picker is rendered inline | | `view` | `DateView` | The current view of the date picker | | `getDaysInWeek` | `(week: number, from?: DateValue) => DateValue[]` | Returns an array of days in the week index counted from the provided start date, or the first visible date if not given. | | `getOffset` | `(duration: DateDuration) => DateValueOffset` | Returns the offset of the month based on the provided number of months. | | `getRangePresetValue` | `(value: DateRangePreset) => DateValue[]` | Returns the range of dates based on the provided date range preset. | | `getMonthWeeks` | `(from?: DateValue) => DateValue[][]` | Returns the weeks of the month from the provided date. Represented as an array of arrays of dates. | | `isUnavailable` | `(date: DateValue) => boolean` | Returns whether the provided date is available (or can be selected) | | `weeks` | `DateValue[][]` | The weeks of the month. Represented as an array of arrays of dates. | | `weekDays` | `WeekDay[]` | The days of the week. Represented as an array of strings. | | `visibleRange` | `VisibleRange` | The visible range of dates. | | `visibleRangeText` | `VisibleRangeText` | The human readable text for the visible range of dates. | | `value` | `DateValue[]` | The selected date. | | `valueAsDate` | `Date[]` | The selected date as a Date object. | | `valueAsString` | `string[]` | The selected date as a string. | | `focusedValue` | `DateValue` | The focused date. | | `focusedValueAsDate` | `Date` | The focused date as a Date object. | | `focusedValueAsString` | `string` | The focused date as a string. | | `selectToday` | `VoidFunction` | Sets the selected date to today. | | `setValue` | `(values: DateValue[]) => void` | Sets the selected date to the given date. | | `setFocusedValue` | `(value: DateValue) => void` | Sets the focused date to the given date. | | `clearValue` | `VoidFunction` | Clears the selected date(s). | | `setOpen` | `(open: boolean) => void` | Function to open or close the calendar. | | `focusMonth` | `(month: number) => void` | Function to set the selected month. | | `focusYear` | `(year: number) => void` | Function to set the selected year. | | `getYears` | `() => Cell[]` | Returns the months of the year | | `getYearsGrid` | `(props?: YearGridProps) => YearGridValue` | Returns the years of the decade based on the columns. Represented as an array of arrays of years. | | `getDecade` | `() => Range` | Returns the start and end years of the decade. | | `getMonths` | `(props?: MonthFormatOptions) => Cell[]` | Returns the months of the year | | `getMonthsGrid` | `(props?: MonthGridProps) => MonthGridValue` | Returns the months of the year based on the columns. Represented as an array of arrays of months. | | `format` | `(value: DateValue, opts?: Intl.DateTimeFormatOptions) => string` | Formats the given date value based on the provided options. | | `setView` | `(view: DateView) => void` | Sets the view of the date picker. | | `goToNext` | `VoidFunction` | Goes to the next month/year/decade. | | `goToPrev` | `VoidFunction` | Goes to the previous month/year/decade. | | `getDayTableCellState` | `(props: DayTableCellProps) => DayTableCellState` | Returns the state details for a given cell. | | `getMonthTableCellState` | `(props: TableCellProps) => TableCellState` | Returns the state details for a given month cell. | | `getYearTableCellState` | `(props: TableCellProps) => TableCellState` | Returns the state details for a given year cell. | ## Accessibility ### Keyboard Support **`ArrowLeft`** Description: Moves focus to the previous day within the current week. **`ArrowRight`** Description: Moves focus to the next day within the current week. **`ArrowUp`** Description: Moves focus to the same day of the week in the previous week. **`ArrowDown`** Description: Moves focus to the same day of the week in the next week. **`Home`** Description: Moves focus to the first day of the current month. **`End`** Description: Moves focus to the last day of the current month. **`PageUp`** Description: Moves focus to the same day of the month in the previous month. **`PageDown`** Description: Moves focus to the same day of the month in the next month. **`Enter`** Description: Selects the focused date and closes the date picker. **`Esc`** Description: Closes the date picker without selecting any date. --- # Dialog (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Basic = () => ( Open Dialog Welcome Back Sign in to your account to continue. ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Basic = () => ( Open Dialog Welcome Back Sign in to your account to continue. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Welcome Back Sign in to your account to continue. ``` ### Controlled Manage the dialog state using the `open` and `onOpenChange` props. **Example: controlled** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return ( setOpen(e.open)}> Open Dialog Session Settings Manage your session preferences and security options. ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return ( setOpen(e.open)}> Open Dialog Session Settings Manage your session preferences and security options. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Session Settings Manage your session preferences and security options. ``` ### 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. **Example: root-provider** #### React ```tsx import { Dialog, useDialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const RootProvider = () => { const dialog = useDialog() return (
                    Controlled Externally This dialog is controlled via the useDialog hook.
                    ) } ``` #### Solid ```tsx import { Dialog, useDialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const RootProvider = () => { const dialog = useDialog() return ( <> Account Settings Manage your account preferences and security options. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Account Settings Manage your account preferences and security options. ``` ### 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 **Example: alert-dialog** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const AlertDialog = () => ( Delete Account Are you absolutely sure? This action cannot be undone. This will permanently delete your account and remove your data from our servers.
                    Cancel
                    ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const AlertDialog = () => ( Delete Account Are you absolutely sure? This action cannot be undone. This will permanently delete your account and remove your data from our servers.
                    Cancel
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Delete Account Are you absolutely sure? This action cannot be undone. This will permanently delete your account and remove your data from our servers.
                    Cancel
                    ``` ### Lazy Mount Use `lazyMount` to render dialog content only when first opened. Combine with `unmountOnExit` to unmount when closed, freeing up resources. **Example: lazy-mount** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const LazyMount = () => ( Open Dialog Lazy Loaded This dialog content is only mounted when opened and unmounts on close. ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const LazyMount = () => ( Open Dialog Lazy Mounted Dialog This dialog content is only mounted when opened and unmounted when closed. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Lazy Mounted Dialog This dialog content is only mounted when opened and unmounted when closed. ``` ### Initial Focus Use `initialFocusEl` to control which element receives focus when the dialog opens. **Example: initial-focus** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useRef } from 'react' import button from 'styles/button.module.css' import field from 'styles/field.module.css' import styles from 'styles/dialog.module.css' export const InitialFocus = () => { const inputRef = useRef(null) return ( inputRef.current}> Open Dialog Edit Profile The first input will be focused when the dialog opens.
                    ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const InitialFocus = () => { let inputRef: HTMLInputElement | undefined return ( inputRef!}> Open Dialog Edit Profile The name input will be focused when this dialog opens.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte inputRef}> Open Dialog Edit Profile The name input will be focused when this dialog opens.
                    ``` ### Final Focus Use `finalFocusEl` to control which element receives focus when the dialog closes. Defaults to the trigger element. **Example: final-focus** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useRef } from 'react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const FinalFocus = () => { const finalRef = useRef(null) return (
                    finalRef.current}> Open Dialog Focus Redirect When this dialog closes, focus will return to the button above instead of the trigger.
                    ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const FinalFocus = () => { let buttonRef: HTMLButtonElement | undefined return ( <> buttonRef!}> Open Dialog Custom Focus Return When this dialog closes, focus will return to the "Focus Target" button instead of the trigger. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte buttonRef}> Open Dialog Custom Focus Return When this dialog closes, focus will return to the "Focus Target" button instead of the trigger. ``` ### Non-Modal Use `modal={false}` to allow interaction with elements outside the dialog. Disables focus trapping and scroll prevention. **Example: non-modal** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const NonModal = () => ( Open Non-Modal Dialog Non-Modal Dialog This dialog allows interaction with elements outside. You can click buttons, select text, and interact with the page behind it. ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const NonModal = () => ( Open Non-Modal Non-Modal Dialog This dialog allows interaction with elements outside while open. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Non-Modal Non-Modal Dialog This dialog allows interaction with elements outside while open. ``` ### Inside Scroll Make the content area scrollable while keeping header and footer fixed using `maxHeight` and `overflow: auto`. **Example: inside-scroll** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const InsideScroll = () => ( Open Dialog Terms of Service Please review our terms before continuing.
                    {CONTENT_SECTIONS.map((item) => (

                    {item.title}

                    {item.body}

                    ))}
                    Decline Accept
                    ) const CONTENT_SECTIONS = [ { title: '1. Acceptance of Terms', body: 'By accessing and using this service, you accept and agree to be bound by the terms and provisions of this agreement.', }, { title: '2. Use License', body: 'Permission is granted to temporarily use this service for personal, non-commercial purposes only. This is the grant of a license, not a transfer of title.', }, { title: '3. User Responsibilities', body: 'You are responsible for maintaining the confidentiality of your account and password. You agree to accept responsibility for all activities that occur under your account.', }, { title: '4. Privacy Policy', body: 'Your use of this service is also governed by our Privacy Policy. Please review our Privacy Policy, which also governs the site and informs users of our data collection practices.', }, { title: '5. Limitations', body: 'In no event shall we be liable for any damages arising out of the use or inability to use the materials on this service.', }, { title: '6. Revisions', body: 'We may revise these terms of service at any time without notice. By using this service you are agreeing to be bound by the then current version of these terms.', }, { title: '7. Governing Law', body: 'These terms and conditions are governed by and construed in accordance with applicable laws and you irrevocably submit to the exclusive jurisdiction of the courts.', }, ] ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const InsideScroll = () => ( Open Dialog Terms of Service Please review our terms before continuing.
                    {CONTENT_SECTIONS.map((item) => (

                    {item.title}

                    {item.body}

                    ))}
                    Decline Accept
                    ) const CONTENT_SECTIONS = [ { title: '1. Acceptance of Terms', body: 'By accessing and using this service, you accept and agree to be bound by the terms and provisions of this agreement.', }, { title: '2. Use License', body: 'Permission is granted to temporarily use this service for personal, non-commercial purposes only. This is the grant of a license, not a transfer of title.', }, { title: '3. User Responsibilities', body: 'You are responsible for maintaining the confidentiality of your account and password. You agree to accept responsibility for all activities that occur under your account.', }, { title: '4. Privacy Policy', body: 'Your use of this service is also governed by our Privacy Policy. Please review our Privacy Policy, which also governs the site and informs users of our data collection practices.', }, { title: '5. Limitations', body: 'In no event shall we be liable for any damages arising out of the use or inability to use the materials on this service.', }, { title: '6. Revisions', body: 'We may revise these terms of service at any time without notice. By using this service you are agreeing to be bound by the then current version of these terms.', }, { title: '7. Governing Law', body: 'These terms and conditions are governed by and construed in accordance with applicable laws and you irrevocably submit to the exclusive jurisdiction of the courts.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Terms of Service Please review our terms before continuing.
                    {#each CONTENT_SECTIONS as item}

                    {item.title}

                    {item.body}

                    {/each}
                    Decline Accept
                    ``` ### Outside Scroll Make the positioner scrollable so the dialog can extend beyond the viewport. **Example: outside-scroll** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useRef } from 'react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const OutsideScroll = () => { const contentRef = useRef(null) return ( contentRef.current}> Open Dialog Privacy Policy This layout allows the dialog to extend beyond the viewport while keeping the outer container scrollable.
                    {CONTENT_SECTIONS.map((item) => (

                    {item.title}

                    {item.body}

                    ))}
                    ) } const CONTENT_SECTIONS = [ { title: '1. Information We Collect', body: 'We collect information you provide directly, such as when you create an account, make a purchase, or contact us for support. This may include your name, email address, and payment information.', }, { title: '2. How We Use Your Information', body: 'We use the information we collect to provide and improve our services, process transactions, send communications, and personalize your experience.', }, { title: '3. Information Sharing', body: 'We do not sell your personal information. We may share information with service providers who assist in our operations, or when required by law.', }, { title: '4. Data Security', body: 'We implement appropriate technical and organizational measures to protect your personal information against unauthorized access, alteration, or destruction.', }, { title: '5. Your Rights', body: 'You have the right to access, correct, or delete your personal information. You may also opt out of marketing communications at any time.', }, { title: '6. Cookies and Tracking', body: 'We use cookies and similar technologies to enhance your experience, analyze usage patterns, and deliver targeted content. You can manage cookie preferences in your browser settings.', }, { title: '7. Third-Party Services', body: 'Our service may contain links to third-party websites. We are not responsible for the privacy practices of these external sites.', }, { title: '8. Children Privacy', body: 'Our services are not directed to children under 13. We do not knowingly collect personal information from children without parental consent.', }, { title: '9. International Transfers', body: 'Your information may be transferred to and processed in countries other than your own. We ensure appropriate safeguards are in place for such transfers.', }, { title: '10. Changes to This Policy', body: 'We may update this privacy policy from time to time. We will notify you of significant changes by posting a notice on our website or sending you an email.', }, { title: '11. Data Retention', body: 'We retain your personal information for as long as necessary to fulfill the purposes outlined in this policy, unless a longer retention period is required by law.', }, { title: '12. Contact Us', body: 'If you have questions about this privacy policy or our data practices, please contact our privacy team through the support channels provided on our website.', }, ] ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const OutsideScroll = () => { let contentRef: HTMLDivElement | undefined return ( contentRef!}> Open Dialog Privacy Policy This layout allows the dialog to extend beyond the viewport while keeping the outer container scrollable.
                    {CONTENT_SECTIONS.map((item) => (

                    {item.title}

                    {item.body}

                    ))}
                    ) } const CONTENT_SECTIONS = [ { title: '1. Information We Collect', body: 'We collect information you provide directly, such as when you create an account, make a purchase, or contact us for support. This may include your name, email address, and payment information.', }, { title: '2. How We Use Your Information', body: 'We use the information we collect to provide and improve our services, process transactions, send communications, and personalize your experience.', }, { title: '3. Information Sharing', body: 'We do not sell your personal information. We may share information with service providers who assist in our operations, or when required by law.', }, { title: '4. Data Security', body: 'We implement appropriate technical and organizational measures to protect your personal information against unauthorized access, alteration, or destruction.', }, { title: '5. Your Rights', body: 'You have the right to access, correct, or delete your personal information. You may also opt out of marketing communications at any time.', }, { title: '6. Cookies and Tracking', body: 'We use cookies and similar technologies to enhance your experience, analyze usage patterns, and deliver targeted content. You can manage cookie preferences in your browser settings.', }, { title: '7. Third-Party Services', body: 'Our service may contain links to third-party websites. We are not responsible for the privacy practices of these external sites.', }, { title: '8. Children Privacy', body: 'Our services are not directed to children under 13. We do not knowingly collect personal information from children without parental consent.', }, { title: '9. International Transfers', body: 'Your information may be transferred to and processed in countries other than your own. We ensure appropriate safeguards are in place for such transfers.', }, { title: '10. Changes to This Policy', body: 'We may update this privacy policy from time to time. We will notify you of significant changes by posting a notice on our website or sending you an email.', }, { title: '11. Data Retention', body: 'We retain your personal information for as long as necessary to fulfill the purposes outlined in this policy, unless a longer retention period is required by law.', }, { title: '12. Contact Us', body: 'If you have questions about this privacy policy or our data practices, please contact our privacy team through the support channels provided on our website.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte contentRef}> Open Dialog Privacy Policy This layout allows the dialog to extend beyond the viewport while keeping the outer container scrollable.
                    {#each CONTENT_SECTIONS as item}

                    {item.title}

                    {item.body}

                    {/each}
                    ``` ### Context Use the `Dialog.Context` component to access the dialog's state and methods. **Example: context** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Context = () => ( Open Dialog Status {(dialog) => Dialog is {dialog.open ? 'open' : 'closed'}} ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Context = () => ( Open Dialog Status {(dialog) => Dialog is {dialog().open ? 'open' : 'closed'}} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Status {#snippet children(dialog)} Dialog is {dialog().open ? 'open' : 'closed'} {/snippet} ``` ### Open from Menu Open a dialog imperatively from a menu item using the `onClick` handler. **Example: open-from-menu** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Menu } from '@ark-ui/react/menu' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import dialog from 'styles/dialog.module.css' import menu from 'styles/menu.module.css' export const OpenFromMenu = () => { const [open, setOpen] = useState(false) return ( <> Actions Edit Duplicate setOpen(true)}> Delete... setOpen(e.open)} role="alertdialog"> Confirm Delete Are you sure you want to delete this item? This action cannot be undone. ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import dialog from 'styles/dialog.module.css' import menu from 'styles/menu.module.css' export const OpenFromMenu = () => { const [open, setOpen] = createSignal(false) return ( <> Actions Edit Duplicate setOpen(true)}> Delete... setOpen(e.open)} role="alertdialog"> Confirm Delete Are you sure you want to delete this item? This action cannot be undone. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Actions Edit Duplicate (open = true)}>Delete... Confirm Delete Are you sure you want to delete this item? This action cannot be undone. ``` ### Nested Nest dialogs within one another. The parent receives `data-has-nested` and `--nested-layer-count` CSS variable for styling effects like zoom-out: ```css [data-part='content'][data-has-nested] { transform: scale(calc(1 - var(--nested-layer-count) * 0.05)); } ``` **Example: nested** #### React ```tsx import { Dialog, useDialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Nested = () => { const parentDialog = useDialog() const childDialog = useDialog() return ( <> Parent Dialog This is the parent dialog. Open a nested dialog to see automatic z-index management.
                    Nested Dialog This dialog is nested within the parent with proper z-index layering. ) } ``` #### Solid ```tsx import { Dialog, useDialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Nested = () => { const parentDialog = useDialog() const childDialog = useDialog() return ( <> Parent Dialog This is the parent dialog. Open a nested dialog from here.
                    Nested Dialog This is a nested dialog with proper z-index layering. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Parent Dialog This is the parent dialog. Open a nested dialog from here.
                    Nested Dialog This is a nested dialog with proper z-index layering. ``` ### Confirmation Intercept close attempts to show confirmation prompts, preventing data loss from unsaved changes. **Example: confirmation** #### React ```tsx import { Dialog, useDialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import field from 'styles/field.module.css' import styles from 'styles/dialog.module.css' export const Confirmation = () => { const [formContent, setFormContent] = useState('') const [isParentDialogOpen, setIsParentDialogOpen] = useState(false) const parentDialog = useDialog({ open: isParentDialogOpen, onOpenChange: (details) => { if (!details.open && formContent.trim()) { confirmDialog.setOpen(true) } else { setIsParentDialogOpen(details.open) } }, }) const confirmDialog = useDialog() const handleConfirmClose = () => { confirmDialog.setOpen(false) parentDialog.setOpen(false) setFormContent('') } return ( <> Edit Content Make changes to your content. You'll be asked to confirm before closing if there are unsaved changes.
                    Unsaved Changes You have unsaved changes. Are you sure you want to discard them?
                    ``` #### Svelte ```svelte Edit Content Make changes to your content. You'll be asked to confirm if you have unsaved changes.
                    Unsaved Changes You have unsaved changes. Are you sure you want to discard them?
                    ``` ## Guides ### Close Behavior - `closeOnEscape={false}` - Prevent closing on Escape - `closeOnInteractOutside={false}` - Prevent closing on outside click For conditional control, use `onEscapeKeyDown` or `onInteractOutside` with `e.preventDefault()`. ### Z-Index Stacking Use the `--layer-index` CSS variable for z-index management of stacked dialogs: ```css [data-part='content'] { z-index: calc(var(--layer-index)); } ``` ### Dynamic Imports When using `lazyMount` with `React.lazy` or Next.js `dynamic`, wrap the imported component in `Suspense`: ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Suspense } from 'react' import dynamic from 'next/dynamic' const HeavyComponent = dynamic(() => import('./HeavyComponent')) export const Demo = () => ( Open Loading...}> ) ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered | | `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed | | `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked | | `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. | | `finalFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is closed | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string positioner: string backdrop: string content: string closeTrigger: string title: string description: string }>` | No | The ids of the elements in the dialog. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is opened | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function to call when the dialog's open state changes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the dialog | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened | | `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened | | `role` | `'dialog' | 'alertdialog'` | No | The dialog's role | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | dialog | | `[data-has-nested]` | dialog | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested dialogs | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDialogReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered | | `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed | | `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked | | `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. | | `finalFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is closed | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string positioner: string backdrop: string content: string closeTrigger: string title: string description: string }>` | No | The ids of the elements in the dialog. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is opened | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function to call when the dialog's open state changes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the dialog | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened | | `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened | | `role` | `'dialog' | 'alertdialog'` | No | The dialog's role | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | dialog | | `[data-has-nested]` | dialog | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested dialogs | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDialogReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'h2'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered | | `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed | | `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked | | `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. | | `finalFocusEl` | `() => HTMLElement | null` | No | Element to receive focus when the dialog is closed | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string positioner: string backdrop: string content: string closeTrigger: string title: string description: string }>` | No | The ids of the elements in the dialog. Useful for composition. | | `initialFocusEl` | `() => HTMLElement | null` | No | Element to receive focus when the dialog is opened | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it | | `open` | `boolean` | No | The controlled open state of the dialog | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened | | `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened | | `role` | `'dialog' | 'alertdialog'` | No | The dialog's role | | `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | dialog | | `[data-has-nested]` | dialog | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested dialogs | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `DialogApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered | | `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed | | `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked | | `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. | | `finalFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is closed | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string positioner: string backdrop: string content: string closeTrigger: string title: string description: string }>` | No | The ids of the elements in the dialog. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is opened | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function to call when the dialog's open state changes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the dialog | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened | | `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened | | `role` | `'alertdialog' | 'dialog'` | No | The dialog's role | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | dialog | | `[data-has-nested]` | dialog | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested dialogs | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'p'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDialogReturn` | Yes | | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the dialog is open | | `setOpen` | `(open: boolean) => void` | Function to open or close the dialog | ## Accessibility Complies with the [Dialog WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/). ### Keyboard Support **`Enter`** Description: When focus is on the trigger, opens the dialog. **`Tab`** Description: Moves focus to the next focusable element within the content. Focus is trapped within the dialog. **`Shift + Tab`** Description: Moves focus to the previous focusable element. Focus is trapped within the dialog. **`Esc`** Description: Closes the dialog and moves focus to trigger or the defined final focus element --- # Dialog (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Basic = () => ( Open Dialog Welcome Back Sign in to your account to continue. ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Basic = () => ( Open Dialog Welcome Back Sign in to your account to continue. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Welcome Back Sign in to your account to continue. ``` ### Controlled Manage the dialog state using the `open` and `onOpenChange` props. **Example: controlled** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return ( setOpen(e.open)}> Open Dialog Session Settings Manage your session preferences and security options. ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return ( setOpen(e.open)}> Open Dialog Session Settings Manage your session preferences and security options. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Session Settings Manage your session preferences and security options. ``` ### 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. **Example: root-provider** #### React ```tsx import { Dialog, useDialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const RootProvider = () => { const dialog = useDialog() return (
                    Controlled Externally This dialog is controlled via the useDialog hook.
                    ) } ``` #### Solid ```tsx import { Dialog, useDialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const RootProvider = () => { const dialog = useDialog() return ( <> Account Settings Manage your account preferences and security options. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Account Settings Manage your account preferences and security options. ``` ### 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 **Example: alert-dialog** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const AlertDialog = () => ( Delete Account Are you absolutely sure? This action cannot be undone. This will permanently delete your account and remove your data from our servers.
                    Cancel
                    ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const AlertDialog = () => ( Delete Account Are you absolutely sure? This action cannot be undone. This will permanently delete your account and remove your data from our servers.
                    Cancel
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Delete Account Are you absolutely sure? This action cannot be undone. This will permanently delete your account and remove your data from our servers.
                    Cancel
                    ``` ### Lazy Mount Use `lazyMount` to render dialog content only when first opened. Combine with `unmountOnExit` to unmount when closed, freeing up resources. **Example: lazy-mount** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const LazyMount = () => ( Open Dialog Lazy Loaded This dialog content is only mounted when opened and unmounts on close. ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const LazyMount = () => ( Open Dialog Lazy Mounted Dialog This dialog content is only mounted when opened and unmounted when closed. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Lazy Mounted Dialog This dialog content is only mounted when opened and unmounted when closed. ``` ### Initial Focus Use `initialFocusEl` to control which element receives focus when the dialog opens. **Example: initial-focus** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useRef } from 'react' import button from 'styles/button.module.css' import field from 'styles/field.module.css' import styles from 'styles/dialog.module.css' export const InitialFocus = () => { const inputRef = useRef(null) return ( inputRef.current}> Open Dialog Edit Profile The first input will be focused when the dialog opens.
                    ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const InitialFocus = () => { let inputRef: HTMLInputElement | undefined return ( inputRef!}> Open Dialog Edit Profile The name input will be focused when this dialog opens.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte inputRef}> Open Dialog Edit Profile The name input will be focused when this dialog opens.
                    ``` ### Final Focus Use `finalFocusEl` to control which element receives focus when the dialog closes. Defaults to the trigger element. **Example: final-focus** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useRef } from 'react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const FinalFocus = () => { const finalRef = useRef(null) return (
                    finalRef.current}> Open Dialog Focus Redirect When this dialog closes, focus will return to the button above instead of the trigger.
                    ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const FinalFocus = () => { let buttonRef: HTMLButtonElement | undefined return ( <> buttonRef!}> Open Dialog Custom Focus Return When this dialog closes, focus will return to the "Focus Target" button instead of the trigger. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte buttonRef}> Open Dialog Custom Focus Return When this dialog closes, focus will return to the "Focus Target" button instead of the trigger. ``` ### Non-Modal Use `modal={false}` to allow interaction with elements outside the dialog. Disables focus trapping and scroll prevention. **Example: non-modal** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const NonModal = () => ( Open Non-Modal Dialog Non-Modal Dialog This dialog allows interaction with elements outside. You can click buttons, select text, and interact with the page behind it. ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const NonModal = () => ( Open Non-Modal Non-Modal Dialog This dialog allows interaction with elements outside while open. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Non-Modal Non-Modal Dialog This dialog allows interaction with elements outside while open. ``` ### Inside Scroll Make the content area scrollable while keeping header and footer fixed using `maxHeight` and `overflow: auto`. **Example: inside-scroll** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const InsideScroll = () => ( Open Dialog Terms of Service Please review our terms before continuing.
                    {CONTENT_SECTIONS.map((item) => (

                    {item.title}

                    {item.body}

                    ))}
                    Decline Accept
                    ) const CONTENT_SECTIONS = [ { title: '1. Acceptance of Terms', body: 'By accessing and using this service, you accept and agree to be bound by the terms and provisions of this agreement.', }, { title: '2. Use License', body: 'Permission is granted to temporarily use this service for personal, non-commercial purposes only. This is the grant of a license, not a transfer of title.', }, { title: '3. User Responsibilities', body: 'You are responsible for maintaining the confidentiality of your account and password. You agree to accept responsibility for all activities that occur under your account.', }, { title: '4. Privacy Policy', body: 'Your use of this service is also governed by our Privacy Policy. Please review our Privacy Policy, which also governs the site and informs users of our data collection practices.', }, { title: '5. Limitations', body: 'In no event shall we be liable for any damages arising out of the use or inability to use the materials on this service.', }, { title: '6. Revisions', body: 'We may revise these terms of service at any time without notice. By using this service you are agreeing to be bound by the then current version of these terms.', }, { title: '7. Governing Law', body: 'These terms and conditions are governed by and construed in accordance with applicable laws and you irrevocably submit to the exclusive jurisdiction of the courts.', }, ] ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const InsideScroll = () => ( Open Dialog Terms of Service Please review our terms before continuing.
                    {CONTENT_SECTIONS.map((item) => (

                    {item.title}

                    {item.body}

                    ))}
                    Decline Accept
                    ) const CONTENT_SECTIONS = [ { title: '1. Acceptance of Terms', body: 'By accessing and using this service, you accept and agree to be bound by the terms and provisions of this agreement.', }, { title: '2. Use License', body: 'Permission is granted to temporarily use this service for personal, non-commercial purposes only. This is the grant of a license, not a transfer of title.', }, { title: '3. User Responsibilities', body: 'You are responsible for maintaining the confidentiality of your account and password. You agree to accept responsibility for all activities that occur under your account.', }, { title: '4. Privacy Policy', body: 'Your use of this service is also governed by our Privacy Policy. Please review our Privacy Policy, which also governs the site and informs users of our data collection practices.', }, { title: '5. Limitations', body: 'In no event shall we be liable for any damages arising out of the use or inability to use the materials on this service.', }, { title: '6. Revisions', body: 'We may revise these terms of service at any time without notice. By using this service you are agreeing to be bound by the then current version of these terms.', }, { title: '7. Governing Law', body: 'These terms and conditions are governed by and construed in accordance with applicable laws and you irrevocably submit to the exclusive jurisdiction of the courts.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Terms of Service Please review our terms before continuing.
                    {#each CONTENT_SECTIONS as item}

                    {item.title}

                    {item.body}

                    {/each}
                    Decline Accept
                    ``` ### Outside Scroll Make the positioner scrollable so the dialog can extend beyond the viewport. **Example: outside-scroll** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useRef } from 'react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const OutsideScroll = () => { const contentRef = useRef(null) return ( contentRef.current}> Open Dialog Privacy Policy This layout allows the dialog to extend beyond the viewport while keeping the outer container scrollable.
                    {CONTENT_SECTIONS.map((item) => (

                    {item.title}

                    {item.body}

                    ))}
                    ) } const CONTENT_SECTIONS = [ { title: '1. Information We Collect', body: 'We collect information you provide directly, such as when you create an account, make a purchase, or contact us for support. This may include your name, email address, and payment information.', }, { title: '2. How We Use Your Information', body: 'We use the information we collect to provide and improve our services, process transactions, send communications, and personalize your experience.', }, { title: '3. Information Sharing', body: 'We do not sell your personal information. We may share information with service providers who assist in our operations, or when required by law.', }, { title: '4. Data Security', body: 'We implement appropriate technical and organizational measures to protect your personal information against unauthorized access, alteration, or destruction.', }, { title: '5. Your Rights', body: 'You have the right to access, correct, or delete your personal information. You may also opt out of marketing communications at any time.', }, { title: '6. Cookies and Tracking', body: 'We use cookies and similar technologies to enhance your experience, analyze usage patterns, and deliver targeted content. You can manage cookie preferences in your browser settings.', }, { title: '7. Third-Party Services', body: 'Our service may contain links to third-party websites. We are not responsible for the privacy practices of these external sites.', }, { title: '8. Children Privacy', body: 'Our services are not directed to children under 13. We do not knowingly collect personal information from children without parental consent.', }, { title: '9. International Transfers', body: 'Your information may be transferred to and processed in countries other than your own. We ensure appropriate safeguards are in place for such transfers.', }, { title: '10. Changes to This Policy', body: 'We may update this privacy policy from time to time. We will notify you of significant changes by posting a notice on our website or sending you an email.', }, { title: '11. Data Retention', body: 'We retain your personal information for as long as necessary to fulfill the purposes outlined in this policy, unless a longer retention period is required by law.', }, { title: '12. Contact Us', body: 'If you have questions about this privacy policy or our data practices, please contact our privacy team through the support channels provided on our website.', }, ] ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const OutsideScroll = () => { let contentRef: HTMLDivElement | undefined return ( contentRef!}> Open Dialog Privacy Policy This layout allows the dialog to extend beyond the viewport while keeping the outer container scrollable.
                    {CONTENT_SECTIONS.map((item) => (

                    {item.title}

                    {item.body}

                    ))}
                    ) } const CONTENT_SECTIONS = [ { title: '1. Information We Collect', body: 'We collect information you provide directly, such as when you create an account, make a purchase, or contact us for support. This may include your name, email address, and payment information.', }, { title: '2. How We Use Your Information', body: 'We use the information we collect to provide and improve our services, process transactions, send communications, and personalize your experience.', }, { title: '3. Information Sharing', body: 'We do not sell your personal information. We may share information with service providers who assist in our operations, or when required by law.', }, { title: '4. Data Security', body: 'We implement appropriate technical and organizational measures to protect your personal information against unauthorized access, alteration, or destruction.', }, { title: '5. Your Rights', body: 'You have the right to access, correct, or delete your personal information. You may also opt out of marketing communications at any time.', }, { title: '6. Cookies and Tracking', body: 'We use cookies and similar technologies to enhance your experience, analyze usage patterns, and deliver targeted content. You can manage cookie preferences in your browser settings.', }, { title: '7. Third-Party Services', body: 'Our service may contain links to third-party websites. We are not responsible for the privacy practices of these external sites.', }, { title: '8. Children Privacy', body: 'Our services are not directed to children under 13. We do not knowingly collect personal information from children without parental consent.', }, { title: '9. International Transfers', body: 'Your information may be transferred to and processed in countries other than your own. We ensure appropriate safeguards are in place for such transfers.', }, { title: '10. Changes to This Policy', body: 'We may update this privacy policy from time to time. We will notify you of significant changes by posting a notice on our website or sending you an email.', }, { title: '11. Data Retention', body: 'We retain your personal information for as long as necessary to fulfill the purposes outlined in this policy, unless a longer retention period is required by law.', }, { title: '12. Contact Us', body: 'If you have questions about this privacy policy or our data practices, please contact our privacy team through the support channels provided on our website.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte contentRef}> Open Dialog Privacy Policy This layout allows the dialog to extend beyond the viewport while keeping the outer container scrollable.
                    {#each CONTENT_SECTIONS as item}

                    {item.title}

                    {item.body}

                    {/each}
                    ``` ### Context Use the `Dialog.Context` component to access the dialog's state and methods. **Example: context** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Context = () => ( Open Dialog Status {(dialog) => Dialog is {dialog.open ? 'open' : 'closed'}} ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Context = () => ( Open Dialog Status {(dialog) => Dialog is {dialog().open ? 'open' : 'closed'}} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Status {#snippet children(dialog)} Dialog is {dialog().open ? 'open' : 'closed'} {/snippet} ``` ### Open from Menu Open a dialog imperatively from a menu item using the `onClick` handler. **Example: open-from-menu** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Menu } from '@ark-ui/react/menu' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import dialog from 'styles/dialog.module.css' import menu from 'styles/menu.module.css' export const OpenFromMenu = () => { const [open, setOpen] = useState(false) return ( <> Actions Edit Duplicate setOpen(true)}> Delete... setOpen(e.open)} role="alertdialog"> Confirm Delete Are you sure you want to delete this item? This action cannot be undone. ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import dialog from 'styles/dialog.module.css' import menu from 'styles/menu.module.css' export const OpenFromMenu = () => { const [open, setOpen] = createSignal(false) return ( <> Actions Edit Duplicate setOpen(true)}> Delete... setOpen(e.open)} role="alertdialog"> Confirm Delete Are you sure you want to delete this item? This action cannot be undone. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Actions Edit Duplicate (open = true)}>Delete... Confirm Delete Are you sure you want to delete this item? This action cannot be undone. ``` ### Nested Nest dialogs within one another. The parent receives `data-has-nested` and `--nested-layer-count` CSS variable for styling effects like zoom-out: ```css [data-part='content'][data-has-nested] { transform: scale(calc(1 - var(--nested-layer-count) * 0.05)); } ``` **Example: nested** #### React ```tsx import { Dialog, useDialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Nested = () => { const parentDialog = useDialog() const childDialog = useDialog() return ( <> Parent Dialog This is the parent dialog. Open a nested dialog to see automatic z-index management.
                    Nested Dialog This dialog is nested within the parent with proper z-index layering. ) } ``` #### Solid ```tsx import { Dialog, useDialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Nested = () => { const parentDialog = useDialog() const childDialog = useDialog() return ( <> Parent Dialog This is the parent dialog. Open a nested dialog from here.
                    Nested Dialog This is a nested dialog with proper z-index layering. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Parent Dialog This is the parent dialog. Open a nested dialog from here.
                    Nested Dialog This is a nested dialog with proper z-index layering. ``` ### Confirmation Intercept close attempts to show confirmation prompts, preventing data loss from unsaved changes. **Example: confirmation** #### React ```tsx import { Dialog, useDialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import field from 'styles/field.module.css' import styles from 'styles/dialog.module.css' export const Confirmation = () => { const [formContent, setFormContent] = useState('') const [isParentDialogOpen, setIsParentDialogOpen] = useState(false) const parentDialog = useDialog({ open: isParentDialogOpen, onOpenChange: (details) => { if (!details.open && formContent.trim()) { confirmDialog.setOpen(true) } else { setIsParentDialogOpen(details.open) } }, }) const confirmDialog = useDialog() const handleConfirmClose = () => { confirmDialog.setOpen(false) parentDialog.setOpen(false) setFormContent('') } return ( <> Edit Content Make changes to your content. You'll be asked to confirm before closing if there are unsaved changes.
                    Unsaved Changes You have unsaved changes. Are you sure you want to discard them?
                    ``` #### Svelte ```svelte Edit Content Make changes to your content. You'll be asked to confirm if you have unsaved changes.
                    Unsaved Changes You have unsaved changes. Are you sure you want to discard them?
                    ``` ## Guides ### Close Behavior - `closeOnEscape={false}` - Prevent closing on Escape - `closeOnInteractOutside={false}` - Prevent closing on outside click For conditional control, use `onEscapeKeyDown` or `onInteractOutside` with `e.preventDefault()`. ### Z-Index Stacking Use the `--layer-index` CSS variable for z-index management of stacked dialogs: ```css [data-part='content'] { z-index: calc(var(--layer-index)); } ``` ### Dynamic Imports When using `lazyMount` with `React.lazy` or Next.js `dynamic`, wrap the imported component in `Suspense`: ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Suspense } from 'react' import dynamic from 'next/dynamic' const HeavyComponent = dynamic(() => import('./HeavyComponent')) export const Demo = () => ( Open Loading...}> ) ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered | | `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed | | `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked | | `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. | | `finalFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is closed | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string positioner: string backdrop: string content: string closeTrigger: string title: string description: string }>` | No | The ids of the elements in the dialog. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is opened | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function to call when the dialog's open state changes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the dialog | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened | | `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened | | `role` | `'dialog' | 'alertdialog'` | No | The dialog's role | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | dialog | | `[data-has-nested]` | dialog | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested dialogs | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDialogReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered | | `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed | | `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked | | `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. | | `finalFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is closed | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string positioner: string backdrop: string content: string closeTrigger: string title: string description: string }>` | No | The ids of the elements in the dialog. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is opened | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function to call when the dialog's open state changes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the dialog | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened | | `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened | | `role` | `'dialog' | 'alertdialog'` | No | The dialog's role | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | dialog | | `[data-has-nested]` | dialog | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested dialogs | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDialogReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'h2'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered | | `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed | | `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked | | `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. | | `finalFocusEl` | `() => HTMLElement | null` | No | Element to receive focus when the dialog is closed | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string positioner: string backdrop: string content: string closeTrigger: string title: string description: string }>` | No | The ids of the elements in the dialog. Useful for composition. | | `initialFocusEl` | `() => HTMLElement | null` | No | Element to receive focus when the dialog is opened | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it | | `open` | `boolean` | No | The controlled open state of the dialog | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened | | `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened | | `role` | `'dialog' | 'alertdialog'` | No | The dialog's role | | `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | dialog | | `[data-has-nested]` | dialog | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested dialogs | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `DialogApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered | | `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed | | `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked | | `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. | | `finalFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is closed | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string positioner: string backdrop: string content: string closeTrigger: string title: string description: string }>` | No | The ids of the elements in the dialog. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is opened | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function to call when the dialog's open state changes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the dialog | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened | | `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened | | `role` | `'alertdialog' | 'dialog'` | No | The dialog's role | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | dialog | | `[data-has-nested]` | dialog | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested dialogs | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'p'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDialogReturn` | Yes | | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the dialog is open | | `setOpen` | `(open: boolean) => void` | Function to open or close the dialog | ## Accessibility Complies with the [Dialog WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/). ### Keyboard Support **`Enter`** Description: When focus is on the trigger, opens the dialog. **`Tab`** Description: Moves focus to the next focusable element within the content. Focus is trapped within the dialog. **`Shift + Tab`** Description: Moves focus to the previous focusable element. Focus is trapped within the dialog. **`Esc`** Description: Closes the dialog and moves focus to trigger or the defined final focus element --- # Dialog (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Basic = () => ( Open Dialog Welcome Back Sign in to your account to continue. ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Basic = () => ( Open Dialog Welcome Back Sign in to your account to continue. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Welcome Back Sign in to your account to continue. ``` ### Controlled Manage the dialog state using the `open` and `onOpenChange` props. **Example: controlled** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return ( setOpen(e.open)}> Open Dialog Session Settings Manage your session preferences and security options. ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return ( setOpen(e.open)}> Open Dialog Session Settings Manage your session preferences and security options. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Session Settings Manage your session preferences and security options. ``` ### 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. **Example: root-provider** #### React ```tsx import { Dialog, useDialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const RootProvider = () => { const dialog = useDialog() return (
                    Controlled Externally This dialog is controlled via the useDialog hook.
                    ) } ``` #### Solid ```tsx import { Dialog, useDialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const RootProvider = () => { const dialog = useDialog() return ( <> Account Settings Manage your account preferences and security options. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Account Settings Manage your account preferences and security options. ``` ### 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 **Example: alert-dialog** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const AlertDialog = () => ( Delete Account Are you absolutely sure? This action cannot be undone. This will permanently delete your account and remove your data from our servers.
                    Cancel
                    ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const AlertDialog = () => ( Delete Account Are you absolutely sure? This action cannot be undone. This will permanently delete your account and remove your data from our servers.
                    Cancel
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Delete Account Are you absolutely sure? This action cannot be undone. This will permanently delete your account and remove your data from our servers.
                    Cancel
                    ``` ### Lazy Mount Use `lazyMount` to render dialog content only when first opened. Combine with `unmountOnExit` to unmount when closed, freeing up resources. **Example: lazy-mount** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const LazyMount = () => ( Open Dialog Lazy Loaded This dialog content is only mounted when opened and unmounts on close. ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const LazyMount = () => ( Open Dialog Lazy Mounted Dialog This dialog content is only mounted when opened and unmounted when closed. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Lazy Mounted Dialog This dialog content is only mounted when opened and unmounted when closed. ``` ### Initial Focus Use `initialFocusEl` to control which element receives focus when the dialog opens. **Example: initial-focus** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useRef } from 'react' import button from 'styles/button.module.css' import field from 'styles/field.module.css' import styles from 'styles/dialog.module.css' export const InitialFocus = () => { const inputRef = useRef(null) return ( inputRef.current}> Open Dialog Edit Profile The first input will be focused when the dialog opens.
                    ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const InitialFocus = () => { let inputRef: HTMLInputElement | undefined return ( inputRef!}> Open Dialog Edit Profile The name input will be focused when this dialog opens.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte inputRef}> Open Dialog Edit Profile The name input will be focused when this dialog opens.
                    ``` ### Final Focus Use `finalFocusEl` to control which element receives focus when the dialog closes. Defaults to the trigger element. **Example: final-focus** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useRef } from 'react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const FinalFocus = () => { const finalRef = useRef(null) return (
                    finalRef.current}> Open Dialog Focus Redirect When this dialog closes, focus will return to the button above instead of the trigger.
                    ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const FinalFocus = () => { let buttonRef: HTMLButtonElement | undefined return ( <> buttonRef!}> Open Dialog Custom Focus Return When this dialog closes, focus will return to the "Focus Target" button instead of the trigger. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte buttonRef}> Open Dialog Custom Focus Return When this dialog closes, focus will return to the "Focus Target" button instead of the trigger. ``` ### Non-Modal Use `modal={false}` to allow interaction with elements outside the dialog. Disables focus trapping and scroll prevention. **Example: non-modal** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const NonModal = () => ( Open Non-Modal Dialog Non-Modal Dialog This dialog allows interaction with elements outside. You can click buttons, select text, and interact with the page behind it. ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const NonModal = () => ( Open Non-Modal Non-Modal Dialog This dialog allows interaction with elements outside while open. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Non-Modal Non-Modal Dialog This dialog allows interaction with elements outside while open. ``` ### Inside Scroll Make the content area scrollable while keeping header and footer fixed using `maxHeight` and `overflow: auto`. **Example: inside-scroll** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const InsideScroll = () => ( Open Dialog Terms of Service Please review our terms before continuing.
                    {CONTENT_SECTIONS.map((item) => (

                    {item.title}

                    {item.body}

                    ))}
                    Decline Accept
                    ) const CONTENT_SECTIONS = [ { title: '1. Acceptance of Terms', body: 'By accessing and using this service, you accept and agree to be bound by the terms and provisions of this agreement.', }, { title: '2. Use License', body: 'Permission is granted to temporarily use this service for personal, non-commercial purposes only. This is the grant of a license, not a transfer of title.', }, { title: '3. User Responsibilities', body: 'You are responsible for maintaining the confidentiality of your account and password. You agree to accept responsibility for all activities that occur under your account.', }, { title: '4. Privacy Policy', body: 'Your use of this service is also governed by our Privacy Policy. Please review our Privacy Policy, which also governs the site and informs users of our data collection practices.', }, { title: '5. Limitations', body: 'In no event shall we be liable for any damages arising out of the use or inability to use the materials on this service.', }, { title: '6. Revisions', body: 'We may revise these terms of service at any time without notice. By using this service you are agreeing to be bound by the then current version of these terms.', }, { title: '7. Governing Law', body: 'These terms and conditions are governed by and construed in accordance with applicable laws and you irrevocably submit to the exclusive jurisdiction of the courts.', }, ] ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const InsideScroll = () => ( Open Dialog Terms of Service Please review our terms before continuing.
                    {CONTENT_SECTIONS.map((item) => (

                    {item.title}

                    {item.body}

                    ))}
                    Decline Accept
                    ) const CONTENT_SECTIONS = [ { title: '1. Acceptance of Terms', body: 'By accessing and using this service, you accept and agree to be bound by the terms and provisions of this agreement.', }, { title: '2. Use License', body: 'Permission is granted to temporarily use this service for personal, non-commercial purposes only. This is the grant of a license, not a transfer of title.', }, { title: '3. User Responsibilities', body: 'You are responsible for maintaining the confidentiality of your account and password. You agree to accept responsibility for all activities that occur under your account.', }, { title: '4. Privacy Policy', body: 'Your use of this service is also governed by our Privacy Policy. Please review our Privacy Policy, which also governs the site and informs users of our data collection practices.', }, { title: '5. Limitations', body: 'In no event shall we be liable for any damages arising out of the use or inability to use the materials on this service.', }, { title: '6. Revisions', body: 'We may revise these terms of service at any time without notice. By using this service you are agreeing to be bound by the then current version of these terms.', }, { title: '7. Governing Law', body: 'These terms and conditions are governed by and construed in accordance with applicable laws and you irrevocably submit to the exclusive jurisdiction of the courts.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Terms of Service Please review our terms before continuing.
                    {#each CONTENT_SECTIONS as item}

                    {item.title}

                    {item.body}

                    {/each}
                    Decline Accept
                    ``` ### Outside Scroll Make the positioner scrollable so the dialog can extend beyond the viewport. **Example: outside-scroll** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useRef } from 'react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const OutsideScroll = () => { const contentRef = useRef(null) return ( contentRef.current}> Open Dialog Privacy Policy This layout allows the dialog to extend beyond the viewport while keeping the outer container scrollable.
                    {CONTENT_SECTIONS.map((item) => (

                    {item.title}

                    {item.body}

                    ))}
                    ) } const CONTENT_SECTIONS = [ { title: '1. Information We Collect', body: 'We collect information you provide directly, such as when you create an account, make a purchase, or contact us for support. This may include your name, email address, and payment information.', }, { title: '2. How We Use Your Information', body: 'We use the information we collect to provide and improve our services, process transactions, send communications, and personalize your experience.', }, { title: '3. Information Sharing', body: 'We do not sell your personal information. We may share information with service providers who assist in our operations, or when required by law.', }, { title: '4. Data Security', body: 'We implement appropriate technical and organizational measures to protect your personal information against unauthorized access, alteration, or destruction.', }, { title: '5. Your Rights', body: 'You have the right to access, correct, or delete your personal information. You may also opt out of marketing communications at any time.', }, { title: '6. Cookies and Tracking', body: 'We use cookies and similar technologies to enhance your experience, analyze usage patterns, and deliver targeted content. You can manage cookie preferences in your browser settings.', }, { title: '7. Third-Party Services', body: 'Our service may contain links to third-party websites. We are not responsible for the privacy practices of these external sites.', }, { title: '8. Children Privacy', body: 'Our services are not directed to children under 13. We do not knowingly collect personal information from children without parental consent.', }, { title: '9. International Transfers', body: 'Your information may be transferred to and processed in countries other than your own. We ensure appropriate safeguards are in place for such transfers.', }, { title: '10. Changes to This Policy', body: 'We may update this privacy policy from time to time. We will notify you of significant changes by posting a notice on our website or sending you an email.', }, { title: '11. Data Retention', body: 'We retain your personal information for as long as necessary to fulfill the purposes outlined in this policy, unless a longer retention period is required by law.', }, { title: '12. Contact Us', body: 'If you have questions about this privacy policy or our data practices, please contact our privacy team through the support channels provided on our website.', }, ] ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const OutsideScroll = () => { let contentRef: HTMLDivElement | undefined return ( contentRef!}> Open Dialog Privacy Policy This layout allows the dialog to extend beyond the viewport while keeping the outer container scrollable.
                    {CONTENT_SECTIONS.map((item) => (

                    {item.title}

                    {item.body}

                    ))}
                    ) } const CONTENT_SECTIONS = [ { title: '1. Information We Collect', body: 'We collect information you provide directly, such as when you create an account, make a purchase, or contact us for support. This may include your name, email address, and payment information.', }, { title: '2. How We Use Your Information', body: 'We use the information we collect to provide and improve our services, process transactions, send communications, and personalize your experience.', }, { title: '3. Information Sharing', body: 'We do not sell your personal information. We may share information with service providers who assist in our operations, or when required by law.', }, { title: '4. Data Security', body: 'We implement appropriate technical and organizational measures to protect your personal information against unauthorized access, alteration, or destruction.', }, { title: '5. Your Rights', body: 'You have the right to access, correct, or delete your personal information. You may also opt out of marketing communications at any time.', }, { title: '6. Cookies and Tracking', body: 'We use cookies and similar technologies to enhance your experience, analyze usage patterns, and deliver targeted content. You can manage cookie preferences in your browser settings.', }, { title: '7. Third-Party Services', body: 'Our service may contain links to third-party websites. We are not responsible for the privacy practices of these external sites.', }, { title: '8. Children Privacy', body: 'Our services are not directed to children under 13. We do not knowingly collect personal information from children without parental consent.', }, { title: '9. International Transfers', body: 'Your information may be transferred to and processed in countries other than your own. We ensure appropriate safeguards are in place for such transfers.', }, { title: '10. Changes to This Policy', body: 'We may update this privacy policy from time to time. We will notify you of significant changes by posting a notice on our website or sending you an email.', }, { title: '11. Data Retention', body: 'We retain your personal information for as long as necessary to fulfill the purposes outlined in this policy, unless a longer retention period is required by law.', }, { title: '12. Contact Us', body: 'If you have questions about this privacy policy or our data practices, please contact our privacy team through the support channels provided on our website.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte contentRef}> Open Dialog Privacy Policy This layout allows the dialog to extend beyond the viewport while keeping the outer container scrollable.
                    {#each CONTENT_SECTIONS as item}

                    {item.title}

                    {item.body}

                    {/each}
                    ``` ### Context Use the `Dialog.Context` component to access the dialog's state and methods. **Example: context** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Context = () => ( Open Dialog Status {(dialog) => Dialog is {dialog.open ? 'open' : 'closed'}} ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Context = () => ( Open Dialog Status {(dialog) => Dialog is {dialog().open ? 'open' : 'closed'}} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Status {#snippet children(dialog)} Dialog is {dialog().open ? 'open' : 'closed'} {/snippet} ``` ### Open from Menu Open a dialog imperatively from a menu item using the `onClick` handler. **Example: open-from-menu** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Menu } from '@ark-ui/react/menu' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import dialog from 'styles/dialog.module.css' import menu from 'styles/menu.module.css' export const OpenFromMenu = () => { const [open, setOpen] = useState(false) return ( <> Actions Edit Duplicate setOpen(true)}> Delete... setOpen(e.open)} role="alertdialog"> Confirm Delete Are you sure you want to delete this item? This action cannot be undone. ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import dialog from 'styles/dialog.module.css' import menu from 'styles/menu.module.css' export const OpenFromMenu = () => { const [open, setOpen] = createSignal(false) return ( <> Actions Edit Duplicate setOpen(true)}> Delete... setOpen(e.open)} role="alertdialog"> Confirm Delete Are you sure you want to delete this item? This action cannot be undone. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Actions Edit Duplicate (open = true)}>Delete... Confirm Delete Are you sure you want to delete this item? This action cannot be undone. ``` ### Nested Nest dialogs within one another. The parent receives `data-has-nested` and `--nested-layer-count` CSS variable for styling effects like zoom-out: ```css [data-part='content'][data-has-nested] { transform: scale(calc(1 - var(--nested-layer-count) * 0.05)); } ``` **Example: nested** #### React ```tsx import { Dialog, useDialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Nested = () => { const parentDialog = useDialog() const childDialog = useDialog() return ( <> Parent Dialog This is the parent dialog. Open a nested dialog to see automatic z-index management.
                    Nested Dialog This dialog is nested within the parent with proper z-index layering. ) } ``` #### Solid ```tsx import { Dialog, useDialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Nested = () => { const parentDialog = useDialog() const childDialog = useDialog() return ( <> Parent Dialog This is the parent dialog. Open a nested dialog from here.
                    Nested Dialog This is a nested dialog with proper z-index layering. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Parent Dialog This is the parent dialog. Open a nested dialog from here.
                    Nested Dialog This is a nested dialog with proper z-index layering. ``` ### Confirmation Intercept close attempts to show confirmation prompts, preventing data loss from unsaved changes. **Example: confirmation** #### React ```tsx import { Dialog, useDialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import field from 'styles/field.module.css' import styles from 'styles/dialog.module.css' export const Confirmation = () => { const [formContent, setFormContent] = useState('') const [isParentDialogOpen, setIsParentDialogOpen] = useState(false) const parentDialog = useDialog({ open: isParentDialogOpen, onOpenChange: (details) => { if (!details.open && formContent.trim()) { confirmDialog.setOpen(true) } else { setIsParentDialogOpen(details.open) } }, }) const confirmDialog = useDialog() const handleConfirmClose = () => { confirmDialog.setOpen(false) parentDialog.setOpen(false) setFormContent('') } return ( <> Edit Content Make changes to your content. You'll be asked to confirm before closing if there are unsaved changes.
                    Unsaved Changes You have unsaved changes. Are you sure you want to discard them?
                    ``` #### Svelte ```svelte Edit Content Make changes to your content. You'll be asked to confirm if you have unsaved changes.
                    Unsaved Changes You have unsaved changes. Are you sure you want to discard them?
                    ``` ## Guides ### Close Behavior - `closeOnEscape={false}` - Prevent closing on Escape - `closeOnInteractOutside={false}` - Prevent closing on outside click For conditional control, use `onEscapeKeyDown` or `onInteractOutside` with `e.preventDefault()`. ### Z-Index Stacking Use the `--layer-index` CSS variable for z-index management of stacked dialogs: ```css [data-part='content'] { z-index: calc(var(--layer-index)); } ``` ### Dynamic Imports When using `lazyMount` with `React.lazy` or Next.js `dynamic`, wrap the imported component in `Suspense`: ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Suspense } from 'react' import dynamic from 'next/dynamic' const HeavyComponent = dynamic(() => import('./HeavyComponent')) export const Demo = () => ( Open Loading...}> ) ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered | | `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed | | `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked | | `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. | | `finalFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is closed | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string positioner: string backdrop: string content: string closeTrigger: string title: string description: string }>` | No | The ids of the elements in the dialog. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is opened | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function to call when the dialog's open state changes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the dialog | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened | | `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened | | `role` | `'dialog' | 'alertdialog'` | No | The dialog's role | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | dialog | | `[data-has-nested]` | dialog | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested dialogs | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDialogReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered | | `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed | | `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked | | `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. | | `finalFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is closed | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string positioner: string backdrop: string content: string closeTrigger: string title: string description: string }>` | No | The ids of the elements in the dialog. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is opened | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function to call when the dialog's open state changes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the dialog | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened | | `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened | | `role` | `'dialog' | 'alertdialog'` | No | The dialog's role | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | dialog | | `[data-has-nested]` | dialog | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested dialogs | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDialogReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'h2'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered | | `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed | | `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked | | `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. | | `finalFocusEl` | `() => HTMLElement | null` | No | Element to receive focus when the dialog is closed | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string positioner: string backdrop: string content: string closeTrigger: string title: string description: string }>` | No | The ids of the elements in the dialog. Useful for composition. | | `initialFocusEl` | `() => HTMLElement | null` | No | Element to receive focus when the dialog is opened | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it | | `open` | `boolean` | No | The controlled open state of the dialog | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened | | `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened | | `role` | `'dialog' | 'alertdialog'` | No | The dialog's role | | `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | dialog | | `[data-has-nested]` | dialog | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested dialogs | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `DialogApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered | | `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed | | `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked | | `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. | | `finalFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is closed | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string positioner: string backdrop: string content: string closeTrigger: string title: string description: string }>` | No | The ids of the elements in the dialog. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is opened | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function to call when the dialog's open state changes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the dialog | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened | | `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened | | `role` | `'alertdialog' | 'dialog'` | No | The dialog's role | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | dialog | | `[data-has-nested]` | dialog | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested dialogs | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'p'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDialogReturn` | Yes | | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the dialog is open | | `setOpen` | `(open: boolean) => void` | Function to open or close the dialog | ## Accessibility Complies with the [Dialog WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/). ### Keyboard Support **`Enter`** Description: When focus is on the trigger, opens the dialog. **`Tab`** Description: Moves focus to the next focusable element within the content. Focus is trapped within the dialog. **`Shift + Tab`** Description: Moves focus to the previous focusable element. Focus is trapped within the dialog. **`Esc`** Description: Closes the dialog and moves focus to trigger or the defined final focus element --- # Dialog (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Basic = () => ( Open Dialog Welcome Back Sign in to your account to continue. ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Basic = () => ( Open Dialog Welcome Back Sign in to your account to continue. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Welcome Back Sign in to your account to continue. ``` ### Controlled Manage the dialog state using the `open` and `onOpenChange` props. **Example: controlled** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return ( setOpen(e.open)}> Open Dialog Session Settings Manage your session preferences and security options. ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return ( setOpen(e.open)}> Open Dialog Session Settings Manage your session preferences and security options. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Session Settings Manage your session preferences and security options. ``` ### 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. **Example: root-provider** #### React ```tsx import { Dialog, useDialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const RootProvider = () => { const dialog = useDialog() return (
                    Controlled Externally This dialog is controlled via the useDialog hook.
                    ) } ``` #### Solid ```tsx import { Dialog, useDialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const RootProvider = () => { const dialog = useDialog() return ( <> Account Settings Manage your account preferences and security options. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Account Settings Manage your account preferences and security options. ``` ### 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 **Example: alert-dialog** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const AlertDialog = () => ( Delete Account Are you absolutely sure? This action cannot be undone. This will permanently delete your account and remove your data from our servers.
                    Cancel
                    ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const AlertDialog = () => ( Delete Account Are you absolutely sure? This action cannot be undone. This will permanently delete your account and remove your data from our servers.
                    Cancel
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Delete Account Are you absolutely sure? This action cannot be undone. This will permanently delete your account and remove your data from our servers.
                    Cancel
                    ``` ### Lazy Mount Use `lazyMount` to render dialog content only when first opened. Combine with `unmountOnExit` to unmount when closed, freeing up resources. **Example: lazy-mount** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const LazyMount = () => ( Open Dialog Lazy Loaded This dialog content is only mounted when opened and unmounts on close. ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const LazyMount = () => ( Open Dialog Lazy Mounted Dialog This dialog content is only mounted when opened and unmounted when closed. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Lazy Mounted Dialog This dialog content is only mounted when opened and unmounted when closed. ``` ### Initial Focus Use `initialFocusEl` to control which element receives focus when the dialog opens. **Example: initial-focus** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useRef } from 'react' import button from 'styles/button.module.css' import field from 'styles/field.module.css' import styles from 'styles/dialog.module.css' export const InitialFocus = () => { const inputRef = useRef(null) return ( inputRef.current}> Open Dialog Edit Profile The first input will be focused when the dialog opens.
                    ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const InitialFocus = () => { let inputRef: HTMLInputElement | undefined return ( inputRef!}> Open Dialog Edit Profile The name input will be focused when this dialog opens.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte inputRef}> Open Dialog Edit Profile The name input will be focused when this dialog opens.
                    ``` ### Final Focus Use `finalFocusEl` to control which element receives focus when the dialog closes. Defaults to the trigger element. **Example: final-focus** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useRef } from 'react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const FinalFocus = () => { const finalRef = useRef(null) return (
                    finalRef.current}> Open Dialog Focus Redirect When this dialog closes, focus will return to the button above instead of the trigger.
                    ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const FinalFocus = () => { let buttonRef: HTMLButtonElement | undefined return ( <> buttonRef!}> Open Dialog Custom Focus Return When this dialog closes, focus will return to the "Focus Target" button instead of the trigger. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte buttonRef}> Open Dialog Custom Focus Return When this dialog closes, focus will return to the "Focus Target" button instead of the trigger. ``` ### Non-Modal Use `modal={false}` to allow interaction with elements outside the dialog. Disables focus trapping and scroll prevention. **Example: non-modal** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const NonModal = () => ( Open Non-Modal Dialog Non-Modal Dialog This dialog allows interaction with elements outside. You can click buttons, select text, and interact with the page behind it. ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const NonModal = () => ( Open Non-Modal Non-Modal Dialog This dialog allows interaction with elements outside while open. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Non-Modal Non-Modal Dialog This dialog allows interaction with elements outside while open. ``` ### Inside Scroll Make the content area scrollable while keeping header and footer fixed using `maxHeight` and `overflow: auto`. **Example: inside-scroll** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const InsideScroll = () => ( Open Dialog Terms of Service Please review our terms before continuing.
                    {CONTENT_SECTIONS.map((item) => (

                    {item.title}

                    {item.body}

                    ))}
                    Decline Accept
                    ) const CONTENT_SECTIONS = [ { title: '1. Acceptance of Terms', body: 'By accessing and using this service, you accept and agree to be bound by the terms and provisions of this agreement.', }, { title: '2. Use License', body: 'Permission is granted to temporarily use this service for personal, non-commercial purposes only. This is the grant of a license, not a transfer of title.', }, { title: '3. User Responsibilities', body: 'You are responsible for maintaining the confidentiality of your account and password. You agree to accept responsibility for all activities that occur under your account.', }, { title: '4. Privacy Policy', body: 'Your use of this service is also governed by our Privacy Policy. Please review our Privacy Policy, which also governs the site and informs users of our data collection practices.', }, { title: '5. Limitations', body: 'In no event shall we be liable for any damages arising out of the use or inability to use the materials on this service.', }, { title: '6. Revisions', body: 'We may revise these terms of service at any time without notice. By using this service you are agreeing to be bound by the then current version of these terms.', }, { title: '7. Governing Law', body: 'These terms and conditions are governed by and construed in accordance with applicable laws and you irrevocably submit to the exclusive jurisdiction of the courts.', }, ] ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const InsideScroll = () => ( Open Dialog Terms of Service Please review our terms before continuing.
                    {CONTENT_SECTIONS.map((item) => (

                    {item.title}

                    {item.body}

                    ))}
                    Decline Accept
                    ) const CONTENT_SECTIONS = [ { title: '1. Acceptance of Terms', body: 'By accessing and using this service, you accept and agree to be bound by the terms and provisions of this agreement.', }, { title: '2. Use License', body: 'Permission is granted to temporarily use this service for personal, non-commercial purposes only. This is the grant of a license, not a transfer of title.', }, { title: '3. User Responsibilities', body: 'You are responsible for maintaining the confidentiality of your account and password. You agree to accept responsibility for all activities that occur under your account.', }, { title: '4. Privacy Policy', body: 'Your use of this service is also governed by our Privacy Policy. Please review our Privacy Policy, which also governs the site and informs users of our data collection practices.', }, { title: '5. Limitations', body: 'In no event shall we be liable for any damages arising out of the use or inability to use the materials on this service.', }, { title: '6. Revisions', body: 'We may revise these terms of service at any time without notice. By using this service you are agreeing to be bound by the then current version of these terms.', }, { title: '7. Governing Law', body: 'These terms and conditions are governed by and construed in accordance with applicable laws and you irrevocably submit to the exclusive jurisdiction of the courts.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Terms of Service Please review our terms before continuing.
                    {#each CONTENT_SECTIONS as item}

                    {item.title}

                    {item.body}

                    {/each}
                    Decline Accept
                    ``` ### Outside Scroll Make the positioner scrollable so the dialog can extend beyond the viewport. **Example: outside-scroll** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useRef } from 'react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const OutsideScroll = () => { const contentRef = useRef(null) return ( contentRef.current}> Open Dialog Privacy Policy This layout allows the dialog to extend beyond the viewport while keeping the outer container scrollable.
                    {CONTENT_SECTIONS.map((item) => (

                    {item.title}

                    {item.body}

                    ))}
                    ) } const CONTENT_SECTIONS = [ { title: '1. Information We Collect', body: 'We collect information you provide directly, such as when you create an account, make a purchase, or contact us for support. This may include your name, email address, and payment information.', }, { title: '2. How We Use Your Information', body: 'We use the information we collect to provide and improve our services, process transactions, send communications, and personalize your experience.', }, { title: '3. Information Sharing', body: 'We do not sell your personal information. We may share information with service providers who assist in our operations, or when required by law.', }, { title: '4. Data Security', body: 'We implement appropriate technical and organizational measures to protect your personal information against unauthorized access, alteration, or destruction.', }, { title: '5. Your Rights', body: 'You have the right to access, correct, or delete your personal information. You may also opt out of marketing communications at any time.', }, { title: '6. Cookies and Tracking', body: 'We use cookies and similar technologies to enhance your experience, analyze usage patterns, and deliver targeted content. You can manage cookie preferences in your browser settings.', }, { title: '7. Third-Party Services', body: 'Our service may contain links to third-party websites. We are not responsible for the privacy practices of these external sites.', }, { title: '8. Children Privacy', body: 'Our services are not directed to children under 13. We do not knowingly collect personal information from children without parental consent.', }, { title: '9. International Transfers', body: 'Your information may be transferred to and processed in countries other than your own. We ensure appropriate safeguards are in place for such transfers.', }, { title: '10. Changes to This Policy', body: 'We may update this privacy policy from time to time. We will notify you of significant changes by posting a notice on our website or sending you an email.', }, { title: '11. Data Retention', body: 'We retain your personal information for as long as necessary to fulfill the purposes outlined in this policy, unless a longer retention period is required by law.', }, { title: '12. Contact Us', body: 'If you have questions about this privacy policy or our data practices, please contact our privacy team through the support channels provided on our website.', }, ] ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const OutsideScroll = () => { let contentRef: HTMLDivElement | undefined return ( contentRef!}> Open Dialog Privacy Policy This layout allows the dialog to extend beyond the viewport while keeping the outer container scrollable.
                    {CONTENT_SECTIONS.map((item) => (

                    {item.title}

                    {item.body}

                    ))}
                    ) } const CONTENT_SECTIONS = [ { title: '1. Information We Collect', body: 'We collect information you provide directly, such as when you create an account, make a purchase, or contact us for support. This may include your name, email address, and payment information.', }, { title: '2. How We Use Your Information', body: 'We use the information we collect to provide and improve our services, process transactions, send communications, and personalize your experience.', }, { title: '3. Information Sharing', body: 'We do not sell your personal information. We may share information with service providers who assist in our operations, or when required by law.', }, { title: '4. Data Security', body: 'We implement appropriate technical and organizational measures to protect your personal information against unauthorized access, alteration, or destruction.', }, { title: '5. Your Rights', body: 'You have the right to access, correct, or delete your personal information. You may also opt out of marketing communications at any time.', }, { title: '6. Cookies and Tracking', body: 'We use cookies and similar technologies to enhance your experience, analyze usage patterns, and deliver targeted content. You can manage cookie preferences in your browser settings.', }, { title: '7. Third-Party Services', body: 'Our service may contain links to third-party websites. We are not responsible for the privacy practices of these external sites.', }, { title: '8. Children Privacy', body: 'Our services are not directed to children under 13. We do not knowingly collect personal information from children without parental consent.', }, { title: '9. International Transfers', body: 'Your information may be transferred to and processed in countries other than your own. We ensure appropriate safeguards are in place for such transfers.', }, { title: '10. Changes to This Policy', body: 'We may update this privacy policy from time to time. We will notify you of significant changes by posting a notice on our website or sending you an email.', }, { title: '11. Data Retention', body: 'We retain your personal information for as long as necessary to fulfill the purposes outlined in this policy, unless a longer retention period is required by law.', }, { title: '12. Contact Us', body: 'If you have questions about this privacy policy or our data practices, please contact our privacy team through the support channels provided on our website.', }, ] ``` #### Vue ```vue ``` #### Svelte ```svelte contentRef}> Open Dialog Privacy Policy This layout allows the dialog to extend beyond the viewport while keeping the outer container scrollable.
                    {#each CONTENT_SECTIONS as item}

                    {item.title}

                    {item.body}

                    {/each}
                    ``` ### Context Use the `Dialog.Context` component to access the dialog's state and methods. **Example: context** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Context = () => ( Open Dialog Status {(dialog) => Dialog is {dialog.open ? 'open' : 'closed'}} ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Context = () => ( Open Dialog Status {(dialog) => Dialog is {dialog().open ? 'open' : 'closed'}} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Status {#snippet children(dialog)} Dialog is {dialog().open ? 'open' : 'closed'} {/snippet} ``` ### Open from Menu Open a dialog imperatively from a menu item using the `onClick` handler. **Example: open-from-menu** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Menu } from '@ark-ui/react/menu' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import dialog from 'styles/dialog.module.css' import menu from 'styles/menu.module.css' export const OpenFromMenu = () => { const [open, setOpen] = useState(false) return ( <> Actions Edit Duplicate setOpen(true)}> Delete... setOpen(e.open)} role="alertdialog"> Confirm Delete Are you sure you want to delete this item? This action cannot be undone. ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import dialog from 'styles/dialog.module.css' import menu from 'styles/menu.module.css' export const OpenFromMenu = () => { const [open, setOpen] = createSignal(false) return ( <> Actions Edit Duplicate setOpen(true)}> Delete... setOpen(e.open)} role="alertdialog"> Confirm Delete Are you sure you want to delete this item? This action cannot be undone. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Actions Edit Duplicate (open = true)}>Delete... Confirm Delete Are you sure you want to delete this item? This action cannot be undone. ``` ### Nested Nest dialogs within one another. The parent receives `data-has-nested` and `--nested-layer-count` CSS variable for styling effects like zoom-out: ```css [data-part='content'][data-has-nested] { transform: scale(calc(1 - var(--nested-layer-count) * 0.05)); } ``` **Example: nested** #### React ```tsx import { Dialog, useDialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Nested = () => { const parentDialog = useDialog() const childDialog = useDialog() return ( <> Parent Dialog This is the parent dialog. Open a nested dialog to see automatic z-index management.
                    Nested Dialog This dialog is nested within the parent with proper z-index layering. ) } ``` #### Solid ```tsx import { Dialog, useDialog } from '@ark-ui/solid/dialog' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/dialog.module.css' export const Nested = () => { const parentDialog = useDialog() const childDialog = useDialog() return ( <> Parent Dialog This is the parent dialog. Open a nested dialog from here.
                    Nested Dialog This is a nested dialog with proper z-index layering. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Parent Dialog This is the parent dialog. Open a nested dialog from here.
                    Nested Dialog This is a nested dialog with proper z-index layering. ``` ### Confirmation Intercept close attempts to show confirmation prompts, preventing data loss from unsaved changes. **Example: confirmation** #### React ```tsx import { Dialog, useDialog } from '@ark-ui/react/dialog' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import field from 'styles/field.module.css' import styles from 'styles/dialog.module.css' export const Confirmation = () => { const [formContent, setFormContent] = useState('') const [isParentDialogOpen, setIsParentDialogOpen] = useState(false) const parentDialog = useDialog({ open: isParentDialogOpen, onOpenChange: (details) => { if (!details.open && formContent.trim()) { confirmDialog.setOpen(true) } else { setIsParentDialogOpen(details.open) } }, }) const confirmDialog = useDialog() const handleConfirmClose = () => { confirmDialog.setOpen(false) parentDialog.setOpen(false) setFormContent('') } return ( <> Edit Content Make changes to your content. You'll be asked to confirm before closing if there are unsaved changes.
                    Unsaved Changes You have unsaved changes. Are you sure you want to discard them?
                    ``` #### Svelte ```svelte Edit Content Make changes to your content. You'll be asked to confirm if you have unsaved changes.
                    Unsaved Changes You have unsaved changes. Are you sure you want to discard them?
                    ``` ## Guides ### Close Behavior - `closeOnEscape={false}` - Prevent closing on Escape - `closeOnInteractOutside={false}` - Prevent closing on outside click For conditional control, use `onEscapeKeyDown` or `onInteractOutside` with `e.preventDefault()`. ### Z-Index Stacking Use the `--layer-index` CSS variable for z-index management of stacked dialogs: ```css [data-part='content'] { z-index: calc(var(--layer-index)); } ``` ### Dynamic Imports When using `lazyMount` with `React.lazy` or Next.js `dynamic`, wrap the imported component in `Suspense`: ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Suspense } from 'react' import dynamic from 'next/dynamic' const HeavyComponent = dynamic(() => import('./HeavyComponent')) export const Demo = () => ( Open Loading...}> ) ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered | | `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed | | `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked | | `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. | | `finalFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is closed | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string positioner: string backdrop: string content: string closeTrigger: string title: string description: string }>` | No | The ids of the elements in the dialog. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is opened | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function to call when the dialog's open state changes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the dialog | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened | | `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened | | `role` | `'dialog' | 'alertdialog'` | No | The dialog's role | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | dialog | | `[data-has-nested]` | dialog | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested dialogs | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDialogReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered | | `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed | | `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked | | `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. | | `finalFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is closed | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string positioner: string backdrop: string content: string closeTrigger: string title: string description: string }>` | No | The ids of the elements in the dialog. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is opened | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function to call when the dialog's open state changes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the dialog | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened | | `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened | | `role` | `'dialog' | 'alertdialog'` | No | The dialog's role | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | dialog | | `[data-has-nested]` | dialog | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested dialogs | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDialogReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'h2'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered | | `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed | | `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked | | `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. | | `finalFocusEl` | `() => HTMLElement | null` | No | Element to receive focus when the dialog is closed | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string positioner: string backdrop: string content: string closeTrigger: string title: string description: string }>` | No | The ids of the elements in the dialog. Useful for composition. | | `initialFocusEl` | `() => HTMLElement | null` | No | Element to receive focus when the dialog is opened | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it | | `open` | `boolean` | No | The controlled open state of the dialog | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened | | `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened | | `role` | `'dialog' | 'alertdialog'` | No | The dialog's role | | `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | dialog | | `[data-has-nested]` | dialog | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested dialogs | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `DialogApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered | | `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed | | `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked | | `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered. Use when you don't need to control the open state of the dialog. | | `finalFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is closed | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string positioner: string backdrop: string content: string closeTrigger: string title: string description: string }>` | No | The ids of the elements in the dialog. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is opened | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function to call when the dialog's open state changes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the dialog | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened | | `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened | | `role` | `'alertdialog' | 'dialog'` | No | The dialog's role | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | dialog | | `[data-has-nested]` | dialog | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested dialogs | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'p'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseDialogReturn` | Yes | | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | dialog | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the dialog is open | | `setOpen` | `(open: boolean) => void` | Function to open or close the dialog | ## Accessibility Complies with the [Dialog WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/). ### Keyboard Support **`Enter`** Description: When focus is on the trigger, opens the dialog. **`Tab`** Description: Moves focus to the next focusable element within the content. Focus is trapped within the dialog. **`Shift + Tab`** Description: Moves focus to the previous focusable element. Focus is trapped within the dialog. **`Esc`** Description: Closes the dialog and moves focus to trigger or the defined final focus element --- # Editable (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { PencilIcon } from 'lucide-react' import styles from 'styles/editable.module.css' export const Basic = () => ( Label ) ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { PencilIcon } from 'lucide-solid' import styles from 'styles/editable.module.css' export const Basic = () => ( Label ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### Controlled Use the `value` and `onValueChange` props to control the editable state. **Example: controlled** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { PencilIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/editable.module.css' export const Controlled = () => { const [value, setValue] = useState('Hello World') return ( setValue(e.value)} > Label ) } ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { PencilIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/editable.module.css' export const Controlled = () => { const [value, setValue] = createSignal('Hello World') return ( setValue(e.value)} > Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte (value = e.value)}> Label ``` ### 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. **Example: root-provider** #### React ```tsx import { Editable, useEditable } from '@ark-ui/react/editable' import { PencilIcon } from 'lucide-react' import styles from 'styles/editable.module.css' export const RootProvider = () => { const editable = useEditable({ defaultValue: 'Hello World' }) return ( Label ) } ``` #### Solid ```tsx import { Editable, useEditable } from '@ark-ui/solid/editable' import { PencilIcon } from 'lucide-solid' import styles from 'styles/editable.module.css' export const RootProvider = () => { const editable = useEditable({ defaultValue: 'Hello World' }) return ( Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### Context Use `Editable.Context` to access the editable state and show contextual UI like keyboard hints when editing. **Example: context** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { PencilIcon } from 'lucide-react' import styles from 'styles/editable.module.css' export const Context = () => ( Label {(editable) => editable.editing ? ( Enter to save, Esc to cancel ) : ( ) } ) ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { PencilIcon } from 'lucide-solid' import { Show } from 'solid-js' import styles from 'styles/editable.module.css' export const Context = () => ( Label {(editable) => ( } > Enter to save, Esc to cancel )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(editable)} {#if editable().editing} Enter to save, Esc to cancel {:else} {/if} {/snippet} ``` ### 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. **Example: controls** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { CheckIcon, PencilIcon, XIcon } from 'lucide-react' import styles from 'styles/editable.module.css' export const Controls = () => ( Label {(editable) => ( {editable.editing ? ( <> ) : ( )} )} ) ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { CheckIcon, PencilIcon, XIcon } from 'lucide-solid' import { Show } from 'solid-js' import styles from 'styles/editable.module.css' export const Controls = () => ( Label {(editable) => ( } > )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(editable)} {#if editable().editing} {:else} {/if} {/snippet} ``` ### Textarea Use the `asChild` prop on `Editable.Input` to render a textarea for multi-line editing. **Example: textarea** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import styles from 'styles/editable.module.css' export const Textarea = () => ( Description {/snippet}
                    Press Cmd + Enter to save
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { Field } from '@ark-ui/react/field' import field from 'styles/field.module.css' import styles from 'styles/editable.module.css' export const WithField = () => ( Bio Click to edit your bio Bio is required ) ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { Field } from '@ark-ui/solid/field' import field from 'styles/field.module.css' import styles from 'styles/editable.module.css' export const WithField = () => ( Bio Double-click to edit your bio Bio is required ) ``` #### Vue ```vue ``` #### Svelte ```svelte Bio Double-click to edit your bio Bio is required ``` ## Guides ### Auto-resizing To auto-grow the editable as the content changes, set the `autoResize` prop to `true`. ```tsx {/*...*/} ``` ### Max Length Use the `maxLength` prop to set a maximum number of characters that can be entered into the editable. ```tsx {/*...*/} ``` ### Double Click The editable supports two modes of activating the "edit" state: - when the preview part is focused (with pointer or keyboard). - when the preview part is double-clicked. To change the mode to double-click, pass the prop `activationMode="dblclick"`. ```tsx {/*...*/} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `ActivationMode` | No | The activation mode for the preview element. - "focus" - Enter edit mode when the preview is focused - "dblclick" - Enter edit mode when the preview is double-clicked - "click" - Enter edit mode when the preview is clicked - "none" - Edit can be triggered programmatically only | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoResize` | `boolean` | No | Whether the editable should auto-resize to fit the content. | | `defaultEdit` | `boolean` | No | Whether the editable is in edit mode by default. | | `defaultValue` | `string` | No | The initial value of the editable when rendered. Use when you don't need to control the value of the editable. | | `disabled` | `boolean` | No | Whether the editable is disabled. | | `edit` | `boolean` | No | Whether the editable is in edit mode. | | `finalFocusEl` | `() => HTMLElement | null` | No | The element to receive focus when the editable is closed. | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string area: string label: string preview: string input: string control: string submitTrigger: string cancelTrigger: string editTrigger: string }>` | No | The ids of the elements in the editable. Useful for composition. | | `invalid` | `boolean` | No | Whether the input's value is invalid. | | `maxLength` | `number` | No | The maximum number of characters allowed in the editable | | `name` | `string` | No | The name attribute of the editable component. Used for form submission. | | `onEditChange` | `(details: EditChangeDetails) => void` | No | Function to call when the edit mode changes. | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the value changes. | | `onValueCommit` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is committed. | | `onValueRevert` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is reverted. | | `placeholder` | `string | { edit: string; preview: string }` | No | The placeholder text for the editable. | | `readOnly` | `boolean` | No | Whether the editable is read-only. | | `required` | `boolean` | No | Whether the editable is required. | | `selectOnFocus` | `boolean` | No | Whether to select the text in the input when it is focused. | | `submitMode` | `SubmitMode` | No | The action that triggers submit in the edit mode: - "enter" - Trigger submit when the enter key is pressed - "blur" - Trigger submit when the editable is blurred - "none" - No action will trigger submit. You need to use the submit button - "both" - Pressing `Enter` and blurring the input will trigger submit | | `translations` | `IntlTranslations` | No | The translations for the editable. | | `value` | `string` | No | The controlled value of the editable. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | area | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-placeholder-shown]` | Present when placeholder is shown | **CancelTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EditTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | label | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Preview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Preview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | preview | | `[data-placeholder-shown]` | Present when placeholder is shown | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseEditableReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SubmitTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `ActivationMode` | No | The activation mode for the preview element. - "focus" - Enter edit mode when the preview is focused - "dblclick" - Enter edit mode when the preview is double-clicked - "click" - Enter edit mode when the preview is clicked - "none" - Edit can be triggered programmatically only | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoResize` | `boolean` | No | Whether the editable should auto-resize to fit the content. | | `defaultEdit` | `boolean` | No | Whether the editable is in edit mode by default. | | `defaultValue` | `string` | No | The initial value of the editable when rendered. Use when you don't need to control the value of the editable. | | `disabled` | `boolean` | No | Whether the editable is disabled. | | `edit` | `boolean` | No | Whether the editable is in edit mode. | | `finalFocusEl` | `() => HTMLElement | null` | No | The element to receive focus when the editable is closed. | | `form` | `string` | No | The associate form of the underlying input. | | `ids` | `Partial<{ root: string area: string label: string preview: string input: string control: string submitTrigger: string cancelTrigger: string editTrigger: string }>` | No | The ids of the elements in the editable. Useful for composition. | | `invalid` | `boolean` | No | Whether the input's value is invalid. | | `maxLength` | `number` | No | The maximum number of characters allowed in the editable | | `name` | `string` | No | The name attribute of the editable component. Used for form submission. | | `onEditChange` | `(details: EditChangeDetails) => void` | No | Function to call when the edit mode changes. | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the value changes. | | `onValueCommit` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is committed. | | `onValueRevert` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is reverted. | | `placeholder` | `string | { edit: string; preview: string }` | No | The placeholder text for the editable. | | `readOnly` | `boolean` | No | Whether the editable is read-only. | | `required` | `boolean` | No | Whether the editable is required. | | `selectOnFocus` | `boolean` | No | Whether to select the text in the input when it is focused. | | `submitMode` | `SubmitMode` | No | The action that triggers submit in the edit mode: - "enter" - Trigger submit when the enter key is pressed - "blur" - Trigger submit when the editable is blurred - "none" - No action will trigger submit. You need to use the submit button - "both" - Pressing `Enter` and blurring the input will trigger submit | | `translations` | `IntlTranslations` | No | The translations for the editable. | | `value` | `string` | No | The controlled value of the editable. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | area | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-placeholder-shown]` | Present when placeholder is shown | **CancelTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EditTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | label | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Preview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Preview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | preview | | `[data-placeholder-shown]` | Present when placeholder is shown | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseEditableReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SubmitTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `ActivationMode` | No | The activation mode for the preview element. - "focus" - Enter edit mode when the preview is focused - "dblclick" - Enter edit mode when the preview is double-clicked - "click" - Enter edit mode when the preview is clicked | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoResize` | `boolean` | No | Whether the editable should auto-resize to fit the content. | | `defaultEdit` | `boolean` | No | Whether the editable is in edit mode by default. | | `defaultValue` | `string` | No | The initial value of the editable when rendered. Use when you don't need to control the value of the editable. | | `disabled` | `boolean` | No | Whether the editable is disabled. | | `edit` | `boolean` | No | Whether the editable is in edit mode. | | `finalFocusEl` | `() => HTMLElement | null` | No | The element to receive focus when the editable is closed. | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string area: string label: string preview: string input: string control: string submitTrigger: string cancelTrigger: string editTrigger: string }>` | No | The ids of the elements in the editable. Useful for composition. | | `invalid` | `boolean` | No | Whether the input's value is invalid. | | `maxLength` | `number` | No | The maximum number of characters allowed in the editable | | `modelValue` | `string` | No | The v-model value of the editable | | `name` | `string` | No | The name attribute of the editable component. Used for form submission. | | `placeholder` | `string | { edit: string; preview: string }` | No | The placeholder text for the editable. | | `readOnly` | `boolean` | No | Whether the editable is read-only. | | `required` | `boolean` | No | Whether the editable is required. | | `selectOnFocus` | `boolean` | No | Whether to select the text in the input when it is focused. | | `submitMode` | `SubmitMode` | No | The action that triggers submit in the edit mode: - "enter" - Trigger submit when the enter key is pressed - "blur" - Trigger submit when the editable is blurred - "none" - No action will trigger submit. You need to use the submit button - "both" - Pressing `Enter` and blurring the input will trigger submit | | `translations` | `IntlTranslations` | No | The translations for the editable. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | area | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-placeholder-shown]` | Present when placeholder is shown | **CancelTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EditTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | label | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Preview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Preview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | preview | | `[data-placeholder-shown]` | Present when placeholder is shown | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `EditableApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SubmitTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `ActivationMode` | No | The activation mode for the preview element. - "focus" - Enter edit mode when the preview is focused - "dblclick" - Enter edit mode when the preview is double-clicked - "click" - Enter edit mode when the preview is clicked - "none" - Edit can be triggered programmatically only | | `autoResize` | `boolean` | No | Whether the editable should auto-resize to fit the content. | | `defaultEdit` | `boolean` | No | Whether the editable is in edit mode by default. | | `defaultValue` | `string` | No | The initial value of the editable when rendered. Use when you don't need to control the value of the editable. | | `disabled` | `boolean` | No | Whether the editable is disabled. | | `edit` | `boolean` | No | Whether the editable is in edit mode. | | `finalFocusEl` | `() => HTMLElement | null` | No | The element to receive focus when the editable is closed. | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string area: string label: string preview: string input: string control: string submitTrigger: string cancelTrigger: string editTrigger: string }>` | No | The ids of the elements in the editable. Useful for composition. | | `invalid` | `boolean` | No | Whether the input's value is invalid. | | `maxLength` | `number` | No | The maximum number of characters allowed in the editable | | `name` | `string` | No | The name attribute of the editable component. Used for form submission. | | `onEditChange` | `(details: EditChangeDetails) => void` | No | Function to call when the edit mode changes. | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the value changes. | | `onValueCommit` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is committed. | | `onValueRevert` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is reverted. | | `placeholder` | `string | { edit: string; preview: string }` | No | The placeholder text for the editable. | | `readOnly` | `boolean` | No | Whether the editable is read-only. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the editable is required. | | `selectOnFocus` | `boolean` | No | Whether to select the text in the input when it is focused. | | `submitMode` | `SubmitMode` | No | The action that triggers submit in the edit mode: - "enter" - Trigger submit when the enter key is pressed - "blur" - Trigger submit when the editable is blurred - "none" - No action will trigger submit. You need to use the submit button - "both" - Pressing `Enter` and blurring the input will trigger submit | | `translations` | `IntlTranslations` | No | The translations for the editable. | | `value` | `string` | No | The controlled value of the editable. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | area | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-placeholder-shown]` | Present when placeholder is shown | **CancelTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseEditableContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **EditTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | label | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Preview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Preview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | preview | | `[data-placeholder-shown]` | Present when placeholder is shown | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseEditableReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **SubmitTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `editing` | `boolean` | Whether the editable is in edit mode | | `empty` | `boolean` | Whether the editable value is empty | | `value` | `string` | The current value of the editable | | `valueText` | `string` | The current value of the editable, or the placeholder if the value is empty | | `setValue` | `(value: string) => void` | Function to set the value of the editable | | `clearValue` | `VoidFunction` | Function to clear the value of the editable | | `edit` | `VoidFunction` | Function to enter edit mode | | `cancel` | `VoidFunction` | Function to exit edit mode, and discard any changes | | `submit` | `VoidFunction` | Function to exit edit mode, and submit any changes | ## Accessibility ### Keyboard Support **`Enter`** Description: Saves the edited content and exits edit mode. **`Escape`** Description: Discards the changes and exits edit mode. --- # Editable (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { PencilIcon } from 'lucide-react' import styles from 'styles/editable.module.css' export const Basic = () => ( Label ) ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { PencilIcon } from 'lucide-solid' import styles from 'styles/editable.module.css' export const Basic = () => ( Label ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### Controlled Use the `value` and `onValueChange` props to control the editable state. **Example: controlled** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { PencilIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/editable.module.css' export const Controlled = () => { const [value, setValue] = useState('Hello World') return ( setValue(e.value)} > Label ) } ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { PencilIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/editable.module.css' export const Controlled = () => { const [value, setValue] = createSignal('Hello World') return ( setValue(e.value)} > Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte (value = e.value)}> Label ``` ### 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. **Example: root-provider** #### React ```tsx import { Editable, useEditable } from '@ark-ui/react/editable' import { PencilIcon } from 'lucide-react' import styles from 'styles/editable.module.css' export const RootProvider = () => { const editable = useEditable({ defaultValue: 'Hello World' }) return ( Label ) } ``` #### Solid ```tsx import { Editable, useEditable } from '@ark-ui/solid/editable' import { PencilIcon } from 'lucide-solid' import styles from 'styles/editable.module.css' export const RootProvider = () => { const editable = useEditable({ defaultValue: 'Hello World' }) return ( Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### Context Use `Editable.Context` to access the editable state and show contextual UI like keyboard hints when editing. **Example: context** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { PencilIcon } from 'lucide-react' import styles from 'styles/editable.module.css' export const Context = () => ( Label {(editable) => editable.editing ? ( Enter to save, Esc to cancel ) : ( ) } ) ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { PencilIcon } from 'lucide-solid' import { Show } from 'solid-js' import styles from 'styles/editable.module.css' export const Context = () => ( Label {(editable) => ( } > Enter to save, Esc to cancel )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(editable)} {#if editable().editing} Enter to save, Esc to cancel {:else} {/if} {/snippet} ``` ### 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. **Example: controls** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { CheckIcon, PencilIcon, XIcon } from 'lucide-react' import styles from 'styles/editable.module.css' export const Controls = () => ( Label {(editable) => ( {editable.editing ? ( <> ) : ( )} )} ) ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { CheckIcon, PencilIcon, XIcon } from 'lucide-solid' import { Show } from 'solid-js' import styles from 'styles/editable.module.css' export const Controls = () => ( Label {(editable) => ( } > )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(editable)} {#if editable().editing} {:else} {/if} {/snippet} ``` ### Textarea Use the `asChild` prop on `Editable.Input` to render a textarea for multi-line editing. **Example: textarea** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import styles from 'styles/editable.module.css' export const Textarea = () => ( Description {/snippet}
                    Press Cmd + Enter to save
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { Field } from '@ark-ui/react/field' import field from 'styles/field.module.css' import styles from 'styles/editable.module.css' export const WithField = () => ( Bio Click to edit your bio Bio is required ) ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { Field } from '@ark-ui/solid/field' import field from 'styles/field.module.css' import styles from 'styles/editable.module.css' export const WithField = () => ( Bio Double-click to edit your bio Bio is required ) ``` #### Vue ```vue ``` #### Svelte ```svelte Bio Double-click to edit your bio Bio is required ``` ## Guides ### Auto-resizing To auto-grow the editable as the content changes, set the `autoResize` prop to `true`. ```tsx {/*...*/} ``` ### Max Length Use the `maxLength` prop to set a maximum number of characters that can be entered into the editable. ```tsx {/*...*/} ``` ### Double Click The editable supports two modes of activating the "edit" state: - when the preview part is focused (with pointer or keyboard). - when the preview part is double-clicked. To change the mode to double-click, pass the prop `activationMode="dblclick"`. ```tsx {/*...*/} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `ActivationMode` | No | The activation mode for the preview element. - "focus" - Enter edit mode when the preview is focused - "dblclick" - Enter edit mode when the preview is double-clicked - "click" - Enter edit mode when the preview is clicked - "none" - Edit can be triggered programmatically only | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoResize` | `boolean` | No | Whether the editable should auto-resize to fit the content. | | `defaultEdit` | `boolean` | No | Whether the editable is in edit mode by default. | | `defaultValue` | `string` | No | The initial value of the editable when rendered. Use when you don't need to control the value of the editable. | | `disabled` | `boolean` | No | Whether the editable is disabled. | | `edit` | `boolean` | No | Whether the editable is in edit mode. | | `finalFocusEl` | `() => HTMLElement | null` | No | The element to receive focus when the editable is closed. | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string area: string label: string preview: string input: string control: string submitTrigger: string cancelTrigger: string editTrigger: string }>` | No | The ids of the elements in the editable. Useful for composition. | | `invalid` | `boolean` | No | Whether the input's value is invalid. | | `maxLength` | `number` | No | The maximum number of characters allowed in the editable | | `name` | `string` | No | The name attribute of the editable component. Used for form submission. | | `onEditChange` | `(details: EditChangeDetails) => void` | No | Function to call when the edit mode changes. | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the value changes. | | `onValueCommit` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is committed. | | `onValueRevert` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is reverted. | | `placeholder` | `string | { edit: string; preview: string }` | No | The placeholder text for the editable. | | `readOnly` | `boolean` | No | Whether the editable is read-only. | | `required` | `boolean` | No | Whether the editable is required. | | `selectOnFocus` | `boolean` | No | Whether to select the text in the input when it is focused. | | `submitMode` | `SubmitMode` | No | The action that triggers submit in the edit mode: - "enter" - Trigger submit when the enter key is pressed - "blur" - Trigger submit when the editable is blurred - "none" - No action will trigger submit. You need to use the submit button - "both" - Pressing `Enter` and blurring the input will trigger submit | | `translations` | `IntlTranslations` | No | The translations for the editable. | | `value` | `string` | No | The controlled value of the editable. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | area | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-placeholder-shown]` | Present when placeholder is shown | **CancelTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EditTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | label | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Preview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Preview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | preview | | `[data-placeholder-shown]` | Present when placeholder is shown | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseEditableReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SubmitTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `ActivationMode` | No | The activation mode for the preview element. - "focus" - Enter edit mode when the preview is focused - "dblclick" - Enter edit mode when the preview is double-clicked - "click" - Enter edit mode when the preview is clicked - "none" - Edit can be triggered programmatically only | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoResize` | `boolean` | No | Whether the editable should auto-resize to fit the content. | | `defaultEdit` | `boolean` | No | Whether the editable is in edit mode by default. | | `defaultValue` | `string` | No | The initial value of the editable when rendered. Use when you don't need to control the value of the editable. | | `disabled` | `boolean` | No | Whether the editable is disabled. | | `edit` | `boolean` | No | Whether the editable is in edit mode. | | `finalFocusEl` | `() => HTMLElement | null` | No | The element to receive focus when the editable is closed. | | `form` | `string` | No | The associate form of the underlying input. | | `ids` | `Partial<{ root: string area: string label: string preview: string input: string control: string submitTrigger: string cancelTrigger: string editTrigger: string }>` | No | The ids of the elements in the editable. Useful for composition. | | `invalid` | `boolean` | No | Whether the input's value is invalid. | | `maxLength` | `number` | No | The maximum number of characters allowed in the editable | | `name` | `string` | No | The name attribute of the editable component. Used for form submission. | | `onEditChange` | `(details: EditChangeDetails) => void` | No | Function to call when the edit mode changes. | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the value changes. | | `onValueCommit` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is committed. | | `onValueRevert` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is reverted. | | `placeholder` | `string | { edit: string; preview: string }` | No | The placeholder text for the editable. | | `readOnly` | `boolean` | No | Whether the editable is read-only. | | `required` | `boolean` | No | Whether the editable is required. | | `selectOnFocus` | `boolean` | No | Whether to select the text in the input when it is focused. | | `submitMode` | `SubmitMode` | No | The action that triggers submit in the edit mode: - "enter" - Trigger submit when the enter key is pressed - "blur" - Trigger submit when the editable is blurred - "none" - No action will trigger submit. You need to use the submit button - "both" - Pressing `Enter` and blurring the input will trigger submit | | `translations` | `IntlTranslations` | No | The translations for the editable. | | `value` | `string` | No | The controlled value of the editable. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | area | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-placeholder-shown]` | Present when placeholder is shown | **CancelTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EditTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | label | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Preview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Preview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | preview | | `[data-placeholder-shown]` | Present when placeholder is shown | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseEditableReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SubmitTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `ActivationMode` | No | The activation mode for the preview element. - "focus" - Enter edit mode when the preview is focused - "dblclick" - Enter edit mode when the preview is double-clicked - "click" - Enter edit mode when the preview is clicked | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoResize` | `boolean` | No | Whether the editable should auto-resize to fit the content. | | `defaultEdit` | `boolean` | No | Whether the editable is in edit mode by default. | | `defaultValue` | `string` | No | The initial value of the editable when rendered. Use when you don't need to control the value of the editable. | | `disabled` | `boolean` | No | Whether the editable is disabled. | | `edit` | `boolean` | No | Whether the editable is in edit mode. | | `finalFocusEl` | `() => HTMLElement | null` | No | The element to receive focus when the editable is closed. | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string area: string label: string preview: string input: string control: string submitTrigger: string cancelTrigger: string editTrigger: string }>` | No | The ids of the elements in the editable. Useful for composition. | | `invalid` | `boolean` | No | Whether the input's value is invalid. | | `maxLength` | `number` | No | The maximum number of characters allowed in the editable | | `modelValue` | `string` | No | The v-model value of the editable | | `name` | `string` | No | The name attribute of the editable component. Used for form submission. | | `placeholder` | `string | { edit: string; preview: string }` | No | The placeholder text for the editable. | | `readOnly` | `boolean` | No | Whether the editable is read-only. | | `required` | `boolean` | No | Whether the editable is required. | | `selectOnFocus` | `boolean` | No | Whether to select the text in the input when it is focused. | | `submitMode` | `SubmitMode` | No | The action that triggers submit in the edit mode: - "enter" - Trigger submit when the enter key is pressed - "blur" - Trigger submit when the editable is blurred - "none" - No action will trigger submit. You need to use the submit button - "both" - Pressing `Enter` and blurring the input will trigger submit | | `translations` | `IntlTranslations` | No | The translations for the editable. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | area | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-placeholder-shown]` | Present when placeholder is shown | **CancelTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EditTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | label | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Preview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Preview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | preview | | `[data-placeholder-shown]` | Present when placeholder is shown | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `EditableApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SubmitTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `ActivationMode` | No | The activation mode for the preview element. - "focus" - Enter edit mode when the preview is focused - "dblclick" - Enter edit mode when the preview is double-clicked - "click" - Enter edit mode when the preview is clicked - "none" - Edit can be triggered programmatically only | | `autoResize` | `boolean` | No | Whether the editable should auto-resize to fit the content. | | `defaultEdit` | `boolean` | No | Whether the editable is in edit mode by default. | | `defaultValue` | `string` | No | The initial value of the editable when rendered. Use when you don't need to control the value of the editable. | | `disabled` | `boolean` | No | Whether the editable is disabled. | | `edit` | `boolean` | No | Whether the editable is in edit mode. | | `finalFocusEl` | `() => HTMLElement | null` | No | The element to receive focus when the editable is closed. | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string area: string label: string preview: string input: string control: string submitTrigger: string cancelTrigger: string editTrigger: string }>` | No | The ids of the elements in the editable. Useful for composition. | | `invalid` | `boolean` | No | Whether the input's value is invalid. | | `maxLength` | `number` | No | The maximum number of characters allowed in the editable | | `name` | `string` | No | The name attribute of the editable component. Used for form submission. | | `onEditChange` | `(details: EditChangeDetails) => void` | No | Function to call when the edit mode changes. | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the value changes. | | `onValueCommit` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is committed. | | `onValueRevert` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is reverted. | | `placeholder` | `string | { edit: string; preview: string }` | No | The placeholder text for the editable. | | `readOnly` | `boolean` | No | Whether the editable is read-only. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the editable is required. | | `selectOnFocus` | `boolean` | No | Whether to select the text in the input when it is focused. | | `submitMode` | `SubmitMode` | No | The action that triggers submit in the edit mode: - "enter" - Trigger submit when the enter key is pressed - "blur" - Trigger submit when the editable is blurred - "none" - No action will trigger submit. You need to use the submit button - "both" - Pressing `Enter` and blurring the input will trigger submit | | `translations` | `IntlTranslations` | No | The translations for the editable. | | `value` | `string` | No | The controlled value of the editable. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | area | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-placeholder-shown]` | Present when placeholder is shown | **CancelTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseEditableContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **EditTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | label | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Preview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Preview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | preview | | `[data-placeholder-shown]` | Present when placeholder is shown | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseEditableReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **SubmitTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `editing` | `boolean` | Whether the editable is in edit mode | | `empty` | `boolean` | Whether the editable value is empty | | `value` | `string` | The current value of the editable | | `valueText` | `string` | The current value of the editable, or the placeholder if the value is empty | | `setValue` | `(value: string) => void` | Function to set the value of the editable | | `clearValue` | `VoidFunction` | Function to clear the value of the editable | | `edit` | `VoidFunction` | Function to enter edit mode | | `cancel` | `VoidFunction` | Function to exit edit mode, and discard any changes | | `submit` | `VoidFunction` | Function to exit edit mode, and submit any changes | ## Accessibility ### Keyboard Support **`Enter`** Description: Saves the edited content and exits edit mode. **`Escape`** Description: Discards the changes and exits edit mode. --- # Editable (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { PencilIcon } from 'lucide-react' import styles from 'styles/editable.module.css' export const Basic = () => ( Label ) ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { PencilIcon } from 'lucide-solid' import styles from 'styles/editable.module.css' export const Basic = () => ( Label ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### Controlled Use the `value` and `onValueChange` props to control the editable state. **Example: controlled** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { PencilIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/editable.module.css' export const Controlled = () => { const [value, setValue] = useState('Hello World') return ( setValue(e.value)} > Label ) } ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { PencilIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/editable.module.css' export const Controlled = () => { const [value, setValue] = createSignal('Hello World') return ( setValue(e.value)} > Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte (value = e.value)}> Label ``` ### 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. **Example: root-provider** #### React ```tsx import { Editable, useEditable } from '@ark-ui/react/editable' import { PencilIcon } from 'lucide-react' import styles from 'styles/editable.module.css' export const RootProvider = () => { const editable = useEditable({ defaultValue: 'Hello World' }) return ( Label ) } ``` #### Solid ```tsx import { Editable, useEditable } from '@ark-ui/solid/editable' import { PencilIcon } from 'lucide-solid' import styles from 'styles/editable.module.css' export const RootProvider = () => { const editable = useEditable({ defaultValue: 'Hello World' }) return ( Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### Context Use `Editable.Context` to access the editable state and show contextual UI like keyboard hints when editing. **Example: context** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { PencilIcon } from 'lucide-react' import styles from 'styles/editable.module.css' export const Context = () => ( Label {(editable) => editable.editing ? ( Enter to save, Esc to cancel ) : ( ) } ) ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { PencilIcon } from 'lucide-solid' import { Show } from 'solid-js' import styles from 'styles/editable.module.css' export const Context = () => ( Label {(editable) => ( } > Enter to save, Esc to cancel )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(editable)} {#if editable().editing} Enter to save, Esc to cancel {:else} {/if} {/snippet} ``` ### 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. **Example: controls** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { CheckIcon, PencilIcon, XIcon } from 'lucide-react' import styles from 'styles/editable.module.css' export const Controls = () => ( Label {(editable) => ( {editable.editing ? ( <> ) : ( )} )} ) ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { CheckIcon, PencilIcon, XIcon } from 'lucide-solid' import { Show } from 'solid-js' import styles from 'styles/editable.module.css' export const Controls = () => ( Label {(editable) => ( } > )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(editable)} {#if editable().editing} {:else} {/if} {/snippet} ``` ### Textarea Use the `asChild` prop on `Editable.Input` to render a textarea for multi-line editing. **Example: textarea** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import styles from 'styles/editable.module.css' export const Textarea = () => ( Description {/snippet}
                    Press Cmd + Enter to save
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { Field } from '@ark-ui/react/field' import field from 'styles/field.module.css' import styles from 'styles/editable.module.css' export const WithField = () => ( Bio Click to edit your bio Bio is required ) ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { Field } from '@ark-ui/solid/field' import field from 'styles/field.module.css' import styles from 'styles/editable.module.css' export const WithField = () => ( Bio Double-click to edit your bio Bio is required ) ``` #### Vue ```vue ``` #### Svelte ```svelte Bio Double-click to edit your bio Bio is required ``` ## Guides ### Auto-resizing To auto-grow the editable as the content changes, set the `autoResize` prop to `true`. ```tsx {/*...*/} ``` ### Max Length Use the `maxLength` prop to set a maximum number of characters that can be entered into the editable. ```tsx {/*...*/} ``` ### Double Click The editable supports two modes of activating the "edit" state: - when the preview part is focused (with pointer or keyboard). - when the preview part is double-clicked. To change the mode to double-click, pass the prop `activationMode="dblclick"`. ```tsx {/*...*/} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `ActivationMode` | No | The activation mode for the preview element. - "focus" - Enter edit mode when the preview is focused - "dblclick" - Enter edit mode when the preview is double-clicked - "click" - Enter edit mode when the preview is clicked - "none" - Edit can be triggered programmatically only | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoResize` | `boolean` | No | Whether the editable should auto-resize to fit the content. | | `defaultEdit` | `boolean` | No | Whether the editable is in edit mode by default. | | `defaultValue` | `string` | No | The initial value of the editable when rendered. Use when you don't need to control the value of the editable. | | `disabled` | `boolean` | No | Whether the editable is disabled. | | `edit` | `boolean` | No | Whether the editable is in edit mode. | | `finalFocusEl` | `() => HTMLElement | null` | No | The element to receive focus when the editable is closed. | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string area: string label: string preview: string input: string control: string submitTrigger: string cancelTrigger: string editTrigger: string }>` | No | The ids of the elements in the editable. Useful for composition. | | `invalid` | `boolean` | No | Whether the input's value is invalid. | | `maxLength` | `number` | No | The maximum number of characters allowed in the editable | | `name` | `string` | No | The name attribute of the editable component. Used for form submission. | | `onEditChange` | `(details: EditChangeDetails) => void` | No | Function to call when the edit mode changes. | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the value changes. | | `onValueCommit` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is committed. | | `onValueRevert` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is reverted. | | `placeholder` | `string | { edit: string; preview: string }` | No | The placeholder text for the editable. | | `readOnly` | `boolean` | No | Whether the editable is read-only. | | `required` | `boolean` | No | Whether the editable is required. | | `selectOnFocus` | `boolean` | No | Whether to select the text in the input when it is focused. | | `submitMode` | `SubmitMode` | No | The action that triggers submit in the edit mode: - "enter" - Trigger submit when the enter key is pressed - "blur" - Trigger submit when the editable is blurred - "none" - No action will trigger submit. You need to use the submit button - "both" - Pressing `Enter` and blurring the input will trigger submit | | `translations` | `IntlTranslations` | No | The translations for the editable. | | `value` | `string` | No | The controlled value of the editable. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | area | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-placeholder-shown]` | Present when placeholder is shown | **CancelTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EditTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | label | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Preview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Preview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | preview | | `[data-placeholder-shown]` | Present when placeholder is shown | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseEditableReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SubmitTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `ActivationMode` | No | The activation mode for the preview element. - "focus" - Enter edit mode when the preview is focused - "dblclick" - Enter edit mode when the preview is double-clicked - "click" - Enter edit mode when the preview is clicked - "none" - Edit can be triggered programmatically only | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoResize` | `boolean` | No | Whether the editable should auto-resize to fit the content. | | `defaultEdit` | `boolean` | No | Whether the editable is in edit mode by default. | | `defaultValue` | `string` | No | The initial value of the editable when rendered. Use when you don't need to control the value of the editable. | | `disabled` | `boolean` | No | Whether the editable is disabled. | | `edit` | `boolean` | No | Whether the editable is in edit mode. | | `finalFocusEl` | `() => HTMLElement | null` | No | The element to receive focus when the editable is closed. | | `form` | `string` | No | The associate form of the underlying input. | | `ids` | `Partial<{ root: string area: string label: string preview: string input: string control: string submitTrigger: string cancelTrigger: string editTrigger: string }>` | No | The ids of the elements in the editable. Useful for composition. | | `invalid` | `boolean` | No | Whether the input's value is invalid. | | `maxLength` | `number` | No | The maximum number of characters allowed in the editable | | `name` | `string` | No | The name attribute of the editable component. Used for form submission. | | `onEditChange` | `(details: EditChangeDetails) => void` | No | Function to call when the edit mode changes. | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the value changes. | | `onValueCommit` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is committed. | | `onValueRevert` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is reverted. | | `placeholder` | `string | { edit: string; preview: string }` | No | The placeholder text for the editable. | | `readOnly` | `boolean` | No | Whether the editable is read-only. | | `required` | `boolean` | No | Whether the editable is required. | | `selectOnFocus` | `boolean` | No | Whether to select the text in the input when it is focused. | | `submitMode` | `SubmitMode` | No | The action that triggers submit in the edit mode: - "enter" - Trigger submit when the enter key is pressed - "blur" - Trigger submit when the editable is blurred - "none" - No action will trigger submit. You need to use the submit button - "both" - Pressing `Enter` and blurring the input will trigger submit | | `translations` | `IntlTranslations` | No | The translations for the editable. | | `value` | `string` | No | The controlled value of the editable. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | area | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-placeholder-shown]` | Present when placeholder is shown | **CancelTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EditTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | label | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Preview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Preview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | preview | | `[data-placeholder-shown]` | Present when placeholder is shown | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseEditableReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SubmitTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `ActivationMode` | No | The activation mode for the preview element. - "focus" - Enter edit mode when the preview is focused - "dblclick" - Enter edit mode when the preview is double-clicked - "click" - Enter edit mode when the preview is clicked | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoResize` | `boolean` | No | Whether the editable should auto-resize to fit the content. | | `defaultEdit` | `boolean` | No | Whether the editable is in edit mode by default. | | `defaultValue` | `string` | No | The initial value of the editable when rendered. Use when you don't need to control the value of the editable. | | `disabled` | `boolean` | No | Whether the editable is disabled. | | `edit` | `boolean` | No | Whether the editable is in edit mode. | | `finalFocusEl` | `() => HTMLElement | null` | No | The element to receive focus when the editable is closed. | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string area: string label: string preview: string input: string control: string submitTrigger: string cancelTrigger: string editTrigger: string }>` | No | The ids of the elements in the editable. Useful for composition. | | `invalid` | `boolean` | No | Whether the input's value is invalid. | | `maxLength` | `number` | No | The maximum number of characters allowed in the editable | | `modelValue` | `string` | No | The v-model value of the editable | | `name` | `string` | No | The name attribute of the editable component. Used for form submission. | | `placeholder` | `string | { edit: string; preview: string }` | No | The placeholder text for the editable. | | `readOnly` | `boolean` | No | Whether the editable is read-only. | | `required` | `boolean` | No | Whether the editable is required. | | `selectOnFocus` | `boolean` | No | Whether to select the text in the input when it is focused. | | `submitMode` | `SubmitMode` | No | The action that triggers submit in the edit mode: - "enter" - Trigger submit when the enter key is pressed - "blur" - Trigger submit when the editable is blurred - "none" - No action will trigger submit. You need to use the submit button - "both" - Pressing `Enter` and blurring the input will trigger submit | | `translations` | `IntlTranslations` | No | The translations for the editable. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | area | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-placeholder-shown]` | Present when placeholder is shown | **CancelTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EditTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | label | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Preview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Preview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | preview | | `[data-placeholder-shown]` | Present when placeholder is shown | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `EditableApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SubmitTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `ActivationMode` | No | The activation mode for the preview element. - "focus" - Enter edit mode when the preview is focused - "dblclick" - Enter edit mode when the preview is double-clicked - "click" - Enter edit mode when the preview is clicked - "none" - Edit can be triggered programmatically only | | `autoResize` | `boolean` | No | Whether the editable should auto-resize to fit the content. | | `defaultEdit` | `boolean` | No | Whether the editable is in edit mode by default. | | `defaultValue` | `string` | No | The initial value of the editable when rendered. Use when you don't need to control the value of the editable. | | `disabled` | `boolean` | No | Whether the editable is disabled. | | `edit` | `boolean` | No | Whether the editable is in edit mode. | | `finalFocusEl` | `() => HTMLElement | null` | No | The element to receive focus when the editable is closed. | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string area: string label: string preview: string input: string control: string submitTrigger: string cancelTrigger: string editTrigger: string }>` | No | The ids of the elements in the editable. Useful for composition. | | `invalid` | `boolean` | No | Whether the input's value is invalid. | | `maxLength` | `number` | No | The maximum number of characters allowed in the editable | | `name` | `string` | No | The name attribute of the editable component. Used for form submission. | | `onEditChange` | `(details: EditChangeDetails) => void` | No | Function to call when the edit mode changes. | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the value changes. | | `onValueCommit` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is committed. | | `onValueRevert` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is reverted. | | `placeholder` | `string | { edit: string; preview: string }` | No | The placeholder text for the editable. | | `readOnly` | `boolean` | No | Whether the editable is read-only. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the editable is required. | | `selectOnFocus` | `boolean` | No | Whether to select the text in the input when it is focused. | | `submitMode` | `SubmitMode` | No | The action that triggers submit in the edit mode: - "enter" - Trigger submit when the enter key is pressed - "blur" - Trigger submit when the editable is blurred - "none" - No action will trigger submit. You need to use the submit button - "both" - Pressing `Enter` and blurring the input will trigger submit | | `translations` | `IntlTranslations` | No | The translations for the editable. | | `value` | `string` | No | The controlled value of the editable. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | area | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-placeholder-shown]` | Present when placeholder is shown | **CancelTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseEditableContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **EditTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | label | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Preview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Preview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | preview | | `[data-placeholder-shown]` | Present when placeholder is shown | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseEditableReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **SubmitTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `editing` | `boolean` | Whether the editable is in edit mode | | `empty` | `boolean` | Whether the editable value is empty | | `value` | `string` | The current value of the editable | | `valueText` | `string` | The current value of the editable, or the placeholder if the value is empty | | `setValue` | `(value: string) => void` | Function to set the value of the editable | | `clearValue` | `VoidFunction` | Function to clear the value of the editable | | `edit` | `VoidFunction` | Function to enter edit mode | | `cancel` | `VoidFunction` | Function to exit edit mode, and discard any changes | | `submit` | `VoidFunction` | Function to exit edit mode, and submit any changes | ## Accessibility ### Keyboard Support **`Enter`** Description: Saves the edited content and exits edit mode. **`Escape`** Description: Discards the changes and exits edit mode. --- # Editable (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { PencilIcon } from 'lucide-react' import styles from 'styles/editable.module.css' export const Basic = () => ( Label ) ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { PencilIcon } from 'lucide-solid' import styles from 'styles/editable.module.css' export const Basic = () => ( Label ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### Controlled Use the `value` and `onValueChange` props to control the editable state. **Example: controlled** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { PencilIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/editable.module.css' export const Controlled = () => { const [value, setValue] = useState('Hello World') return ( setValue(e.value)} > Label ) } ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { PencilIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/editable.module.css' export const Controlled = () => { const [value, setValue] = createSignal('Hello World') return ( setValue(e.value)} > Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte (value = e.value)}> Label ``` ### 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. **Example: root-provider** #### React ```tsx import { Editable, useEditable } from '@ark-ui/react/editable' import { PencilIcon } from 'lucide-react' import styles from 'styles/editable.module.css' export const RootProvider = () => { const editable = useEditable({ defaultValue: 'Hello World' }) return ( Label ) } ``` #### Solid ```tsx import { Editable, useEditable } from '@ark-ui/solid/editable' import { PencilIcon } from 'lucide-solid' import styles from 'styles/editable.module.css' export const RootProvider = () => { const editable = useEditable({ defaultValue: 'Hello World' }) return ( Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### Context Use `Editable.Context` to access the editable state and show contextual UI like keyboard hints when editing. **Example: context** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { PencilIcon } from 'lucide-react' import styles from 'styles/editable.module.css' export const Context = () => ( Label {(editable) => editable.editing ? ( Enter to save, Esc to cancel ) : ( ) } ) ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { PencilIcon } from 'lucide-solid' import { Show } from 'solid-js' import styles from 'styles/editable.module.css' export const Context = () => ( Label {(editable) => ( } > Enter to save, Esc to cancel )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(editable)} {#if editable().editing} Enter to save, Esc to cancel {:else} {/if} {/snippet} ``` ### 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. **Example: controls** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { CheckIcon, PencilIcon, XIcon } from 'lucide-react' import styles from 'styles/editable.module.css' export const Controls = () => ( Label {(editable) => ( {editable.editing ? ( <> ) : ( )} )} ) ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { CheckIcon, PencilIcon, XIcon } from 'lucide-solid' import { Show } from 'solid-js' import styles from 'styles/editable.module.css' export const Controls = () => ( Label {(editable) => ( } > )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(editable)} {#if editable().editing} {:else} {/if} {/snippet} ``` ### Textarea Use the `asChild` prop on `Editable.Input` to render a textarea for multi-line editing. **Example: textarea** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import styles from 'styles/editable.module.css' export const Textarea = () => ( Description {/snippet}
                    Press Cmd + Enter to save
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Editable } from '@ark-ui/react/editable' import { Field } from '@ark-ui/react/field' import field from 'styles/field.module.css' import styles from 'styles/editable.module.css' export const WithField = () => ( Bio Click to edit your bio Bio is required ) ``` #### Solid ```tsx import { Editable } from '@ark-ui/solid/editable' import { Field } from '@ark-ui/solid/field' import field from 'styles/field.module.css' import styles from 'styles/editable.module.css' export const WithField = () => ( Bio Double-click to edit your bio Bio is required ) ``` #### Vue ```vue ``` #### Svelte ```svelte Bio Double-click to edit your bio Bio is required ``` ## Guides ### Auto-resizing To auto-grow the editable as the content changes, set the `autoResize` prop to `true`. ```tsx {/*...*/} ``` ### Max Length Use the `maxLength` prop to set a maximum number of characters that can be entered into the editable. ```tsx {/*...*/} ``` ### Double Click The editable supports two modes of activating the "edit" state: - when the preview part is focused (with pointer or keyboard). - when the preview part is double-clicked. To change the mode to double-click, pass the prop `activationMode="dblclick"`. ```tsx {/*...*/} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `ActivationMode` | No | The activation mode for the preview element. - "focus" - Enter edit mode when the preview is focused - "dblclick" - Enter edit mode when the preview is double-clicked - "click" - Enter edit mode when the preview is clicked - "none" - Edit can be triggered programmatically only | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoResize` | `boolean` | No | Whether the editable should auto-resize to fit the content. | | `defaultEdit` | `boolean` | No | Whether the editable is in edit mode by default. | | `defaultValue` | `string` | No | The initial value of the editable when rendered. Use when you don't need to control the value of the editable. | | `disabled` | `boolean` | No | Whether the editable is disabled. | | `edit` | `boolean` | No | Whether the editable is in edit mode. | | `finalFocusEl` | `() => HTMLElement | null` | No | The element to receive focus when the editable is closed. | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string area: string label: string preview: string input: string control: string submitTrigger: string cancelTrigger: string editTrigger: string }>` | No | The ids of the elements in the editable. Useful for composition. | | `invalid` | `boolean` | No | Whether the input's value is invalid. | | `maxLength` | `number` | No | The maximum number of characters allowed in the editable | | `name` | `string` | No | The name attribute of the editable component. Used for form submission. | | `onEditChange` | `(details: EditChangeDetails) => void` | No | Function to call when the edit mode changes. | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the value changes. | | `onValueCommit` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is committed. | | `onValueRevert` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is reverted. | | `placeholder` | `string | { edit: string; preview: string }` | No | The placeholder text for the editable. | | `readOnly` | `boolean` | No | Whether the editable is read-only. | | `required` | `boolean` | No | Whether the editable is required. | | `selectOnFocus` | `boolean` | No | Whether to select the text in the input when it is focused. | | `submitMode` | `SubmitMode` | No | The action that triggers submit in the edit mode: - "enter" - Trigger submit when the enter key is pressed - "blur" - Trigger submit when the editable is blurred - "none" - No action will trigger submit. You need to use the submit button - "both" - Pressing `Enter` and blurring the input will trigger submit | | `translations` | `IntlTranslations` | No | The translations for the editable. | | `value` | `string` | No | The controlled value of the editable. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | area | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-placeholder-shown]` | Present when placeholder is shown | **CancelTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EditTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | label | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Preview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Preview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | preview | | `[data-placeholder-shown]` | Present when placeholder is shown | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseEditableReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SubmitTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `ActivationMode` | No | The activation mode for the preview element. - "focus" - Enter edit mode when the preview is focused - "dblclick" - Enter edit mode when the preview is double-clicked - "click" - Enter edit mode when the preview is clicked - "none" - Edit can be triggered programmatically only | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoResize` | `boolean` | No | Whether the editable should auto-resize to fit the content. | | `defaultEdit` | `boolean` | No | Whether the editable is in edit mode by default. | | `defaultValue` | `string` | No | The initial value of the editable when rendered. Use when you don't need to control the value of the editable. | | `disabled` | `boolean` | No | Whether the editable is disabled. | | `edit` | `boolean` | No | Whether the editable is in edit mode. | | `finalFocusEl` | `() => HTMLElement | null` | No | The element to receive focus when the editable is closed. | | `form` | `string` | No | The associate form of the underlying input. | | `ids` | `Partial<{ root: string area: string label: string preview: string input: string control: string submitTrigger: string cancelTrigger: string editTrigger: string }>` | No | The ids of the elements in the editable. Useful for composition. | | `invalid` | `boolean` | No | Whether the input's value is invalid. | | `maxLength` | `number` | No | The maximum number of characters allowed in the editable | | `name` | `string` | No | The name attribute of the editable component. Used for form submission. | | `onEditChange` | `(details: EditChangeDetails) => void` | No | Function to call when the edit mode changes. | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the value changes. | | `onValueCommit` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is committed. | | `onValueRevert` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is reverted. | | `placeholder` | `string | { edit: string; preview: string }` | No | The placeholder text for the editable. | | `readOnly` | `boolean` | No | Whether the editable is read-only. | | `required` | `boolean` | No | Whether the editable is required. | | `selectOnFocus` | `boolean` | No | Whether to select the text in the input when it is focused. | | `submitMode` | `SubmitMode` | No | The action that triggers submit in the edit mode: - "enter" - Trigger submit when the enter key is pressed - "blur" - Trigger submit when the editable is blurred - "none" - No action will trigger submit. You need to use the submit button - "both" - Pressing `Enter` and blurring the input will trigger submit | | `translations` | `IntlTranslations` | No | The translations for the editable. | | `value` | `string` | No | The controlled value of the editable. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | area | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-placeholder-shown]` | Present when placeholder is shown | **CancelTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EditTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | label | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Preview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Preview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | preview | | `[data-placeholder-shown]` | Present when placeholder is shown | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseEditableReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SubmitTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `ActivationMode` | No | The activation mode for the preview element. - "focus" - Enter edit mode when the preview is focused - "dblclick" - Enter edit mode when the preview is double-clicked - "click" - Enter edit mode when the preview is clicked | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoResize` | `boolean` | No | Whether the editable should auto-resize to fit the content. | | `defaultEdit` | `boolean` | No | Whether the editable is in edit mode by default. | | `defaultValue` | `string` | No | The initial value of the editable when rendered. Use when you don't need to control the value of the editable. | | `disabled` | `boolean` | No | Whether the editable is disabled. | | `edit` | `boolean` | No | Whether the editable is in edit mode. | | `finalFocusEl` | `() => HTMLElement | null` | No | The element to receive focus when the editable is closed. | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string area: string label: string preview: string input: string control: string submitTrigger: string cancelTrigger: string editTrigger: string }>` | No | The ids of the elements in the editable. Useful for composition. | | `invalid` | `boolean` | No | Whether the input's value is invalid. | | `maxLength` | `number` | No | The maximum number of characters allowed in the editable | | `modelValue` | `string` | No | The v-model value of the editable | | `name` | `string` | No | The name attribute of the editable component. Used for form submission. | | `placeholder` | `string | { edit: string; preview: string }` | No | The placeholder text for the editable. | | `readOnly` | `boolean` | No | Whether the editable is read-only. | | `required` | `boolean` | No | Whether the editable is required. | | `selectOnFocus` | `boolean` | No | Whether to select the text in the input when it is focused. | | `submitMode` | `SubmitMode` | No | The action that triggers submit in the edit mode: - "enter" - Trigger submit when the enter key is pressed - "blur" - Trigger submit when the editable is blurred - "none" - No action will trigger submit. You need to use the submit button - "both" - Pressing `Enter` and blurring the input will trigger submit | | `translations` | `IntlTranslations` | No | The translations for the editable. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | area | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-placeholder-shown]` | Present when placeholder is shown | **CancelTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **EditTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | label | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Preview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Preview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | preview | | `[data-placeholder-shown]` | Present when placeholder is shown | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `EditableApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **SubmitTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `ActivationMode` | No | The activation mode for the preview element. - "focus" - Enter edit mode when the preview is focused - "dblclick" - Enter edit mode when the preview is double-clicked - "click" - Enter edit mode when the preview is clicked - "none" - Edit can be triggered programmatically only | | `autoResize` | `boolean` | No | Whether the editable should auto-resize to fit the content. | | `defaultEdit` | `boolean` | No | Whether the editable is in edit mode by default. | | `defaultValue` | `string` | No | The initial value of the editable when rendered. Use when you don't need to control the value of the editable. | | `disabled` | `boolean` | No | Whether the editable is disabled. | | `edit` | `boolean` | No | Whether the editable is in edit mode. | | `finalFocusEl` | `() => HTMLElement | null` | No | The element to receive focus when the editable is closed. | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string area: string label: string preview: string input: string control: string submitTrigger: string cancelTrigger: string editTrigger: string }>` | No | The ids of the elements in the editable. Useful for composition. | | `invalid` | `boolean` | No | Whether the input's value is invalid. | | `maxLength` | `number` | No | The maximum number of characters allowed in the editable | | `name` | `string` | No | The name attribute of the editable component. Used for form submission. | | `onEditChange` | `(details: EditChangeDetails) => void` | No | Function to call when the edit mode changes. | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the value changes. | | `onValueCommit` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is committed. | | `onValueRevert` | `(details: ValueChangeDetails) => void` | No | Function to call when the value is reverted. | | `placeholder` | `string | { edit: string; preview: string }` | No | The placeholder text for the editable. | | `readOnly` | `boolean` | No | Whether the editable is read-only. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the editable is required. | | `selectOnFocus` | `boolean` | No | Whether to select the text in the input when it is focused. | | `submitMode` | `SubmitMode` | No | The action that triggers submit in the edit mode: - "enter" - Trigger submit when the enter key is pressed - "blur" - Trigger submit when the editable is blurred - "none" - No action will trigger submit. You need to use the submit button - "both" - Pressing `Enter` and blurring the input will trigger submit | | `translations` | `IntlTranslations` | No | The translations for the editable. | | `value` | `string` | No | The controlled value of the editable. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Area Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | area | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-placeholder-shown]` | Present when placeholder is shown | **CancelTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseEditableContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **EditTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | label | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Preview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Preview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | editable | | `[data-part]` | preview | | `[data-placeholder-shown]` | Present when placeholder is shown | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-autoresize]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseEditableReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **SubmitTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `editing` | `boolean` | Whether the editable is in edit mode | | `empty` | `boolean` | Whether the editable value is empty | | `value` | `string` | The current value of the editable | | `valueText` | `string` | The current value of the editable, or the placeholder if the value is empty | | `setValue` | `(value: string) => void` | Function to set the value of the editable | | `clearValue` | `VoidFunction` | Function to clear the value of the editable | | `edit` | `VoidFunction` | Function to enter edit mode | | `cancel` | `VoidFunction` | Function to exit edit mode, and discard any changes | | `submit` | `VoidFunction` | Function to exit edit mode, and submit any changes | ## Accessibility ### Keyboard Support **`Enter`** Description: Saves the edited content and exits edit mode. **`Escape`** Description: Discards the changes and exits edit mode. --- # Field (REACT) ## Anatomy ```tsx ``` ## 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. **Example: input** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const Input = () => ( Label Some additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const Input = () => ( Label Some additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### Textarea This example illustrates how to use the `Field` component with a textarea element. **Example: textarea** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const Textarea = () => ( Label Some additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const Textarea = () => ( Label Some additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### Textarea Autoresize Pass the `autoresize` prop to the `Textarea` component to enable automatic resizing as the user types. **Example: textarea-autoresize** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const TextareaAutoresize = () => ( Label Some additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const TextareaAutoresize = () => ( Label Some additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### Select This example demonstrates how to integrate the `Field` component with a select dropdown. **Example: select** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const Select = () => ( Label Some additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const Select = () => ( Label Some additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### Checkbox This example demonstrates how to integrate the `Field` and `Checkbox` components. ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { Field } from '@ark-ui/react/field' import { CheckIcon, MinusIcon } from 'lucide-react' import styles from 'styles/checkbox.module.css' import field from 'styles/field.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` ### 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. **Example: root-provider** #### React ```tsx import { Field, useField } from '@ark-ui/react/field' import { useState } from 'react' import styles from 'styles/field.module.css' import button from 'styles/button.module.css' export const RootProvider = () => { const [invalid, setInvalid] = useState(false) const field = useField({ invalid }) return ( <> Label Some additional Info Error Info ) } ``` #### Solid ```tsx import { Field, useField } from '@ark-ui/solid/field' import { createMemo, createSignal } from 'solid-js' import styles from 'styles/field.module.css' import button from 'styles/button.module.css' export const RootProvider = () => { const [invalid, setInvalid] = createSignal(false) const fieldProps = createMemo(() => ({ invalid: invalid(), })) const value = useField(fieldProps) return ( <> Label Some additional Info Error Info ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### 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. **Example: custom-control** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const CustomControl = () => ( Any Control {(context) => } Uses getInputProps() for maximum flexibility This field has an error ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const CustomControl = () => ( Any Control {(field) => } Uses getInputProps() for maximum flexibility This field has an error ) ``` #### Vue ```vue ``` #### Svelte ```svelte Any Control {#snippet render(field)} {/snippet} Uses getInputProps() for maximum flexibility This field has an error ``` ## API Reference **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the field is disabled. | | `ids` | `ElementIds` | No | The ids of the field parts. | | `invalid` | `boolean` | No | Indicates whether the field is invalid. | | `readOnly` | `boolean` | No | Indicates whether the field is read-only. | | `required` | `boolean` | No | Indicates whether the field is required. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RequiredIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ ariaDescribedby: string | undefined; ids: { root: string; control: string; label: string; errorText: string; helperText: string; }; refs: { rootRef: RefObject; }; ... 11 more ...; getRequiredIndicatorProps: () => Omit<...>; }` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Select Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Textarea Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoresize` | `boolean` | No | Whether the textarea should autoresize | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the field is disabled. | | `ids` | `ElementIds` | No | The ids of the field parts. | | `invalid` | `boolean` | No | Indicates whether the field is invalid. | | `readOnly` | `boolean` | No | Indicates whether the field is read-only. | | `required` | `boolean` | No | Indicates whether the field is required. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RequiredIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `number | boolean | Node | ArrayElement | (string & {})` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `Accessor<{ ariaDescribedby: string; ids: { control: string; label: string; errorText: string; helperText: string; }; refs: { rootRef: Setter; }; ... 11 more ...; getRequiredIndicatorProps: () => { ...; }; }>` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Select Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Textarea Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'textarea'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoresize` | `boolean` | No | Whether the textarea should autoresize | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the field is disabled. | | `id` | `string` | No | The id of the field. | | `ids` | `ElementIds` | No | The ids of the field parts. | | `invalid` | `boolean` | No | Indicates whether the field is invalid. | | `readOnly` | `boolean` | No | Indicates whether the field is read-only. | | `required` | `boolean` | No | Indicates whether the field is required. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `modelValue` | `any` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RequiredIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ ariaDescribedby: string | undefined; ids: { control: string; label: string; errorText: string; helperText: string; }; refs: { rootRef: Ref; }; disabled: boolean | undefined; ... 10 more ...; getRequiredIndicatorProps: () => HTMLAttributes; }` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Select Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `modelValue` | `any` | No | | **Textarea Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoresize` | `boolean` | No | Whether the textarea should autoresize | | `modelValue` | `string | number | readonly string[]` | No | | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the field is disabled. | | `id` | `string` | No | The id of the field. | | `ids` | `ElementIds` | No | The ids of the field parts. | | `invalid` | `boolean` | No | Indicates whether the field is invalid. | | `readOnly` | `boolean` | No | Indicates whether the field is read-only. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Indicates whether the field is required. | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[() => { setRootRef: (el: Element | null) => void; ariaDescribedby: string | undefined; ids: { root: string; control: string; label: string; errorText: string; helperText: string; }; ... 11 more ...; getRequiredIndicatorProps: () => HTMLAttributes<...>; }]>` | Yes | | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RequiredIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `Snippet<[]>` | No | | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `() => { setRootRef: (el: Element | null) => void; ariaDescribedby: string | undefined; ids: { root: string; control: string; label: string; errorText: string; helperText: string; }; ... 11 more ...; getRequiredIndicatorProps: () => HTMLAttributes<...>; }` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Select Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Textarea Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'textarea'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoresize` | `boolean` | No | Whether the textarea should autoresize | | `ref` | `Element` | No | | --- # Field (VUE) ## Anatomy ```tsx ``` ## 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. **Example: input** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const Input = () => ( Label Some additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const Input = () => ( Label Some additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### Textarea This example illustrates how to use the `Field` component with a textarea element. **Example: textarea** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const Textarea = () => ( Label Some additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const Textarea = () => ( Label Some additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### Textarea Autoresize Pass the `autoresize` prop to the `Textarea` component to enable automatic resizing as the user types. **Example: textarea-autoresize** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const TextareaAutoresize = () => ( Label Some additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const TextareaAutoresize = () => ( Label Some additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### Select This example demonstrates how to integrate the `Field` component with a select dropdown. **Example: select** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const Select = () => ( Label Some additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const Select = () => ( Label Some additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### Checkbox This example demonstrates how to integrate the `Field` and `Checkbox` components. ```vue ``` ### 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. **Example: root-provider** #### React ```tsx import { Field, useField } from '@ark-ui/react/field' import { useState } from 'react' import styles from 'styles/field.module.css' import button from 'styles/button.module.css' export const RootProvider = () => { const [invalid, setInvalid] = useState(false) const field = useField({ invalid }) return ( <> Label Some additional Info Error Info ) } ``` #### Solid ```tsx import { Field, useField } from '@ark-ui/solid/field' import { createMemo, createSignal } from 'solid-js' import styles from 'styles/field.module.css' import button from 'styles/button.module.css' export const RootProvider = () => { const [invalid, setInvalid] = createSignal(false) const fieldProps = createMemo(() => ({ invalid: invalid(), })) const value = useField(fieldProps) return ( <> Label Some additional Info Error Info ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### 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. **Example: custom-control** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const CustomControl = () => ( Any Control {(context) => } Uses getInputProps() for maximum flexibility This field has an error ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const CustomControl = () => ( Any Control {(field) => } Uses getInputProps() for maximum flexibility This field has an error ) ``` #### Vue ```vue ``` #### Svelte ```svelte Any Control {#snippet render(field)} {/snippet} Uses getInputProps() for maximum flexibility This field has an error ``` ## API Reference **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the field is disabled. | | `ids` | `ElementIds` | No | The ids of the field parts. | | `invalid` | `boolean` | No | Indicates whether the field is invalid. | | `readOnly` | `boolean` | No | Indicates whether the field is read-only. | | `required` | `boolean` | No | Indicates whether the field is required. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RequiredIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ ariaDescribedby: string | undefined; ids: { root: string; control: string; label: string; errorText: string; helperText: string; }; refs: { rootRef: RefObject; }; ... 11 more ...; getRequiredIndicatorProps: () => Omit<...>; }` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Select Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Textarea Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoresize` | `boolean` | No | Whether the textarea should autoresize | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the field is disabled. | | `ids` | `ElementIds` | No | The ids of the field parts. | | `invalid` | `boolean` | No | Indicates whether the field is invalid. | | `readOnly` | `boolean` | No | Indicates whether the field is read-only. | | `required` | `boolean` | No | Indicates whether the field is required. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RequiredIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `number | boolean | Node | ArrayElement | (string & {})` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `Accessor<{ ariaDescribedby: string; ids: { control: string; label: string; errorText: string; helperText: string; }; refs: { rootRef: Setter; }; ... 11 more ...; getRequiredIndicatorProps: () => { ...; }; }>` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Select Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Textarea Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'textarea'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoresize` | `boolean` | No | Whether the textarea should autoresize | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the field is disabled. | | `id` | `string` | No | The id of the field. | | `ids` | `ElementIds` | No | The ids of the field parts. | | `invalid` | `boolean` | No | Indicates whether the field is invalid. | | `readOnly` | `boolean` | No | Indicates whether the field is read-only. | | `required` | `boolean` | No | Indicates whether the field is required. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `modelValue` | `any` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RequiredIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ ariaDescribedby: string | undefined; ids: { control: string; label: string; errorText: string; helperText: string; }; refs: { rootRef: Ref; }; disabled: boolean | undefined; ... 10 more ...; getRequiredIndicatorProps: () => HTMLAttributes; }` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Select Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `modelValue` | `any` | No | | **Textarea Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoresize` | `boolean` | No | Whether the textarea should autoresize | | `modelValue` | `string | number | readonly string[]` | No | | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the field is disabled. | | `id` | `string` | No | The id of the field. | | `ids` | `ElementIds` | No | The ids of the field parts. | | `invalid` | `boolean` | No | Indicates whether the field is invalid. | | `readOnly` | `boolean` | No | Indicates whether the field is read-only. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Indicates whether the field is required. | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[() => { setRootRef: (el: Element | null) => void; ariaDescribedby: string | undefined; ids: { root: string; control: string; label: string; errorText: string; helperText: string; }; ... 11 more ...; getRequiredIndicatorProps: () => HTMLAttributes<...>; }]>` | Yes | | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RequiredIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `Snippet<[]>` | No | | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `() => { setRootRef: (el: Element | null) => void; ariaDescribedby: string | undefined; ids: { root: string; control: string; label: string; errorText: string; helperText: string; }; ... 11 more ...; getRequiredIndicatorProps: () => HTMLAttributes<...>; }` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Select Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Textarea Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'textarea'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoresize` | `boolean` | No | Whether the textarea should autoresize | | `ref` | `Element` | No | | --- # Field (SVELTE) ## Anatomy ```tsx ``` ## 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. **Example: input** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const Input = () => ( Label Some additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const Input = () => ( Label Some additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### Textarea This example illustrates how to use the `Field` component with a textarea element. **Example: textarea** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const Textarea = () => ( Label Some additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const Textarea = () => ( Label Some additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### Textarea Autoresize Pass the `autoresize` prop to the `Textarea` component to enable automatic resizing as the user types. **Example: textarea-autoresize** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const TextareaAutoresize = () => ( Label Some additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const TextareaAutoresize = () => ( Label Some additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### Select This example demonstrates how to integrate the `Field` component with a select dropdown. **Example: select** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const Select = () => ( Label Some additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const Select = () => ( Label Some additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### Checkbox This example demonstrates how to integrate the `Field` and `Checkbox` components. ```svelte Label Additional Info Error Info ``` ### 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. **Example: root-provider** #### React ```tsx import { Field, useField } from '@ark-ui/react/field' import { useState } from 'react' import styles from 'styles/field.module.css' import button from 'styles/button.module.css' export const RootProvider = () => { const [invalid, setInvalid] = useState(false) const field = useField({ invalid }) return ( <> Label Some additional Info Error Info ) } ``` #### Solid ```tsx import { Field, useField } from '@ark-ui/solid/field' import { createMemo, createSignal } from 'solid-js' import styles from 'styles/field.module.css' import button from 'styles/button.module.css' export const RootProvider = () => { const [invalid, setInvalid] = createSignal(false) const fieldProps = createMemo(() => ({ invalid: invalid(), })) const value = useField(fieldProps) return ( <> Label Some additional Info Error Info ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### 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. **Example: custom-control** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const CustomControl = () => ( Any Control {(context) => } Uses getInputProps() for maximum flexibility This field has an error ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const CustomControl = () => ( Any Control {(field) => } Uses getInputProps() for maximum flexibility This field has an error ) ``` #### Vue ```vue ``` #### Svelte ```svelte Any Control {#snippet render(field)} {/snippet} Uses getInputProps() for maximum flexibility This field has an error ``` ## API Reference **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the field is disabled. | | `ids` | `ElementIds` | No | The ids of the field parts. | | `invalid` | `boolean` | No | Indicates whether the field is invalid. | | `readOnly` | `boolean` | No | Indicates whether the field is read-only. | | `required` | `boolean` | No | Indicates whether the field is required. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RequiredIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ ariaDescribedby: string | undefined; ids: { root: string; control: string; label: string; errorText: string; helperText: string; }; refs: { rootRef: RefObject; }; ... 11 more ...; getRequiredIndicatorProps: () => Omit<...>; }` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Select Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Textarea Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoresize` | `boolean` | No | Whether the textarea should autoresize | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the field is disabled. | | `ids` | `ElementIds` | No | The ids of the field parts. | | `invalid` | `boolean` | No | Indicates whether the field is invalid. | | `readOnly` | `boolean` | No | Indicates whether the field is read-only. | | `required` | `boolean` | No | Indicates whether the field is required. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RequiredIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `number | boolean | Node | ArrayElement | (string & {})` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `Accessor<{ ariaDescribedby: string; ids: { control: string; label: string; errorText: string; helperText: string; }; refs: { rootRef: Setter; }; ... 11 more ...; getRequiredIndicatorProps: () => { ...; }; }>` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Select Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Textarea Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'textarea'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoresize` | `boolean` | No | Whether the textarea should autoresize | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the field is disabled. | | `id` | `string` | No | The id of the field. | | `ids` | `ElementIds` | No | The ids of the field parts. | | `invalid` | `boolean` | No | Indicates whether the field is invalid. | | `readOnly` | `boolean` | No | Indicates whether the field is read-only. | | `required` | `boolean` | No | Indicates whether the field is required. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `modelValue` | `any` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RequiredIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ ariaDescribedby: string | undefined; ids: { control: string; label: string; errorText: string; helperText: string; }; refs: { rootRef: Ref; }; disabled: boolean | undefined; ... 10 more ...; getRequiredIndicatorProps: () => HTMLAttributes; }` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Select Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `modelValue` | `any` | No | | **Textarea Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoresize` | `boolean` | No | Whether the textarea should autoresize | | `modelValue` | `string | number | readonly string[]` | No | | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the field is disabled. | | `id` | `string` | No | The id of the field. | | `ids` | `ElementIds` | No | The ids of the field parts. | | `invalid` | `boolean` | No | Indicates whether the field is invalid. | | `readOnly` | `boolean` | No | Indicates whether the field is read-only. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Indicates whether the field is required. | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[() => { setRootRef: (el: Element | null) => void; ariaDescribedby: string | undefined; ids: { root: string; control: string; label: string; errorText: string; helperText: string; }; ... 11 more ...; getRequiredIndicatorProps: () => HTMLAttributes<...>; }]>` | Yes | | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RequiredIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `Snippet<[]>` | No | | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `() => { setRootRef: (el: Element | null) => void; ariaDescribedby: string | undefined; ids: { root: string; control: string; label: string; errorText: string; helperText: string; }; ... 11 more ...; getRequiredIndicatorProps: () => HTMLAttributes<...>; }` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Select Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Textarea Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'textarea'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoresize` | `boolean` | No | Whether the textarea should autoresize | | `ref` | `Element` | No | | --- # Field (SOLID) ## Anatomy ```tsx ``` ## 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. **Example: input** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const Input = () => ( Label Some additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const Input = () => ( Label Some additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### Textarea This example illustrates how to use the `Field` component with a textarea element. **Example: textarea** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const Textarea = () => ( Label Some additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const Textarea = () => ( Label Some additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### Textarea Autoresize Pass the `autoresize` prop to the `Textarea` component to enable automatic resizing as the user types. **Example: textarea-autoresize** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const TextareaAutoresize = () => ( Label Some additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const TextareaAutoresize = () => ( Label Some additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### Select This example demonstrates how to integrate the `Field` component with a select dropdown. **Example: select** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const Select = () => ( Label Some additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const Select = () => ( Label Some additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### Checkbox This example demonstrates how to integrate the `Field` and `Checkbox` components. ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { Field } from '@ark-ui/solid/field' import { CheckIcon, MinusIcon } from 'lucide-solid' import styles from 'styles/checkbox.module.css' import field from 'styles/field.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` ### 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. **Example: root-provider** #### React ```tsx import { Field, useField } from '@ark-ui/react/field' import { useState } from 'react' import styles from 'styles/field.module.css' import button from 'styles/button.module.css' export const RootProvider = () => { const [invalid, setInvalid] = useState(false) const field = useField({ invalid }) return ( <> Label Some additional Info Error Info ) } ``` #### Solid ```tsx import { Field, useField } from '@ark-ui/solid/field' import { createMemo, createSignal } from 'solid-js' import styles from 'styles/field.module.css' import button from 'styles/button.module.css' export const RootProvider = () => { const [invalid, setInvalid] = createSignal(false) const fieldProps = createMemo(() => ({ invalid: invalid(), })) const value = useField(fieldProps) return ( <> Label Some additional Info Error Info ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label Some additional Info Error Info ``` ### 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. **Example: custom-control** #### React ```tsx import { Field } from '@ark-ui/react/field' import styles from 'styles/field.module.css' export const CustomControl = () => ( Any Control {(context) => } Uses getInputProps() for maximum flexibility This field has an error ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import styles from 'styles/field.module.css' export const CustomControl = () => ( Any Control {(field) => } Uses getInputProps() for maximum flexibility This field has an error ) ``` #### Vue ```vue ``` #### Svelte ```svelte Any Control {#snippet render(field)} {/snippet} Uses getInputProps() for maximum flexibility This field has an error ``` ## API Reference **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the field is disabled. | | `ids` | `ElementIds` | No | The ids of the field parts. | | `invalid` | `boolean` | No | Indicates whether the field is invalid. | | `readOnly` | `boolean` | No | Indicates whether the field is read-only. | | `required` | `boolean` | No | Indicates whether the field is required. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RequiredIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ ariaDescribedby: string | undefined; ids: { root: string; control: string; label: string; errorText: string; helperText: string; }; refs: { rootRef: RefObject; }; ... 11 more ...; getRequiredIndicatorProps: () => Omit<...>; }` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Select Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Textarea Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoresize` | `boolean` | No | Whether the textarea should autoresize | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the field is disabled. | | `ids` | `ElementIds` | No | The ids of the field parts. | | `invalid` | `boolean` | No | Indicates whether the field is invalid. | | `readOnly` | `boolean` | No | Indicates whether the field is read-only. | | `required` | `boolean` | No | Indicates whether the field is required. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RequiredIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `number | boolean | Node | ArrayElement | (string & {})` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `Accessor<{ ariaDescribedby: string; ids: { control: string; label: string; errorText: string; helperText: string; }; refs: { rootRef: Setter; }; ... 11 more ...; getRequiredIndicatorProps: () => { ...; }; }>` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Select Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Textarea Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'textarea'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoresize` | `boolean` | No | Whether the textarea should autoresize | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the field is disabled. | | `id` | `string` | No | The id of the field. | | `ids` | `ElementIds` | No | The ids of the field parts. | | `invalid` | `boolean` | No | Indicates whether the field is invalid. | | `readOnly` | `boolean` | No | Indicates whether the field is read-only. | | `required` | `boolean` | No | Indicates whether the field is required. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `modelValue` | `any` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RequiredIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ ariaDescribedby: string | undefined; ids: { control: string; label: string; errorText: string; helperText: string; }; refs: { rootRef: Ref; }; disabled: boolean | undefined; ... 10 more ...; getRequiredIndicatorProps: () => HTMLAttributes; }` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Select Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `modelValue` | `any` | No | | **Textarea Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoresize` | `boolean` | No | Whether the textarea should autoresize | | `modelValue` | `string | number | readonly string[]` | No | | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the field is disabled. | | `id` | `string` | No | The id of the field. | | `ids` | `ElementIds` | No | The ids of the field parts. | | `invalid` | `boolean` | No | Indicates whether the field is invalid. | | `readOnly` | `boolean` | No | Indicates whether the field is read-only. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Indicates whether the field is required. | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[() => { setRootRef: (el: Element | null) => void; ariaDescribedby: string | undefined; ids: { root: string; control: string; label: string; errorText: string; helperText: string; }; ... 11 more ...; getRequiredIndicatorProps: () => HTMLAttributes<...>; }]>` | Yes | | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RequiredIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `Snippet<[]>` | No | | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `() => { setRootRef: (el: Element | null) => void; ariaDescribedby: string | undefined; ids: { root: string; control: string; label: string; errorText: string; helperText: string; }; ... 11 more ...; getRequiredIndicatorProps: () => HTMLAttributes<...>; }` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Select Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Textarea Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'textarea'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoresize` | `boolean` | No | Whether the textarea should autoresize | | `ref` | `Element` | No | | --- # Fieldset (REACT) ## Anatomy ```tsx ``` ## 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. ### Basic **Example: basic** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Fieldset } from '@ark-ui/react/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const Basic = () => { return ( Contact Details Name Email ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Fieldset } from '@ark-ui/solid/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const Basic = () => { return ( Contact Details Name Email ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Contact Details Name Email ``` ### Field This example demonstrates how to use the `Field` component with a standard input field within a `Fieldset`. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Fieldset } from '@ark-ui/react/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const WithField = () => { return ( Personal Information First Name As it appears on your ID Last Name ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Fieldset } from '@ark-ui/solid/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const WithField = () => { return ( Personal Information First Name As it appears on your ID Last Name ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Personal Information First Name As it appears on your ID Last Name ``` ### Checkbox This example shows how to use the `Fieldset` component with other Ark UI form elements like `Checkbox`. **Example: with-checkbox** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { Fieldset } from '@ark-ui/react/fieldset' import { CheckIcon } from 'lucide-react' import checkbox from 'styles/checkbox.module.css' import styles from 'styles/fieldset.module.css' export const WithCheckbox = () => { return ( Email Preferences Product updates Marketing emails ) } ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { Fieldset } from '@ark-ui/solid/fieldset' import { CheckIcon } from 'lucide-solid' import checkbox from 'styles/checkbox.module.css' import styles from 'styles/fieldset.module.css' export const WithCheckbox = () => { return ( Email Preferences Product updates Marketing emails ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Email Preferences Product updates Marketing emails ``` ### 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. **Example: root-provider** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Fieldset, useFieldset } from '@ark-ui/react/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const RootProvider = () => { const fieldset = useFieldset() return ( Contact Details Name Email ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Fieldset, useFieldset } from '@ark-ui/solid/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const RootProvider = () => { const fieldset = useFieldset() return ( Contact Details Name Email ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Contact Details Name Email ``` ### Input with Select This example shows how to use the `Fieldset` component with `Field.Input` and `Select` to create a interactive phone input component. **Example: phone-input** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Fieldset } from '@ark-ui/react/fieldset' import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import { useRef } from 'react' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' import select from 'styles/select.module.css' export const PhoneInput = () => { const extensions = createListCollection({ items: [ { label: '+1', value: '+1' }, { label: '+44', value: '+44' }, { label: '+49', value: '+49' }, { label: '+41', value: '+41' }, ], }) const inputRef = useRef(null) const focusInput = () => { setTimeout(() => { inputRef.current?.focus() }) } return ( Mobile Number
                    {extensions.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Fieldset } from '@ark-ui/solid/fieldset' import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' import select from 'styles/select.module.css' export const PhoneInput = () => { const extensions = createListCollection({ items: [ { label: '+1', value: '+1' }, { label: '+44', value: '+44' }, { label: '+49', value: '+49' }, { label: '+41', value: '+41' }, ], }) const [inputRef, setInputRef] = createSignal(null) const focusInput = () => { setTimeout(() => { inputRef()?.focus() }) } return ( Mobile Number
                    {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Mobile Number
                    {#each extensions.items as item} {item.label} {/each}
                    ``` ## API Reference **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `invalid` | `boolean` | No | Indicates whether the fieldset is invalid. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Legend Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ refs: { rootRef: RefObject; }; disabled: boolean; invalid: boolean; getRootProps: () => Omit, HTMLFieldSetElement>, "ref">; getLegendProps: () => Omit<...>; getHelperTextProps: () => Omit<...>; getErrorTextProps: () => Omit<....` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'fieldset'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `invalid` | `boolean` | No | Indicates whether the fieldset is invalid. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Legend Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'legend'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `Accessor<{ refs: { rootRef: HTMLFieldSetElement | undefined; }; disabled: boolean; invalid: boolean; getRootProps: () => { disabled: boolean; 'data-disabled': boolean | "true" | "false"; ... 4 more ...; "data-part": string; }; getLegendProps: () => { ...; }; getHelperTextProps: () => { ...; }; getErrorTextProps: () ...` | Yes | | | `asChild` | `(props: ParentProps<'fieldset'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean | 'true' | 'false'` | No | Indicates whether the fieldset is disabled. | | `id` | `string` | No | The id of the fieldset. | | `invalid` | `boolean` | No | Indicates whether the fieldset is invalid. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Legend Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ refs: { rootRef: Ref; }; disabled: boolean | "true" | "false" | undefined; invalid: boolean | undefined; getRootProps: () => FieldsetHTMLAttributes; getLegendProps: () => { ...; }; getHelperTextProps: () => { ...; }; getErrorTextProps: () => HTMLAttributes; }` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'fieldset'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the fieldset is disabled. | | `id` | `string` | No | The id of the fieldset. | | `invalid` | `boolean` | No | Indicates whether the fieldset is invalid. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[() => { setRootRef: (el: Element | null) => void; disabled: boolean; invalid: boolean; getRootProps: () => HTMLFieldsetAttributes; getLegendProps: () => HTMLAttributes<...>; getHelperTextProps: () => HTMLAttributes<...>; getErrorTextProps: () => HTMLAttributes<...>; }]>` | Yes | | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Legend Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'legend'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `() => { setRootRef: (el: Element | null) => void; disabled: boolean; invalid: boolean; getRootProps: () => HTMLFieldsetAttributes; getLegendProps: () => HTMLAttributes<...>; getHelperTextProps: () => HTMLAttributes<...>; getErrorTextProps: () => HTMLAttributes<...>; }` | Yes | | | `asChild` | `Snippet<[PropsFn<'fieldset'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | --- # Fieldset (VUE) ## Anatomy ```tsx ``` ## 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. ### Basic **Example: basic** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Fieldset } from '@ark-ui/react/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const Basic = () => { return ( Contact Details Name Email ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Fieldset } from '@ark-ui/solid/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const Basic = () => { return ( Contact Details Name Email ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Contact Details Name Email ``` ### Field This example demonstrates how to use the `Field` component with a standard input field within a `Fieldset`. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Fieldset } from '@ark-ui/react/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const WithField = () => { return ( Personal Information First Name As it appears on your ID Last Name ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Fieldset } from '@ark-ui/solid/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const WithField = () => { return ( Personal Information First Name As it appears on your ID Last Name ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Personal Information First Name As it appears on your ID Last Name ``` ### Checkbox This example shows how to use the `Fieldset` component with other Ark UI form elements like `Checkbox`. **Example: with-checkbox** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { Fieldset } from '@ark-ui/react/fieldset' import { CheckIcon } from 'lucide-react' import checkbox from 'styles/checkbox.module.css' import styles from 'styles/fieldset.module.css' export const WithCheckbox = () => { return ( Email Preferences Product updates Marketing emails ) } ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { Fieldset } from '@ark-ui/solid/fieldset' import { CheckIcon } from 'lucide-solid' import checkbox from 'styles/checkbox.module.css' import styles from 'styles/fieldset.module.css' export const WithCheckbox = () => { return ( Email Preferences Product updates Marketing emails ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Email Preferences Product updates Marketing emails ``` ### 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. **Example: root-provider** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Fieldset, useFieldset } from '@ark-ui/react/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const RootProvider = () => { const fieldset = useFieldset() return ( Contact Details Name Email ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Fieldset, useFieldset } from '@ark-ui/solid/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const RootProvider = () => { const fieldset = useFieldset() return ( Contact Details Name Email ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Contact Details Name Email ``` ### Input with Select This example shows how to use the `Fieldset` component with `Field.Input` and `Select` to create a interactive phone input component. **Example: phone-input** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Fieldset } from '@ark-ui/react/fieldset' import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import { useRef } from 'react' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' import select from 'styles/select.module.css' export const PhoneInput = () => { const extensions = createListCollection({ items: [ { label: '+1', value: '+1' }, { label: '+44', value: '+44' }, { label: '+49', value: '+49' }, { label: '+41', value: '+41' }, ], }) const inputRef = useRef(null) const focusInput = () => { setTimeout(() => { inputRef.current?.focus() }) } return ( Mobile Number
                    {extensions.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Fieldset } from '@ark-ui/solid/fieldset' import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' import select from 'styles/select.module.css' export const PhoneInput = () => { const extensions = createListCollection({ items: [ { label: '+1', value: '+1' }, { label: '+44', value: '+44' }, { label: '+49', value: '+49' }, { label: '+41', value: '+41' }, ], }) const [inputRef, setInputRef] = createSignal(null) const focusInput = () => { setTimeout(() => { inputRef()?.focus() }) } return ( Mobile Number
                    {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Mobile Number
                    {#each extensions.items as item} {item.label} {/each}
                    ``` ## API Reference **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `invalid` | `boolean` | No | Indicates whether the fieldset is invalid. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Legend Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ refs: { rootRef: RefObject; }; disabled: boolean; invalid: boolean; getRootProps: () => Omit, HTMLFieldSetElement>, "ref">; getLegendProps: () => Omit<...>; getHelperTextProps: () => Omit<...>; getErrorTextProps: () => Omit<....` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'fieldset'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `invalid` | `boolean` | No | Indicates whether the fieldset is invalid. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Legend Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'legend'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `Accessor<{ refs: { rootRef: HTMLFieldSetElement | undefined; }; disabled: boolean; invalid: boolean; getRootProps: () => { disabled: boolean; 'data-disabled': boolean | "true" | "false"; ... 4 more ...; "data-part": string; }; getLegendProps: () => { ...; }; getHelperTextProps: () => { ...; }; getErrorTextProps: () ...` | Yes | | | `asChild` | `(props: ParentProps<'fieldset'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean | 'true' | 'false'` | No | Indicates whether the fieldset is disabled. | | `id` | `string` | No | The id of the fieldset. | | `invalid` | `boolean` | No | Indicates whether the fieldset is invalid. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Legend Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ refs: { rootRef: Ref; }; disabled: boolean | "true" | "false" | undefined; invalid: boolean | undefined; getRootProps: () => FieldsetHTMLAttributes; getLegendProps: () => { ...; }; getHelperTextProps: () => { ...; }; getErrorTextProps: () => HTMLAttributes; }` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'fieldset'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the fieldset is disabled. | | `id` | `string` | No | The id of the fieldset. | | `invalid` | `boolean` | No | Indicates whether the fieldset is invalid. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[() => { setRootRef: (el: Element | null) => void; disabled: boolean; invalid: boolean; getRootProps: () => HTMLFieldsetAttributes; getLegendProps: () => HTMLAttributes<...>; getHelperTextProps: () => HTMLAttributes<...>; getErrorTextProps: () => HTMLAttributes<...>; }]>` | Yes | | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Legend Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'legend'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `() => { setRootRef: (el: Element | null) => void; disabled: boolean; invalid: boolean; getRootProps: () => HTMLFieldsetAttributes; getLegendProps: () => HTMLAttributes<...>; getHelperTextProps: () => HTMLAttributes<...>; getErrorTextProps: () => HTMLAttributes<...>; }` | Yes | | | `asChild` | `Snippet<[PropsFn<'fieldset'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | --- # Fieldset (SVELTE) ## Anatomy ```tsx ``` ## 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. ### Basic **Example: basic** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Fieldset } from '@ark-ui/react/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const Basic = () => { return ( Contact Details Name Email ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Fieldset } from '@ark-ui/solid/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const Basic = () => { return ( Contact Details Name Email ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Contact Details Name Email ``` ### Field This example demonstrates how to use the `Field` component with a standard input field within a `Fieldset`. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Fieldset } from '@ark-ui/react/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const WithField = () => { return ( Personal Information First Name As it appears on your ID Last Name ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Fieldset } from '@ark-ui/solid/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const WithField = () => { return ( Personal Information First Name As it appears on your ID Last Name ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Personal Information First Name As it appears on your ID Last Name ``` ### Checkbox This example shows how to use the `Fieldset` component with other Ark UI form elements like `Checkbox`. **Example: with-checkbox** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { Fieldset } from '@ark-ui/react/fieldset' import { CheckIcon } from 'lucide-react' import checkbox from 'styles/checkbox.module.css' import styles from 'styles/fieldset.module.css' export const WithCheckbox = () => { return ( Email Preferences Product updates Marketing emails ) } ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { Fieldset } from '@ark-ui/solid/fieldset' import { CheckIcon } from 'lucide-solid' import checkbox from 'styles/checkbox.module.css' import styles from 'styles/fieldset.module.css' export const WithCheckbox = () => { return ( Email Preferences Product updates Marketing emails ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Email Preferences Product updates Marketing emails ``` ### 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. **Example: root-provider** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Fieldset, useFieldset } from '@ark-ui/react/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const RootProvider = () => { const fieldset = useFieldset() return ( Contact Details Name Email ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Fieldset, useFieldset } from '@ark-ui/solid/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const RootProvider = () => { const fieldset = useFieldset() return ( Contact Details Name Email ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Contact Details Name Email ``` ### Input with Select This example shows how to use the `Fieldset` component with `Field.Input` and `Select` to create a interactive phone input component. **Example: phone-input** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Fieldset } from '@ark-ui/react/fieldset' import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import { useRef } from 'react' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' import select from 'styles/select.module.css' export const PhoneInput = () => { const extensions = createListCollection({ items: [ { label: '+1', value: '+1' }, { label: '+44', value: '+44' }, { label: '+49', value: '+49' }, { label: '+41', value: '+41' }, ], }) const inputRef = useRef(null) const focusInput = () => { setTimeout(() => { inputRef.current?.focus() }) } return ( Mobile Number
                    {extensions.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Fieldset } from '@ark-ui/solid/fieldset' import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' import select from 'styles/select.module.css' export const PhoneInput = () => { const extensions = createListCollection({ items: [ { label: '+1', value: '+1' }, { label: '+44', value: '+44' }, { label: '+49', value: '+49' }, { label: '+41', value: '+41' }, ], }) const [inputRef, setInputRef] = createSignal(null) const focusInput = () => { setTimeout(() => { inputRef()?.focus() }) } return ( Mobile Number
                    {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Mobile Number
                    {#each extensions.items as item} {item.label} {/each}
                    ``` ## API Reference **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `invalid` | `boolean` | No | Indicates whether the fieldset is invalid. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Legend Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ refs: { rootRef: RefObject; }; disabled: boolean; invalid: boolean; getRootProps: () => Omit, HTMLFieldSetElement>, "ref">; getLegendProps: () => Omit<...>; getHelperTextProps: () => Omit<...>; getErrorTextProps: () => Omit<....` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'fieldset'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `invalid` | `boolean` | No | Indicates whether the fieldset is invalid. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Legend Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'legend'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `Accessor<{ refs: { rootRef: HTMLFieldSetElement | undefined; }; disabled: boolean; invalid: boolean; getRootProps: () => { disabled: boolean; 'data-disabled': boolean | "true" | "false"; ... 4 more ...; "data-part": string; }; getLegendProps: () => { ...; }; getHelperTextProps: () => { ...; }; getErrorTextProps: () ...` | Yes | | | `asChild` | `(props: ParentProps<'fieldset'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean | 'true' | 'false'` | No | Indicates whether the fieldset is disabled. | | `id` | `string` | No | The id of the fieldset. | | `invalid` | `boolean` | No | Indicates whether the fieldset is invalid. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Legend Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ refs: { rootRef: Ref; }; disabled: boolean | "true" | "false" | undefined; invalid: boolean | undefined; getRootProps: () => FieldsetHTMLAttributes; getLegendProps: () => { ...; }; getHelperTextProps: () => { ...; }; getErrorTextProps: () => HTMLAttributes; }` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'fieldset'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the fieldset is disabled. | | `id` | `string` | No | The id of the fieldset. | | `invalid` | `boolean` | No | Indicates whether the fieldset is invalid. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[() => { setRootRef: (el: Element | null) => void; disabled: boolean; invalid: boolean; getRootProps: () => HTMLFieldsetAttributes; getLegendProps: () => HTMLAttributes<...>; getHelperTextProps: () => HTMLAttributes<...>; getErrorTextProps: () => HTMLAttributes<...>; }]>` | Yes | | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Legend Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'legend'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `() => { setRootRef: (el: Element | null) => void; disabled: boolean; invalid: boolean; getRootProps: () => HTMLFieldsetAttributes; getLegendProps: () => HTMLAttributes<...>; getHelperTextProps: () => HTMLAttributes<...>; getErrorTextProps: () => HTMLAttributes<...>; }` | Yes | | | `asChild` | `Snippet<[PropsFn<'fieldset'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | --- # Fieldset (SOLID) ## Anatomy ```tsx ``` ## 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. ### Basic **Example: basic** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Fieldset } from '@ark-ui/react/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const Basic = () => { return ( Contact Details Name Email ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Fieldset } from '@ark-ui/solid/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const Basic = () => { return ( Contact Details Name Email ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Contact Details Name Email ``` ### Field This example demonstrates how to use the `Field` component with a standard input field within a `Fieldset`. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Fieldset } from '@ark-ui/react/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const WithField = () => { return ( Personal Information First Name As it appears on your ID Last Name ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Fieldset } from '@ark-ui/solid/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const WithField = () => { return ( Personal Information First Name As it appears on your ID Last Name ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Personal Information First Name As it appears on your ID Last Name ``` ### Checkbox This example shows how to use the `Fieldset` component with other Ark UI form elements like `Checkbox`. **Example: with-checkbox** #### React ```tsx import { Checkbox } from '@ark-ui/react/checkbox' import { Fieldset } from '@ark-ui/react/fieldset' import { CheckIcon } from 'lucide-react' import checkbox from 'styles/checkbox.module.css' import styles from 'styles/fieldset.module.css' export const WithCheckbox = () => { return ( Email Preferences Product updates Marketing emails ) } ``` #### Solid ```tsx import { Checkbox } from '@ark-ui/solid/checkbox' import { Fieldset } from '@ark-ui/solid/fieldset' import { CheckIcon } from 'lucide-solid' import checkbox from 'styles/checkbox.module.css' import styles from 'styles/fieldset.module.css' export const WithCheckbox = () => { return ( Email Preferences Product updates Marketing emails ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Email Preferences Product updates Marketing emails ``` ### 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. **Example: root-provider** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Fieldset, useFieldset } from '@ark-ui/react/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const RootProvider = () => { const fieldset = useFieldset() return ( Contact Details Name Email ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Fieldset, useFieldset } from '@ark-ui/solid/fieldset' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' export const RootProvider = () => { const fieldset = useFieldset() return ( Contact Details Name Email ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Contact Details Name Email ``` ### Input with Select This example shows how to use the `Fieldset` component with `Field.Input` and `Select` to create a interactive phone input component. **Example: phone-input** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Fieldset } from '@ark-ui/react/fieldset' import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import { useRef } from 'react' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' import select from 'styles/select.module.css' export const PhoneInput = () => { const extensions = createListCollection({ items: [ { label: '+1', value: '+1' }, { label: '+44', value: '+44' }, { label: '+49', value: '+49' }, { label: '+41', value: '+41' }, ], }) const inputRef = useRef(null) const focusInput = () => { setTimeout(() => { inputRef.current?.focus() }) } return ( Mobile Number
                    {extensions.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Fieldset } from '@ark-ui/solid/fieldset' import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import field from 'styles/field.module.css' import styles from 'styles/fieldset.module.css' import select from 'styles/select.module.css' export const PhoneInput = () => { const extensions = createListCollection({ items: [ { label: '+1', value: '+1' }, { label: '+44', value: '+44' }, { label: '+49', value: '+49' }, { label: '+41', value: '+41' }, ], }) const [inputRef, setInputRef] = createSignal(null) const focusInput = () => { setTimeout(() => { inputRef()?.focus() }) } return ( Mobile Number
                    {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Mobile Number
                    {#each extensions.items as item} {item.label} {/each}
                    ``` ## API Reference **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `invalid` | `boolean` | No | Indicates whether the fieldset is invalid. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Legend Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ refs: { rootRef: RefObject; }; disabled: boolean; invalid: boolean; getRootProps: () => Omit, HTMLFieldSetElement>, "ref">; getLegendProps: () => Omit<...>; getHelperTextProps: () => Omit<...>; getErrorTextProps: () => Omit<....` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'fieldset'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `invalid` | `boolean` | No | Indicates whether the fieldset is invalid. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Legend Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'legend'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `Accessor<{ refs: { rootRef: HTMLFieldSetElement | undefined; }; disabled: boolean; invalid: boolean; getRootProps: () => { disabled: boolean; 'data-disabled': boolean | "true" | "false"; ... 4 more ...; "data-part": string; }; getLegendProps: () => { ...; }; getHelperTextProps: () => { ...; }; getErrorTextProps: () ...` | Yes | | | `asChild` | `(props: ParentProps<'fieldset'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean | 'true' | 'false'` | No | Indicates whether the fieldset is disabled. | | `id` | `string` | No | The id of the fieldset. | | `invalid` | `boolean` | No | Indicates whether the fieldset is invalid. | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Legend Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `{ refs: { rootRef: Ref; }; disabled: boolean | "true" | "false" | undefined; invalid: boolean | undefined; getRootProps: () => FieldsetHTMLAttributes; getLegendProps: () => { ...; }; getHelperTextProps: () => { ...; }; getErrorTextProps: () => HTMLAttributes; }` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'fieldset'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Indicates whether the fieldset is disabled. | | `id` | `string` | No | The id of the fieldset. | | `invalid` | `boolean` | No | Indicates whether the fieldset is invalid. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[() => { setRootRef: (el: Element | null) => void; disabled: boolean; invalid: boolean; getRootProps: () => HTMLFieldsetAttributes; getLegendProps: () => HTMLAttributes<...>; getHelperTextProps: () => HTMLAttributes<...>; getErrorTextProps: () => HTMLAttributes<...>; }]>` | Yes | | **ErrorText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HelperText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Legend Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'legend'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `() => { setRootRef: (el: Element | null) => void; disabled: boolean; invalid: boolean; getRootProps: () => HTMLFieldsetAttributes; getLegendProps: () => HTMLAttributes<...>; getHelperTextProps: () => HTMLAttributes<...>; getErrorTextProps: () => HTMLAttributes<...>; }` | Yes | | | `asChild` | `Snippet<[PropsFn<'fieldset'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | --- # File Upload (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { PaperclipIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const Basic = () => ( File Upload Choose file(s) {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) } ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const Basic = () => ( File Upload Choose file(s) {(context) => ( {(file) => ( X )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload Choose file(s) {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} X {/each} {/snippet} ``` ### Initial Files Use the `defaultAcceptedFiles` prop to set the initial files in the file upload component. **Example: initial-files** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { FileIcon, PaperclipIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const InitialFiles = () => ( File Upload Choose file(s) {({ acceptedFiles }) => acceptedFiles.map((file) => (
                    )) }
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const InitialFiles = () => ( File Upload Choose file(s) {(context) => ( {(file) => (
                    📄
                    )}
                    )}
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload Choose file(s) {#snippet render(context)} {#each context().acceptedFiles as file (file.name)}
                    📄
                    {/each} {/snippet}
                    ``` ### Clear Trigger Use the `ClearTrigger` to remove all uploaded files at once. **Example: clear-trigger** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { PaperclipIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const ClearTrigger = () => ( File Upload
                    Choose file(s) Clear Files
                    {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) }
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const ClearTrigger = () => ( File Upload Choose file(s) Clear Files {(context) => ( {(file) => ( )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload Drag your file(s) here Choose file(s) {#snippet render(context)} {#if context().acceptedFiles.length > 0} {/if} {/snippet} {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} X {/each} {/snippet} ``` ### Dropzone Use the `Dropzone` to enable drag-and-drop. It exposes a `data-dragging` attribute for styling. **Example: dropzone** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { FileIcon, UploadIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const Dropzone = () => ( File Upload
                    Drag and drop files here or click to browse
                    {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) }
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const Dropzone = () => ( File Upload Drag and drop files here {(context) => ( {(file) => ( File X )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload Drag and drop files here {#snippet render(fileUpload)} {#each fileUpload().acceptedFiles as file (file.name)} X {/each} {/snippet} ``` ### Directory Upload Use the `directory` prop to upload entire folders. Access file paths through `file.webkitRelativePath`. **Example: directory-upload** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { FileIcon, FolderIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const DirectoryUpload = () => ( Upload Folder Select Folder {({ acceptedFiles }) => acceptedFiles.map((file) => (
                    {file.webkitRelativePath || file.name}
                    )) }
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const DirectoryUpload = () => ( Upload Folder {(fileUpload) => ( {(file) => ( {file.webkitRelativePath ?? file.name} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Upload Folder {#snippet render(fileUpload)} {#each fileUpload().acceptedFiles as file (file.name)} {file.webkitRelativePath ?? file.name} {/each} {/snippet} ``` > 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`). **Example: accepted-file-types** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { AlertCircleIcon, ImageIcon, UploadIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const AcceptedFileTypes = () => ( Upload Images (PNG and JPEG only)
                    Drop your images here Only PNG and JPEG files
                    {({ acceptedFiles, rejectedFiles }) => ( <> {acceptedFiles.length > 0 && ( {acceptedFiles.map((file) => ( ))} )} {rejectedFiles.length > 0 && ( {rejectedFiles.map((fileRejection) => (
                    {fileRejection.errors.map((error) => (
                    {error}
                    ))}
                    ))}
                    )} )}
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const AcceptedFileTypes = () => ( File Upload (PNG and JPEG only) Drop your files here Select Files {(context) => ( {(file) => ( Remove )} )} {(context) => ( {(fileRejection) => (
                    {(error) =>
                    {error}
                    }
                    )}
                    )}
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload (PNG and JPEG only) Drop your files here Select Files {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} Remove {/each} {/snippet} {#snippet render(context)} {#each context().rejectedFiles as fileRejection (fileRejection.file.name)}
                    {#each fileRejection.errors as error}
                    {error}
                    {/each}
                    {/each} {/snippet}
                    ``` ### 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`. **Example: error-handling** #### React ```tsx import { FileUpload, type FileUploadFileError } from '@ark-ui/react/file-upload' import { AlertCircleIcon, CheckCircleIcon, FileIcon, UploadIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' const errorMessages: Record = { TOO_MANY_FILES: 'Too many files selected (max 3 allowed)', FILE_INVALID_TYPE: 'Invalid file type (only images and PDFs allowed)', FILE_TOO_LARGE: 'File too large (max 1MB)', FILE_TOO_SMALL: 'File too small (min 1KB)', FILE_INVALID: 'Invalid file', FILE_EXISTS: 'File already exists', } export const ErrorHandling = () => ( Upload Documents
                    Drop files here Images and PDFs, max 1MB each
                    {({ acceptedFiles, rejectedFiles }) => ( <> {acceptedFiles.length > 0 && (
                    Accepted Files
                    {acceptedFiles.map((file) => ( ))}
                    )} {rejectedFiles.length > 0 && (
                    Rejected Files
                    {rejectedFiles.map((fileRejection) => (
                    {fileRejection.errors.map((error, index) => (
                    {errorMessages[error as FileUploadFileError] || error}
                    ))}
                    ))}
                    )} )}
                    ) ``` #### Solid ```tsx import { FileUpload, type FileUploadFileError } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' const errorMessages: Record = { TOO_MANY_FILES: '📊 Too many files selected (max 3 allowed)', FILE_INVALID_TYPE: '🚫 Invalid file type (only images and PDFs allowed)', FILE_TOO_LARGE: '📏 File too large (max 1MB)', FILE_TOO_SMALL: '📐 File too small (min 1KB)', FILE_INVALID: '⚠️ Invalid file', FILE_EXISTS: '🔄 File already exists', } export const ErrorHandling = () => ( File Upload with Validation Select Files {/* Accepted Files Section */}

                    ✅ Accepted Files

                    {(fileUpload) => fileUpload().acceptedFiles.length === 0 ? (
                    No files uploaded yet
                    ) : ( {(file) => (
                    PDF
                    Remove
                    )}
                    ) }
                    {/* Rejected Files Section */}

                    ❌ Rejected Files

                    {(fileUpload) => fileUpload().rejectedFiles.length === 0 ? (
                    No rejected files
                    ) : ( {(fileRejection) => (
                    Validation Errors: {(error) =>
                    {errorMessages[error] || `❓ ${error}`}
                    }
                    )}
                    ) }
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload with Validation Select Files

                    ✅ Accepted Files

                    {#snippet render(fileUpload)} {#if fileUpload().acceptedFiles.length === 0}
                    No files uploaded yet
                    {:else} {#each fileUpload().acceptedFiles as file (file.name)}
                    PDF
                    Remove
                    {/each} {/if} {/snippet}

                    ❌ Rejected Files

                    {#snippet render(fileUpload)} {#if fileUpload().rejectedFiles.length === 0}
                    No rejected files
                    {:else} {#each fileUpload().rejectedFiles as fileRejection (fileRejection.file.name)}
                    Validation Errors: {#each fileRejection.errors as error}
                    {errorMessages[error] || `❓ ${error}`}
                    {/each}
                    {/each} {/if} {/snippet}
                    ``` ### File Transformations Use `transformFiles` to process files before they're added. Useful for image compression, format conversion, or resizing. **Example: transform-files** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { compressAccurately } from 'image-conversion' import { ImageIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const TransformFiles = () => { const transformFiles = async (files: File[]) => { return Promise.all( files.map(async (file) => { if (file.type.startsWith('image/')) { try { const blob = await compressAccurately(file, 200) return new File([blob], file.name, { type: blob.type }) } catch (error) { console.error('Compression failed for:', file.name, error) return file } } return file }), ) } return ( Upload with Compression Choose Images {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) } ) } ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { compressAccurately } from 'image-conversion' import { For } from 'solid-js' export const TransformFiles = () => { const transformFiles = async (files: File[]) => { return Promise.all( files.map(async (file) => { if (file.type.startsWith('image/')) { try { const blob = await compressAccurately(file, 200) return new File([blob], file.name, { type: blob.type }) } catch (error) { console.error('Compression failed for:', file.name, error) return file } } return file }), ) } return ( File Upload with Compression Choose Images {(fileUpload) => ( {(file) => ( Remove )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Upload with Compression Choose Images {#snippet render(fileUpload)} {#each fileUpload().acceptedFiles as file (file.name)} X {/each} {/snippet} ``` ### Field Use `Field` to add helper text and error handling. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { FileUpload } from '@ark-ui/react/file-upload' import { FileIcon, UploadIcon, XIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/file-upload.module.css' export const WithField = () => ( Attachments
                    Drop files here or click to browse
                    {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) }
                    Upload up to 5 files Please upload at least one file
                    ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { FileUpload } from '@ark-ui/solid/file-upload' export const WithField = (props: Field.RootProps) => ( Label Select Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Select Additional Info Error Info ``` ### 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. **Example: root-provider** #### React ```tsx import { FileUpload, useFileUpload } from '@ark-ui/react/file-upload' import { FileIcon, UploadIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/file-upload.module.css' export const RootProvider = () => { const fileUpload = useFileUpload({ maxFiles: 5 }) return (
                    File Upload
                    Drop files here or click to browse
                    {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) }
                    ) } ``` #### Solid ```tsx import { FileUpload, useFileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const RootProvider = () => { const fileUpload = useFileUpload({ maxFiles: 5 }) return ( <> File Upload Drag your file(s)here Choose file(s) {(context) => ( {(file) => ( Any Icon X )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    File Upload Drag your file(s) here Choose file(s) {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} X {/each} {/snippet}
                    ``` ### Pasting Files Use `setClipboardFiles` to enable pasting images from the clipboard. **Example: pasting-files** #### React ```tsx import { FileUpload, useFileUpload } from '@ark-ui/react/file-upload' import { ClipboardIcon, XIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/file-upload.module.css' export const PastingFiles = () => { const fileUpload = useFileUpload({ maxFiles: 3, accept: 'image/*' }) return ( Upload with Paste {#each fileUpload().acceptedFiles as file (file.name)} X {/each} ``` ### Media Capture Use `capture` to access the device camera. Set to `"environment"` for back camera or `"user"` for front camera. **Example: media-capture** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { CameraIcon, FileIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const MediaCapture = () => ( Capture Photo Open Camera {({ acceptedFiles }) => acceptedFiles.map((file) => ( {file.webkitRelativePath || file.name} )) } ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const MediaCapture = () => ( Open Camera {(context) => ( {(file) => ( {file.webkitRelativePath || file.name} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Camera {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} {file.webkitRelativePath ?? file.name} {/each} {/snippet} ``` ### Rejected Files Access `rejectedFiles` from the context to display validation errors. **Example: rejected-files** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { AlertCircleIcon, CheckCircleIcon, UploadIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const RejectedFiles = () => ( { console.log('Rejected files:', details) }} > Upload Files (Max 2)
                    Drop files here Maximum 2 files allowed
                    {({ acceptedFiles, rejectedFiles }) => ( <> {acceptedFiles.length > 0 && (
                    Accepted Files
                    {acceptedFiles.map((file) => ( ))}
                    )} {rejectedFiles.length > 0 && (
                    Rejected Files
                    {rejectedFiles.map(({ file, errors }) => (
                    {errors.map((error, index) => ( {error} ))}
                    ))}
                    )} )}
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid' import { XIcon } from 'lucide-solid' import { For } from 'solid-js' export const RejectedFiles = () => { return ( { console.log(fileRejection) }} > Drag and drop your images here {/* Accepted Files */}

                    Accepted Files

                    {(context) => ( {(file) => ( )} )}
                    {/* Rejected Files */}

                    Rejected Files

                    {(context) => ( {(fileRejection) => ( )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte console.log(fileRejection)}> Drag and drop your images here

                    Accepted Files

                    {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} {/each} {/snippet}

                    Rejected Files

                    {#snippet render(context)} {#each context().rejectedFiles as { file, errors } (file.name)} {errors.join(', ')} {/each} {/snippet}
                    ``` ## Guides ### File Previews Use `ItemPreview` with type matching to show appropriate previews based on file format. - `type="image/*"`: Shows image thumbnails using `ItemPreviewImage` - `type="video/*"`: For video file previews - `type="application/pdf"`: For PDF files - `type=".*"`: Generic fallback for any file type ```tsx ``` ### Disable Dropzone To disable drag-and-drop functionality, set `allowDrop` to `false`. ```tsx {/* ... */} ``` ### Prevent Document Drop By default, we prevent accidental navigation when files are dropped outside the dropzone. Set `preventDocumentDrop` to `false` to disable this. ```tsx {/* ... */} ``` ### Prevent Double Open Use `disableClick` on `Dropzone` when delegating clicks to a nested `Trigger`. This prevents the file picker from opening twice. ```tsx Choose Files Drag files here ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `accept` | `Record | FileMimeType | FileMimeType[]` | No | The accept file types | | `acceptedFiles` | `File[]` | No | The controlled accepted files | | `allowDrop` | `boolean` | No | Whether to allow drag and drop in the dropzone element | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `capture` | `'user' | 'environment'` | No | The default camera to use when capturing media | | `defaultAcceptedFiles` | `File[]` | No | The default accepted files when rendered. Use when you don't need to control the accepted files of the input. | | `directory` | `boolean` | No | Whether to accept directories, only works in webkit browsers | | `disabled` | `boolean` | No | Whether the file input is disabled | | `ids` | `Partial<{ root: string dropzone: string hiddenInput: string trigger: string label: string item: (id: string) => string itemName: (id: string) => string itemSizeText: (id: string) => string itemPreview: (id: string) => string }>` | No | The ids of the elements. Useful for composition. | | `invalid` | `boolean` | No | Whether the file input is invalid | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `maxFiles` | `number` | No | The maximum number of files | | `maxFileSize` | `number` | No | The maximum file size in bytes | | `minFileSize` | `number` | No | The minimum file size in bytes | | `name` | `string` | No | The name of the underlying file input | | `onFileAccept` | `(details: FileAcceptDetails) => void` | No | Function called when the file is accepted | | `onFileChange` | `(details: FileChangeDetails) => void` | No | Function called when the value changes, whether accepted or rejected | | `onFileReject` | `(details: FileRejectDetails) => void` | No | Function called when the file is rejected | | `preventDocumentDrop` | `boolean` | No | Whether to prevent the drop event on the document | | `required` | `boolean` | No | Whether the file input is required | | `transformFiles` | `(files: File[]) => Promise` | No | Function to transform the accepted files to apply transformations | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `validate` | `(file: File, details: FileValidateDetails) => FileError[] | null` | No | Function to validate a file | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | clear-trigger | | `[data-disabled]` | Present when disabled | **Dropzone Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disableClick` | `boolean` | No | Whether to disable the click event on the dropzone | **Dropzone Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | dropzone | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `ItemType` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemName Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemName Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-name | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreviewImage Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreviewImage Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview-image | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `string` | No | The file type to match against. Matches all file types by default. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `file` | `File` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemSizeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemSizeText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-size-text | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFileUploadReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `accept` | `Record | FileMimeType | FileMimeType[]` | No | The accept file types | | `acceptedFiles` | `File[]` | No | The controlled accepted files | | `allowDrop` | `boolean` | No | Whether to allow drag and drop in the dropzone element | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `capture` | `'user' | 'environment'` | No | The default camera to use when capturing media | | `defaultAcceptedFiles` | `File[]` | No | The default accepted files when rendered. Use when you don't need to control the accepted files of the input. | | `directory` | `boolean` | No | Whether to accept directories, only works in webkit browsers | | `disabled` | `boolean` | No | Whether the file input is disabled | | `ids` | `Partial<{ root: string dropzone: string hiddenInput: string trigger: string label: string item: (id: string) => string itemName: (id: string) => string itemSizeText: (id: string) => string itemPreview: (id: string) => string }>` | No | The ids of the elements. Useful for composition. | | `invalid` | `boolean` | No | Whether the file input is invalid | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `maxFiles` | `number` | No | The maximum number of files | | `maxFileSize` | `number` | No | The maximum file size in bytes | | `minFileSize` | `number` | No | The minimum file size in bytes | | `name` | `string` | No | The name of the underlying file input | | `onFileAccept` | `(details: FileAcceptDetails) => void` | No | Function called when the file is accepted | | `onFileChange` | `(details: FileChangeDetails) => void` | No | Function called when the value changes, whether accepted or rejected | | `onFileReject` | `(details: FileRejectDetails) => void` | No | Function called when the file is rejected | | `preventDocumentDrop` | `boolean` | No | Whether to prevent the drop event on the document | | `required` | `boolean` | No | Whether the file input is required | | `transformFiles` | `(files: File[]) => Promise` | No | Function to transform the accepted files to apply transformations | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `validate` | `(file: File, details: FileValidateDetails) => FileError[] | null` | No | Function to validate a file | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | clear-trigger | | `[data-disabled]` | Present when disabled | **Dropzone Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disableClick` | `boolean` | No | Whether to disable the click event on the dropzone | **Dropzone Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | dropzone | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'ul'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `ItemType` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemName Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemName Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-name | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreviewImage Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'img'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreviewImage Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview-image | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `string` | No | The file type to match against. Matches all file types by default. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `file` | `File` | Yes | | | `asChild` | `(props: ParentProps<'li'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemSizeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemSizeText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-size-text | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFileUploadReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `accept` | `Record | FileMimeType | FileMimeType[]` | No | The accept file types | | `allowDrop` | `boolean` | No | Whether to allow drag and drop in the dropzone element | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `capture` | `'user' | 'environment'` | No | The default camera to use when capturing media | | `defaultAcceptedFiles` | `File[]` | No | The default accepted files | | `directory` | `boolean` | No | Whether to accept directories, only works in webkit browsers | | `disabled` | `boolean` | No | Whether the file input is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string dropzone: string hiddenInput: string trigger: string label: string item(id: string): string itemName(id: string): string itemSizeText(id: string): string itemPreview(id: string): string }>` | No | The ids of the elements. Useful for composition. | | `invalid` | `boolean` | No | Whether the file input is invalid | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `maxFiles` | `number` | No | The maximum number of files | | `maxFileSize` | `number` | No | The maximum file size in bytes | | `minFileSize` | `number` | No | The minimum file size in bytes | | `name` | `string` | No | The name of the underlying file input | | `preventDocumentDrop` | `boolean` | No | Whether to prevent the drop event on the document | | `required` | `boolean` | No | Whether the file input is required | | `transformFiles` | `(files: File[]) => Promise` | No | Function to transform the files | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `validate` | `(file: File, details: FileValidateDetails) => FileError[] | null` | No | Function to validate a file | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | clear-trigger | | `[data-disabled]` | Present when disabled | **Dropzone Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disableClick` | `boolean` | No | Whether to disable the click event on the dropzone | **Dropzone Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | dropzone | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `ItemType` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemName Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemName Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-name | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreviewImage Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreviewImage Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview-image | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `string` | No | The file type to match against. Matches all file types by default. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `file` | `File` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `ItemType` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemSizeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemSizeText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-size-text | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `FileUploadApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `accept` | `Record | FileMimeType | FileMimeType[]` | No | The accept file types | | `acceptedFiles` | `File[]` | No | The controlled accepted files | | `allowDrop` | `boolean` | No | Whether to allow drag and drop in the dropzone element | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `capture` | `'user' | 'environment'` | No | The default camera to use when capturing media | | `defaultAcceptedFiles` | `File[]` | No | The default accepted files when rendered. Use when you don't need to control the accepted files of the input. | | `directory` | `boolean` | No | Whether to accept directories, only works in webkit browsers | | `disabled` | `boolean` | No | Whether the file input is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string dropzone: string hiddenInput: string trigger: string label: string item: (id: string) => string itemName: (id: string) => string itemSizeText: (id: string) => string itemPreview: (id: string) => string }>` | No | The ids of the elements. Useful for composition. | | `invalid` | `boolean` | No | Whether the file input is invalid | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `maxFiles` | `number` | No | The maximum number of files | | `maxFileSize` | `number` | No | The maximum file size in bytes | | `minFileSize` | `number` | No | The minimum file size in bytes | | `name` | `string` | No | The name of the underlying file input | | `onFileAccept` | `(details: FileAcceptDetails) => void` | No | Function called when the file is accepted | | `onFileChange` | `(details: FileChangeDetails) => void` | No | Function called when the value changes, whether accepted or rejected | | `onFileReject` | `(details: FileRejectDetails) => void` | No | Function called when the file is rejected | | `preventDocumentDrop` | `boolean` | No | Whether to prevent the drop event on the document | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the file input is required | | `transformFiles` | `(files: File[]) => Promise` | No | Function to transform the accepted files to apply transformations | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `validate` | `(file: File, details: FileValidateDetails) => FileError[] | null` | No | Function to validate a file | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | clear-trigger | | `[data-disabled]` | Present when disabled | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseFileUploadContext]>` | No | | **Dropzone Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disableClick` | `boolean` | No | Whether to disable the click event on the dropzone | | `ref` | `Element` | No | | **Dropzone Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | dropzone | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `type` | `ItemType` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemName Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemName Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-name | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreviewImage Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'img'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemPreviewImage Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview-image | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `type` | `string` | No | The file type to match against. Matches all file types by default. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `file` | `File` | Yes | | | `asChild` | `Snippet<[PropsFn<'li'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemSizeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemSizeText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-size-text | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFileUploadReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `dragging` | `boolean` | Whether the user is dragging something over the root element | | `focused` | `boolean` | Whether the user is focused on the dropzone element | | `disabled` | `boolean` | Whether the file input is disabled | | `transforming` | `boolean` | Whether files are currently being transformed via `transformFiles` | | `openFilePicker` | `VoidFunction` | Function to open the file dialog | | `deleteFile` | `(file: File, type?: ItemType) => void` | Function to delete the file from the list | | `acceptedFiles` | `File[]` | The accepted files that have been dropped or selected | | `rejectedFiles` | `FileRejection[]` | The files that have been rejected | | `setFiles` | `(files: File[]) => void` | Sets the accepted files | | `clearFiles` | `VoidFunction` | Clears the accepted files | | `clearRejectedFiles` | `VoidFunction` | Clears the rejected files | | `getFileSize` | `(file: File) => string` | Returns the formatted file size (e.g. 1.2MB) | | `createFileUrl` | `(file: File, cb: (url: string) => void) => VoidFunction` | Returns the preview url of a file. Returns a function to revoke the url. | | `setClipboardFiles` | `(dt: DataTransfer) => boolean` | Sets the clipboard files Returns `true` if the clipboard data contains files, `false` otherwise. | --- # File Upload (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { PaperclipIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const Basic = () => ( File Upload Choose file(s) {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) } ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const Basic = () => ( File Upload Choose file(s) {(context) => ( {(file) => ( X )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload Choose file(s) {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} X {/each} {/snippet} ``` ### Initial Files Use the `defaultAcceptedFiles` prop to set the initial files in the file upload component. **Example: initial-files** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { FileIcon, PaperclipIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const InitialFiles = () => ( File Upload Choose file(s) {({ acceptedFiles }) => acceptedFiles.map((file) => (
                    )) }
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const InitialFiles = () => ( File Upload Choose file(s) {(context) => ( {(file) => (
                    📄
                    )}
                    )}
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload Choose file(s) {#snippet render(context)} {#each context().acceptedFiles as file (file.name)}
                    📄
                    {/each} {/snippet}
                    ``` ### Clear Trigger Use the `ClearTrigger` to remove all uploaded files at once. **Example: clear-trigger** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { PaperclipIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const ClearTrigger = () => ( File Upload
                    Choose file(s) Clear Files
                    {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) }
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const ClearTrigger = () => ( File Upload Choose file(s) Clear Files {(context) => ( {(file) => ( )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload Drag your file(s) here Choose file(s) {#snippet render(context)} {#if context().acceptedFiles.length > 0} {/if} {/snippet} {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} X {/each} {/snippet} ``` ### Dropzone Use the `Dropzone` to enable drag-and-drop. It exposes a `data-dragging` attribute for styling. **Example: dropzone** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { FileIcon, UploadIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const Dropzone = () => ( File Upload
                    Drag and drop files here or click to browse
                    {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) }
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const Dropzone = () => ( File Upload Drag and drop files here {(context) => ( {(file) => ( File X )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload Drag and drop files here {#snippet render(fileUpload)} {#each fileUpload().acceptedFiles as file (file.name)} X {/each} {/snippet} ``` ### Directory Upload Use the `directory` prop to upload entire folders. Access file paths through `file.webkitRelativePath`. **Example: directory-upload** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { FileIcon, FolderIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const DirectoryUpload = () => ( Upload Folder Select Folder {({ acceptedFiles }) => acceptedFiles.map((file) => (
                    {file.webkitRelativePath || file.name}
                    )) }
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const DirectoryUpload = () => ( Upload Folder {(fileUpload) => ( {(file) => ( {file.webkitRelativePath ?? file.name} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Upload Folder {#snippet render(fileUpload)} {#each fileUpload().acceptedFiles as file (file.name)} {file.webkitRelativePath ?? file.name} {/each} {/snippet} ``` > 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`). **Example: accepted-file-types** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { AlertCircleIcon, ImageIcon, UploadIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const AcceptedFileTypes = () => ( Upload Images (PNG and JPEG only)
                    Drop your images here Only PNG and JPEG files
                    {({ acceptedFiles, rejectedFiles }) => ( <> {acceptedFiles.length > 0 && ( {acceptedFiles.map((file) => ( ))} )} {rejectedFiles.length > 0 && ( {rejectedFiles.map((fileRejection) => (
                    {fileRejection.errors.map((error) => (
                    {error}
                    ))}
                    ))}
                    )} )}
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const AcceptedFileTypes = () => ( File Upload (PNG and JPEG only) Drop your files here Select Files {(context) => ( {(file) => ( Remove )} )} {(context) => ( {(fileRejection) => (
                    {(error) =>
                    {error}
                    }
                    )}
                    )}
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload (PNG and JPEG only) Drop your files here Select Files {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} Remove {/each} {/snippet} {#snippet render(context)} {#each context().rejectedFiles as fileRejection (fileRejection.file.name)}
                    {#each fileRejection.errors as error}
                    {error}
                    {/each}
                    {/each} {/snippet}
                    ``` ### 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`. **Example: error-handling** #### React ```tsx import { FileUpload, type FileUploadFileError } from '@ark-ui/react/file-upload' import { AlertCircleIcon, CheckCircleIcon, FileIcon, UploadIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' const errorMessages: Record = { TOO_MANY_FILES: 'Too many files selected (max 3 allowed)', FILE_INVALID_TYPE: 'Invalid file type (only images and PDFs allowed)', FILE_TOO_LARGE: 'File too large (max 1MB)', FILE_TOO_SMALL: 'File too small (min 1KB)', FILE_INVALID: 'Invalid file', FILE_EXISTS: 'File already exists', } export const ErrorHandling = () => ( Upload Documents
                    Drop files here Images and PDFs, max 1MB each
                    {({ acceptedFiles, rejectedFiles }) => ( <> {acceptedFiles.length > 0 && (
                    Accepted Files
                    {acceptedFiles.map((file) => ( ))}
                    )} {rejectedFiles.length > 0 && (
                    Rejected Files
                    {rejectedFiles.map((fileRejection) => (
                    {fileRejection.errors.map((error, index) => (
                    {errorMessages[error as FileUploadFileError] || error}
                    ))}
                    ))}
                    )} )}
                    ) ``` #### Solid ```tsx import { FileUpload, type FileUploadFileError } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' const errorMessages: Record = { TOO_MANY_FILES: '📊 Too many files selected (max 3 allowed)', FILE_INVALID_TYPE: '🚫 Invalid file type (only images and PDFs allowed)', FILE_TOO_LARGE: '📏 File too large (max 1MB)', FILE_TOO_SMALL: '📐 File too small (min 1KB)', FILE_INVALID: '⚠️ Invalid file', FILE_EXISTS: '🔄 File already exists', } export const ErrorHandling = () => ( File Upload with Validation Select Files {/* Accepted Files Section */}

                    ✅ Accepted Files

                    {(fileUpload) => fileUpload().acceptedFiles.length === 0 ? (
                    No files uploaded yet
                    ) : ( {(file) => (
                    PDF
                    Remove
                    )}
                    ) }
                    {/* Rejected Files Section */}

                    ❌ Rejected Files

                    {(fileUpload) => fileUpload().rejectedFiles.length === 0 ? (
                    No rejected files
                    ) : ( {(fileRejection) => (
                    Validation Errors: {(error) =>
                    {errorMessages[error] || `❓ ${error}`}
                    }
                    )}
                    ) }
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload with Validation Select Files

                    ✅ Accepted Files

                    {#snippet render(fileUpload)} {#if fileUpload().acceptedFiles.length === 0}
                    No files uploaded yet
                    {:else} {#each fileUpload().acceptedFiles as file (file.name)}
                    PDF
                    Remove
                    {/each} {/if} {/snippet}

                    ❌ Rejected Files

                    {#snippet render(fileUpload)} {#if fileUpload().rejectedFiles.length === 0}
                    No rejected files
                    {:else} {#each fileUpload().rejectedFiles as fileRejection (fileRejection.file.name)}
                    Validation Errors: {#each fileRejection.errors as error}
                    {errorMessages[error] || `❓ ${error}`}
                    {/each}
                    {/each} {/if} {/snippet}
                    ``` ### File Transformations Use `transformFiles` to process files before they're added. Useful for image compression, format conversion, or resizing. **Example: transform-files** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { compressAccurately } from 'image-conversion' import { ImageIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const TransformFiles = () => { const transformFiles = async (files: File[]) => { return Promise.all( files.map(async (file) => { if (file.type.startsWith('image/')) { try { const blob = await compressAccurately(file, 200) return new File([blob], file.name, { type: blob.type }) } catch (error) { console.error('Compression failed for:', file.name, error) return file } } return file }), ) } return ( Upload with Compression Choose Images {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) } ) } ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { compressAccurately } from 'image-conversion' import { For } from 'solid-js' export const TransformFiles = () => { const transformFiles = async (files: File[]) => { return Promise.all( files.map(async (file) => { if (file.type.startsWith('image/')) { try { const blob = await compressAccurately(file, 200) return new File([blob], file.name, { type: blob.type }) } catch (error) { console.error('Compression failed for:', file.name, error) return file } } return file }), ) } return ( File Upload with Compression Choose Images {(fileUpload) => ( {(file) => ( Remove )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Upload with Compression Choose Images {#snippet render(fileUpload)} {#each fileUpload().acceptedFiles as file (file.name)} X {/each} {/snippet} ``` ### Field Use `Field` to add helper text and error handling. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { FileUpload } from '@ark-ui/react/file-upload' import { FileIcon, UploadIcon, XIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/file-upload.module.css' export const WithField = () => ( Attachments
                    Drop files here or click to browse
                    {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) }
                    Upload up to 5 files Please upload at least one file
                    ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { FileUpload } from '@ark-ui/solid/file-upload' export const WithField = (props: Field.RootProps) => ( Label Select Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Select Additional Info Error Info ``` ### 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. **Example: root-provider** #### React ```tsx import { FileUpload, useFileUpload } from '@ark-ui/react/file-upload' import { FileIcon, UploadIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/file-upload.module.css' export const RootProvider = () => { const fileUpload = useFileUpload({ maxFiles: 5 }) return (
                    File Upload
                    Drop files here or click to browse
                    {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) }
                    ) } ``` #### Solid ```tsx import { FileUpload, useFileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const RootProvider = () => { const fileUpload = useFileUpload({ maxFiles: 5 }) return ( <> File Upload Drag your file(s)here Choose file(s) {(context) => ( {(file) => ( Any Icon X )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    File Upload Drag your file(s) here Choose file(s) {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} X {/each} {/snippet}
                    ``` ### Pasting Files Use `setClipboardFiles` to enable pasting images from the clipboard. **Example: pasting-files** #### React ```tsx import { FileUpload, useFileUpload } from '@ark-ui/react/file-upload' import { ClipboardIcon, XIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/file-upload.module.css' export const PastingFiles = () => { const fileUpload = useFileUpload({ maxFiles: 3, accept: 'image/*' }) return ( Upload with Paste {#each fileUpload().acceptedFiles as file (file.name)} X {/each} ``` ### Media Capture Use `capture` to access the device camera. Set to `"environment"` for back camera or `"user"` for front camera. **Example: media-capture** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { CameraIcon, FileIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const MediaCapture = () => ( Capture Photo Open Camera {({ acceptedFiles }) => acceptedFiles.map((file) => ( {file.webkitRelativePath || file.name} )) } ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const MediaCapture = () => ( Open Camera {(context) => ( {(file) => ( {file.webkitRelativePath || file.name} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Camera {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} {file.webkitRelativePath ?? file.name} {/each} {/snippet} ``` ### Rejected Files Access `rejectedFiles` from the context to display validation errors. **Example: rejected-files** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { AlertCircleIcon, CheckCircleIcon, UploadIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const RejectedFiles = () => ( { console.log('Rejected files:', details) }} > Upload Files (Max 2)
                    Drop files here Maximum 2 files allowed
                    {({ acceptedFiles, rejectedFiles }) => ( <> {acceptedFiles.length > 0 && (
                    Accepted Files
                    {acceptedFiles.map((file) => ( ))}
                    )} {rejectedFiles.length > 0 && (
                    Rejected Files
                    {rejectedFiles.map(({ file, errors }) => (
                    {errors.map((error, index) => ( {error} ))}
                    ))}
                    )} )}
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid' import { XIcon } from 'lucide-solid' import { For } from 'solid-js' export const RejectedFiles = () => { return ( { console.log(fileRejection) }} > Drag and drop your images here {/* Accepted Files */}

                    Accepted Files

                    {(context) => ( {(file) => ( )} )}
                    {/* Rejected Files */}

                    Rejected Files

                    {(context) => ( {(fileRejection) => ( )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte console.log(fileRejection)}> Drag and drop your images here

                    Accepted Files

                    {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} {/each} {/snippet}

                    Rejected Files

                    {#snippet render(context)} {#each context().rejectedFiles as { file, errors } (file.name)} {errors.join(', ')} {/each} {/snippet}
                    ``` ## Guides ### File Previews Use `ItemPreview` with type matching to show appropriate previews based on file format. - `type="image/*"`: Shows image thumbnails using `ItemPreviewImage` - `type="video/*"`: For video file previews - `type="application/pdf"`: For PDF files - `type=".*"`: Generic fallback for any file type ```tsx ``` ### Disable Dropzone To disable drag-and-drop functionality, set `allowDrop` to `false`. ```tsx {/* ... */} ``` ### Prevent Document Drop By default, we prevent accidental navigation when files are dropped outside the dropzone. Set `preventDocumentDrop` to `false` to disable this. ```tsx {/* ... */} ``` ### Prevent Double Open Use `disableClick` on `Dropzone` when delegating clicks to a nested `Trigger`. This prevents the file picker from opening twice. ```tsx Choose Files Drag files here ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `accept` | `Record | FileMimeType | FileMimeType[]` | No | The accept file types | | `acceptedFiles` | `File[]` | No | The controlled accepted files | | `allowDrop` | `boolean` | No | Whether to allow drag and drop in the dropzone element | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `capture` | `'user' | 'environment'` | No | The default camera to use when capturing media | | `defaultAcceptedFiles` | `File[]` | No | The default accepted files when rendered. Use when you don't need to control the accepted files of the input. | | `directory` | `boolean` | No | Whether to accept directories, only works in webkit browsers | | `disabled` | `boolean` | No | Whether the file input is disabled | | `ids` | `Partial<{ root: string dropzone: string hiddenInput: string trigger: string label: string item: (id: string) => string itemName: (id: string) => string itemSizeText: (id: string) => string itemPreview: (id: string) => string }>` | No | The ids of the elements. Useful for composition. | | `invalid` | `boolean` | No | Whether the file input is invalid | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `maxFiles` | `number` | No | The maximum number of files | | `maxFileSize` | `number` | No | The maximum file size in bytes | | `minFileSize` | `number` | No | The minimum file size in bytes | | `name` | `string` | No | The name of the underlying file input | | `onFileAccept` | `(details: FileAcceptDetails) => void` | No | Function called when the file is accepted | | `onFileChange` | `(details: FileChangeDetails) => void` | No | Function called when the value changes, whether accepted or rejected | | `onFileReject` | `(details: FileRejectDetails) => void` | No | Function called when the file is rejected | | `preventDocumentDrop` | `boolean` | No | Whether to prevent the drop event on the document | | `required` | `boolean` | No | Whether the file input is required | | `transformFiles` | `(files: File[]) => Promise` | No | Function to transform the accepted files to apply transformations | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `validate` | `(file: File, details: FileValidateDetails) => FileError[] | null` | No | Function to validate a file | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | clear-trigger | | `[data-disabled]` | Present when disabled | **Dropzone Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disableClick` | `boolean` | No | Whether to disable the click event on the dropzone | **Dropzone Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | dropzone | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `ItemType` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemName Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemName Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-name | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreviewImage Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreviewImage Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview-image | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `string` | No | The file type to match against. Matches all file types by default. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `file` | `File` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemSizeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemSizeText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-size-text | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFileUploadReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `accept` | `Record | FileMimeType | FileMimeType[]` | No | The accept file types | | `acceptedFiles` | `File[]` | No | The controlled accepted files | | `allowDrop` | `boolean` | No | Whether to allow drag and drop in the dropzone element | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `capture` | `'user' | 'environment'` | No | The default camera to use when capturing media | | `defaultAcceptedFiles` | `File[]` | No | The default accepted files when rendered. Use when you don't need to control the accepted files of the input. | | `directory` | `boolean` | No | Whether to accept directories, only works in webkit browsers | | `disabled` | `boolean` | No | Whether the file input is disabled | | `ids` | `Partial<{ root: string dropzone: string hiddenInput: string trigger: string label: string item: (id: string) => string itemName: (id: string) => string itemSizeText: (id: string) => string itemPreview: (id: string) => string }>` | No | The ids of the elements. Useful for composition. | | `invalid` | `boolean` | No | Whether the file input is invalid | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `maxFiles` | `number` | No | The maximum number of files | | `maxFileSize` | `number` | No | The maximum file size in bytes | | `minFileSize` | `number` | No | The minimum file size in bytes | | `name` | `string` | No | The name of the underlying file input | | `onFileAccept` | `(details: FileAcceptDetails) => void` | No | Function called when the file is accepted | | `onFileChange` | `(details: FileChangeDetails) => void` | No | Function called when the value changes, whether accepted or rejected | | `onFileReject` | `(details: FileRejectDetails) => void` | No | Function called when the file is rejected | | `preventDocumentDrop` | `boolean` | No | Whether to prevent the drop event on the document | | `required` | `boolean` | No | Whether the file input is required | | `transformFiles` | `(files: File[]) => Promise` | No | Function to transform the accepted files to apply transformations | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `validate` | `(file: File, details: FileValidateDetails) => FileError[] | null` | No | Function to validate a file | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | clear-trigger | | `[data-disabled]` | Present when disabled | **Dropzone Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disableClick` | `boolean` | No | Whether to disable the click event on the dropzone | **Dropzone Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | dropzone | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'ul'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `ItemType` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemName Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemName Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-name | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreviewImage Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'img'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreviewImage Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview-image | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `string` | No | The file type to match against. Matches all file types by default. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `file` | `File` | Yes | | | `asChild` | `(props: ParentProps<'li'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemSizeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemSizeText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-size-text | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFileUploadReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `accept` | `Record | FileMimeType | FileMimeType[]` | No | The accept file types | | `allowDrop` | `boolean` | No | Whether to allow drag and drop in the dropzone element | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `capture` | `'user' | 'environment'` | No | The default camera to use when capturing media | | `defaultAcceptedFiles` | `File[]` | No | The default accepted files | | `directory` | `boolean` | No | Whether to accept directories, only works in webkit browsers | | `disabled` | `boolean` | No | Whether the file input is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string dropzone: string hiddenInput: string trigger: string label: string item(id: string): string itemName(id: string): string itemSizeText(id: string): string itemPreview(id: string): string }>` | No | The ids of the elements. Useful for composition. | | `invalid` | `boolean` | No | Whether the file input is invalid | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `maxFiles` | `number` | No | The maximum number of files | | `maxFileSize` | `number` | No | The maximum file size in bytes | | `minFileSize` | `number` | No | The minimum file size in bytes | | `name` | `string` | No | The name of the underlying file input | | `preventDocumentDrop` | `boolean` | No | Whether to prevent the drop event on the document | | `required` | `boolean` | No | Whether the file input is required | | `transformFiles` | `(files: File[]) => Promise` | No | Function to transform the files | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `validate` | `(file: File, details: FileValidateDetails) => FileError[] | null` | No | Function to validate a file | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | clear-trigger | | `[data-disabled]` | Present when disabled | **Dropzone Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disableClick` | `boolean` | No | Whether to disable the click event on the dropzone | **Dropzone Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | dropzone | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `ItemType` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemName Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemName Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-name | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreviewImage Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreviewImage Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview-image | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `string` | No | The file type to match against. Matches all file types by default. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `file` | `File` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `ItemType` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemSizeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemSizeText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-size-text | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `FileUploadApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `accept` | `Record | FileMimeType | FileMimeType[]` | No | The accept file types | | `acceptedFiles` | `File[]` | No | The controlled accepted files | | `allowDrop` | `boolean` | No | Whether to allow drag and drop in the dropzone element | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `capture` | `'user' | 'environment'` | No | The default camera to use when capturing media | | `defaultAcceptedFiles` | `File[]` | No | The default accepted files when rendered. Use when you don't need to control the accepted files of the input. | | `directory` | `boolean` | No | Whether to accept directories, only works in webkit browsers | | `disabled` | `boolean` | No | Whether the file input is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string dropzone: string hiddenInput: string trigger: string label: string item: (id: string) => string itemName: (id: string) => string itemSizeText: (id: string) => string itemPreview: (id: string) => string }>` | No | The ids of the elements. Useful for composition. | | `invalid` | `boolean` | No | Whether the file input is invalid | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `maxFiles` | `number` | No | The maximum number of files | | `maxFileSize` | `number` | No | The maximum file size in bytes | | `minFileSize` | `number` | No | The minimum file size in bytes | | `name` | `string` | No | The name of the underlying file input | | `onFileAccept` | `(details: FileAcceptDetails) => void` | No | Function called when the file is accepted | | `onFileChange` | `(details: FileChangeDetails) => void` | No | Function called when the value changes, whether accepted or rejected | | `onFileReject` | `(details: FileRejectDetails) => void` | No | Function called when the file is rejected | | `preventDocumentDrop` | `boolean` | No | Whether to prevent the drop event on the document | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the file input is required | | `transformFiles` | `(files: File[]) => Promise` | No | Function to transform the accepted files to apply transformations | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `validate` | `(file: File, details: FileValidateDetails) => FileError[] | null` | No | Function to validate a file | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | clear-trigger | | `[data-disabled]` | Present when disabled | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseFileUploadContext]>` | No | | **Dropzone Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disableClick` | `boolean` | No | Whether to disable the click event on the dropzone | | `ref` | `Element` | No | | **Dropzone Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | dropzone | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `type` | `ItemType` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemName Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemName Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-name | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreviewImage Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'img'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemPreviewImage Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview-image | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `type` | `string` | No | The file type to match against. Matches all file types by default. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `file` | `File` | Yes | | | `asChild` | `Snippet<[PropsFn<'li'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemSizeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemSizeText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-size-text | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFileUploadReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `dragging` | `boolean` | Whether the user is dragging something over the root element | | `focused` | `boolean` | Whether the user is focused on the dropzone element | | `disabled` | `boolean` | Whether the file input is disabled | | `transforming` | `boolean` | Whether files are currently being transformed via `transformFiles` | | `openFilePicker` | `VoidFunction` | Function to open the file dialog | | `deleteFile` | `(file: File, type?: ItemType) => void` | Function to delete the file from the list | | `acceptedFiles` | `File[]` | The accepted files that have been dropped or selected | | `rejectedFiles` | `FileRejection[]` | The files that have been rejected | | `setFiles` | `(files: File[]) => void` | Sets the accepted files | | `clearFiles` | `VoidFunction` | Clears the accepted files | | `clearRejectedFiles` | `VoidFunction` | Clears the rejected files | | `getFileSize` | `(file: File) => string` | Returns the formatted file size (e.g. 1.2MB) | | `createFileUrl` | `(file: File, cb: (url: string) => void) => VoidFunction` | Returns the preview url of a file. Returns a function to revoke the url. | | `setClipboardFiles` | `(dt: DataTransfer) => boolean` | Sets the clipboard files Returns `true` if the clipboard data contains files, `false` otherwise. | --- # File Upload (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { PaperclipIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const Basic = () => ( File Upload Choose file(s) {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) } ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const Basic = () => ( File Upload Choose file(s) {(context) => ( {(file) => ( X )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload Choose file(s) {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} X {/each} {/snippet} ``` ### Initial Files Use the `defaultAcceptedFiles` prop to set the initial files in the file upload component. **Example: initial-files** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { FileIcon, PaperclipIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const InitialFiles = () => ( File Upload Choose file(s) {({ acceptedFiles }) => acceptedFiles.map((file) => (
                    )) }
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const InitialFiles = () => ( File Upload Choose file(s) {(context) => ( {(file) => (
                    📄
                    )}
                    )}
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload Choose file(s) {#snippet render(context)} {#each context().acceptedFiles as file (file.name)}
                    📄
                    {/each} {/snippet}
                    ``` ### Clear Trigger Use the `ClearTrigger` to remove all uploaded files at once. **Example: clear-trigger** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { PaperclipIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const ClearTrigger = () => ( File Upload
                    Choose file(s) Clear Files
                    {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) }
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const ClearTrigger = () => ( File Upload Choose file(s) Clear Files {(context) => ( {(file) => ( )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload Drag your file(s) here Choose file(s) {#snippet render(context)} {#if context().acceptedFiles.length > 0} {/if} {/snippet} {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} X {/each} {/snippet} ``` ### Dropzone Use the `Dropzone` to enable drag-and-drop. It exposes a `data-dragging` attribute for styling. **Example: dropzone** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { FileIcon, UploadIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const Dropzone = () => ( File Upload
                    Drag and drop files here or click to browse
                    {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) }
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const Dropzone = () => ( File Upload Drag and drop files here {(context) => ( {(file) => ( File X )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload Drag and drop files here {#snippet render(fileUpload)} {#each fileUpload().acceptedFiles as file (file.name)} X {/each} {/snippet} ``` ### Directory Upload Use the `directory` prop to upload entire folders. Access file paths through `file.webkitRelativePath`. **Example: directory-upload** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { FileIcon, FolderIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const DirectoryUpload = () => ( Upload Folder Select Folder {({ acceptedFiles }) => acceptedFiles.map((file) => (
                    {file.webkitRelativePath || file.name}
                    )) }
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const DirectoryUpload = () => ( Upload Folder {(fileUpload) => ( {(file) => ( {file.webkitRelativePath ?? file.name} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Upload Folder {#snippet render(fileUpload)} {#each fileUpload().acceptedFiles as file (file.name)} {file.webkitRelativePath ?? file.name} {/each} {/snippet} ``` > 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`). **Example: accepted-file-types** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { AlertCircleIcon, ImageIcon, UploadIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const AcceptedFileTypes = () => ( Upload Images (PNG and JPEG only)
                    Drop your images here Only PNG and JPEG files
                    {({ acceptedFiles, rejectedFiles }) => ( <> {acceptedFiles.length > 0 && ( {acceptedFiles.map((file) => ( ))} )} {rejectedFiles.length > 0 && ( {rejectedFiles.map((fileRejection) => (
                    {fileRejection.errors.map((error) => (
                    {error}
                    ))}
                    ))}
                    )} )}
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const AcceptedFileTypes = () => ( File Upload (PNG and JPEG only) Drop your files here Select Files {(context) => ( {(file) => ( Remove )} )} {(context) => ( {(fileRejection) => (
                    {(error) =>
                    {error}
                    }
                    )}
                    )}
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload (PNG and JPEG only) Drop your files here Select Files {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} Remove {/each} {/snippet} {#snippet render(context)} {#each context().rejectedFiles as fileRejection (fileRejection.file.name)}
                    {#each fileRejection.errors as error}
                    {error}
                    {/each}
                    {/each} {/snippet}
                    ``` ### 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`. **Example: error-handling** #### React ```tsx import { FileUpload, type FileUploadFileError } from '@ark-ui/react/file-upload' import { AlertCircleIcon, CheckCircleIcon, FileIcon, UploadIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' const errorMessages: Record = { TOO_MANY_FILES: 'Too many files selected (max 3 allowed)', FILE_INVALID_TYPE: 'Invalid file type (only images and PDFs allowed)', FILE_TOO_LARGE: 'File too large (max 1MB)', FILE_TOO_SMALL: 'File too small (min 1KB)', FILE_INVALID: 'Invalid file', FILE_EXISTS: 'File already exists', } export const ErrorHandling = () => ( Upload Documents
                    Drop files here Images and PDFs, max 1MB each
                    {({ acceptedFiles, rejectedFiles }) => ( <> {acceptedFiles.length > 0 && (
                    Accepted Files
                    {acceptedFiles.map((file) => ( ))}
                    )} {rejectedFiles.length > 0 && (
                    Rejected Files
                    {rejectedFiles.map((fileRejection) => (
                    {fileRejection.errors.map((error, index) => (
                    {errorMessages[error as FileUploadFileError] || error}
                    ))}
                    ))}
                    )} )}
                    ) ``` #### Solid ```tsx import { FileUpload, type FileUploadFileError } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' const errorMessages: Record = { TOO_MANY_FILES: '📊 Too many files selected (max 3 allowed)', FILE_INVALID_TYPE: '🚫 Invalid file type (only images and PDFs allowed)', FILE_TOO_LARGE: '📏 File too large (max 1MB)', FILE_TOO_SMALL: '📐 File too small (min 1KB)', FILE_INVALID: '⚠️ Invalid file', FILE_EXISTS: '🔄 File already exists', } export const ErrorHandling = () => ( File Upload with Validation Select Files {/* Accepted Files Section */}

                    ✅ Accepted Files

                    {(fileUpload) => fileUpload().acceptedFiles.length === 0 ? (
                    No files uploaded yet
                    ) : ( {(file) => (
                    PDF
                    Remove
                    )}
                    ) }
                    {/* Rejected Files Section */}

                    ❌ Rejected Files

                    {(fileUpload) => fileUpload().rejectedFiles.length === 0 ? (
                    No rejected files
                    ) : ( {(fileRejection) => (
                    Validation Errors: {(error) =>
                    {errorMessages[error] || `❓ ${error}`}
                    }
                    )}
                    ) }
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload with Validation Select Files

                    ✅ Accepted Files

                    {#snippet render(fileUpload)} {#if fileUpload().acceptedFiles.length === 0}
                    No files uploaded yet
                    {:else} {#each fileUpload().acceptedFiles as file (file.name)}
                    PDF
                    Remove
                    {/each} {/if} {/snippet}

                    ❌ Rejected Files

                    {#snippet render(fileUpload)} {#if fileUpload().rejectedFiles.length === 0}
                    No rejected files
                    {:else} {#each fileUpload().rejectedFiles as fileRejection (fileRejection.file.name)}
                    Validation Errors: {#each fileRejection.errors as error}
                    {errorMessages[error] || `❓ ${error}`}
                    {/each}
                    {/each} {/if} {/snippet}
                    ``` ### File Transformations Use `transformFiles` to process files before they're added. Useful for image compression, format conversion, or resizing. **Example: transform-files** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { compressAccurately } from 'image-conversion' import { ImageIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const TransformFiles = () => { const transformFiles = async (files: File[]) => { return Promise.all( files.map(async (file) => { if (file.type.startsWith('image/')) { try { const blob = await compressAccurately(file, 200) return new File([blob], file.name, { type: blob.type }) } catch (error) { console.error('Compression failed for:', file.name, error) return file } } return file }), ) } return ( Upload with Compression Choose Images {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) } ) } ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { compressAccurately } from 'image-conversion' import { For } from 'solid-js' export const TransformFiles = () => { const transformFiles = async (files: File[]) => { return Promise.all( files.map(async (file) => { if (file.type.startsWith('image/')) { try { const blob = await compressAccurately(file, 200) return new File([blob], file.name, { type: blob.type }) } catch (error) { console.error('Compression failed for:', file.name, error) return file } } return file }), ) } return ( File Upload with Compression Choose Images {(fileUpload) => ( {(file) => ( Remove )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Upload with Compression Choose Images {#snippet render(fileUpload)} {#each fileUpload().acceptedFiles as file (file.name)} X {/each} {/snippet} ``` ### Field Use `Field` to add helper text and error handling. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { FileUpload } from '@ark-ui/react/file-upload' import { FileIcon, UploadIcon, XIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/file-upload.module.css' export const WithField = () => ( Attachments
                    Drop files here or click to browse
                    {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) }
                    Upload up to 5 files Please upload at least one file
                    ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { FileUpload } from '@ark-ui/solid/file-upload' export const WithField = (props: Field.RootProps) => ( Label Select Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Select Additional Info Error Info ``` ### 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. **Example: root-provider** #### React ```tsx import { FileUpload, useFileUpload } from '@ark-ui/react/file-upload' import { FileIcon, UploadIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/file-upload.module.css' export const RootProvider = () => { const fileUpload = useFileUpload({ maxFiles: 5 }) return (
                    File Upload
                    Drop files here or click to browse
                    {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) }
                    ) } ``` #### Solid ```tsx import { FileUpload, useFileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const RootProvider = () => { const fileUpload = useFileUpload({ maxFiles: 5 }) return ( <> File Upload Drag your file(s)here Choose file(s) {(context) => ( {(file) => ( Any Icon X )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    File Upload Drag your file(s) here Choose file(s) {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} X {/each} {/snippet}
                    ``` ### Pasting Files Use `setClipboardFiles` to enable pasting images from the clipboard. **Example: pasting-files** #### React ```tsx import { FileUpload, useFileUpload } from '@ark-ui/react/file-upload' import { ClipboardIcon, XIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/file-upload.module.css' export const PastingFiles = () => { const fileUpload = useFileUpload({ maxFiles: 3, accept: 'image/*' }) return ( Upload with Paste {#each fileUpload().acceptedFiles as file (file.name)} X {/each} ``` ### Media Capture Use `capture` to access the device camera. Set to `"environment"` for back camera or `"user"` for front camera. **Example: media-capture** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { CameraIcon, FileIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const MediaCapture = () => ( Capture Photo Open Camera {({ acceptedFiles }) => acceptedFiles.map((file) => ( {file.webkitRelativePath || file.name} )) } ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const MediaCapture = () => ( Open Camera {(context) => ( {(file) => ( {file.webkitRelativePath || file.name} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Camera {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} {file.webkitRelativePath ?? file.name} {/each} {/snippet} ``` ### Rejected Files Access `rejectedFiles` from the context to display validation errors. **Example: rejected-files** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { AlertCircleIcon, CheckCircleIcon, UploadIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const RejectedFiles = () => ( { console.log('Rejected files:', details) }} > Upload Files (Max 2)
                    Drop files here Maximum 2 files allowed
                    {({ acceptedFiles, rejectedFiles }) => ( <> {acceptedFiles.length > 0 && (
                    Accepted Files
                    {acceptedFiles.map((file) => ( ))}
                    )} {rejectedFiles.length > 0 && (
                    Rejected Files
                    {rejectedFiles.map(({ file, errors }) => (
                    {errors.map((error, index) => ( {error} ))}
                    ))}
                    )} )}
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid' import { XIcon } from 'lucide-solid' import { For } from 'solid-js' export const RejectedFiles = () => { return ( { console.log(fileRejection) }} > Drag and drop your images here {/* Accepted Files */}

                    Accepted Files

                    {(context) => ( {(file) => ( )} )}
                    {/* Rejected Files */}

                    Rejected Files

                    {(context) => ( {(fileRejection) => ( )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte console.log(fileRejection)}> Drag and drop your images here

                    Accepted Files

                    {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} {/each} {/snippet}

                    Rejected Files

                    {#snippet render(context)} {#each context().rejectedFiles as { file, errors } (file.name)} {errors.join(', ')} {/each} {/snippet}
                    ``` ## Guides ### File Previews Use `ItemPreview` with type matching to show appropriate previews based on file format. - `type="image/*"`: Shows image thumbnails using `ItemPreviewImage` - `type="video/*"`: For video file previews - `type="application/pdf"`: For PDF files - `type=".*"`: Generic fallback for any file type ```tsx ``` ### Disable Dropzone To disable drag-and-drop functionality, set `allowDrop` to `false`. ```tsx {/* ... */} ``` ### Prevent Document Drop By default, we prevent accidental navigation when files are dropped outside the dropzone. Set `preventDocumentDrop` to `false` to disable this. ```tsx {/* ... */} ``` ### Prevent Double Open Use `disableClick` on `Dropzone` when delegating clicks to a nested `Trigger`. This prevents the file picker from opening twice. ```tsx Choose Files Drag files here ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `accept` | `Record | FileMimeType | FileMimeType[]` | No | The accept file types | | `acceptedFiles` | `File[]` | No | The controlled accepted files | | `allowDrop` | `boolean` | No | Whether to allow drag and drop in the dropzone element | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `capture` | `'user' | 'environment'` | No | The default camera to use when capturing media | | `defaultAcceptedFiles` | `File[]` | No | The default accepted files when rendered. Use when you don't need to control the accepted files of the input. | | `directory` | `boolean` | No | Whether to accept directories, only works in webkit browsers | | `disabled` | `boolean` | No | Whether the file input is disabled | | `ids` | `Partial<{ root: string dropzone: string hiddenInput: string trigger: string label: string item: (id: string) => string itemName: (id: string) => string itemSizeText: (id: string) => string itemPreview: (id: string) => string }>` | No | The ids of the elements. Useful for composition. | | `invalid` | `boolean` | No | Whether the file input is invalid | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `maxFiles` | `number` | No | The maximum number of files | | `maxFileSize` | `number` | No | The maximum file size in bytes | | `minFileSize` | `number` | No | The minimum file size in bytes | | `name` | `string` | No | The name of the underlying file input | | `onFileAccept` | `(details: FileAcceptDetails) => void` | No | Function called when the file is accepted | | `onFileChange` | `(details: FileChangeDetails) => void` | No | Function called when the value changes, whether accepted or rejected | | `onFileReject` | `(details: FileRejectDetails) => void` | No | Function called when the file is rejected | | `preventDocumentDrop` | `boolean` | No | Whether to prevent the drop event on the document | | `required` | `boolean` | No | Whether the file input is required | | `transformFiles` | `(files: File[]) => Promise` | No | Function to transform the accepted files to apply transformations | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `validate` | `(file: File, details: FileValidateDetails) => FileError[] | null` | No | Function to validate a file | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | clear-trigger | | `[data-disabled]` | Present when disabled | **Dropzone Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disableClick` | `boolean` | No | Whether to disable the click event on the dropzone | **Dropzone Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | dropzone | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `ItemType` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemName Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemName Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-name | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreviewImage Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreviewImage Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview-image | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `string` | No | The file type to match against. Matches all file types by default. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `file` | `File` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemSizeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemSizeText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-size-text | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFileUploadReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `accept` | `Record | FileMimeType | FileMimeType[]` | No | The accept file types | | `acceptedFiles` | `File[]` | No | The controlled accepted files | | `allowDrop` | `boolean` | No | Whether to allow drag and drop in the dropzone element | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `capture` | `'user' | 'environment'` | No | The default camera to use when capturing media | | `defaultAcceptedFiles` | `File[]` | No | The default accepted files when rendered. Use when you don't need to control the accepted files of the input. | | `directory` | `boolean` | No | Whether to accept directories, only works in webkit browsers | | `disabled` | `boolean` | No | Whether the file input is disabled | | `ids` | `Partial<{ root: string dropzone: string hiddenInput: string trigger: string label: string item: (id: string) => string itemName: (id: string) => string itemSizeText: (id: string) => string itemPreview: (id: string) => string }>` | No | The ids of the elements. Useful for composition. | | `invalid` | `boolean` | No | Whether the file input is invalid | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `maxFiles` | `number` | No | The maximum number of files | | `maxFileSize` | `number` | No | The maximum file size in bytes | | `minFileSize` | `number` | No | The minimum file size in bytes | | `name` | `string` | No | The name of the underlying file input | | `onFileAccept` | `(details: FileAcceptDetails) => void` | No | Function called when the file is accepted | | `onFileChange` | `(details: FileChangeDetails) => void` | No | Function called when the value changes, whether accepted or rejected | | `onFileReject` | `(details: FileRejectDetails) => void` | No | Function called when the file is rejected | | `preventDocumentDrop` | `boolean` | No | Whether to prevent the drop event on the document | | `required` | `boolean` | No | Whether the file input is required | | `transformFiles` | `(files: File[]) => Promise` | No | Function to transform the accepted files to apply transformations | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `validate` | `(file: File, details: FileValidateDetails) => FileError[] | null` | No | Function to validate a file | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | clear-trigger | | `[data-disabled]` | Present when disabled | **Dropzone Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disableClick` | `boolean` | No | Whether to disable the click event on the dropzone | **Dropzone Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | dropzone | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'ul'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `ItemType` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemName Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemName Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-name | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreviewImage Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'img'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreviewImage Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview-image | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `string` | No | The file type to match against. Matches all file types by default. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `file` | `File` | Yes | | | `asChild` | `(props: ParentProps<'li'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemSizeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemSizeText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-size-text | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFileUploadReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `accept` | `Record | FileMimeType | FileMimeType[]` | No | The accept file types | | `allowDrop` | `boolean` | No | Whether to allow drag and drop in the dropzone element | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `capture` | `'user' | 'environment'` | No | The default camera to use when capturing media | | `defaultAcceptedFiles` | `File[]` | No | The default accepted files | | `directory` | `boolean` | No | Whether to accept directories, only works in webkit browsers | | `disabled` | `boolean` | No | Whether the file input is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string dropzone: string hiddenInput: string trigger: string label: string item(id: string): string itemName(id: string): string itemSizeText(id: string): string itemPreview(id: string): string }>` | No | The ids of the elements. Useful for composition. | | `invalid` | `boolean` | No | Whether the file input is invalid | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `maxFiles` | `number` | No | The maximum number of files | | `maxFileSize` | `number` | No | The maximum file size in bytes | | `minFileSize` | `number` | No | The minimum file size in bytes | | `name` | `string` | No | The name of the underlying file input | | `preventDocumentDrop` | `boolean` | No | Whether to prevent the drop event on the document | | `required` | `boolean` | No | Whether the file input is required | | `transformFiles` | `(files: File[]) => Promise` | No | Function to transform the files | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `validate` | `(file: File, details: FileValidateDetails) => FileError[] | null` | No | Function to validate a file | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | clear-trigger | | `[data-disabled]` | Present when disabled | **Dropzone Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disableClick` | `boolean` | No | Whether to disable the click event on the dropzone | **Dropzone Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | dropzone | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `ItemType` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemName Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemName Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-name | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreviewImage Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreviewImage Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview-image | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `string` | No | The file type to match against. Matches all file types by default. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `file` | `File` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `ItemType` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemSizeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemSizeText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-size-text | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `FileUploadApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `accept` | `Record | FileMimeType | FileMimeType[]` | No | The accept file types | | `acceptedFiles` | `File[]` | No | The controlled accepted files | | `allowDrop` | `boolean` | No | Whether to allow drag and drop in the dropzone element | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `capture` | `'user' | 'environment'` | No | The default camera to use when capturing media | | `defaultAcceptedFiles` | `File[]` | No | The default accepted files when rendered. Use when you don't need to control the accepted files of the input. | | `directory` | `boolean` | No | Whether to accept directories, only works in webkit browsers | | `disabled` | `boolean` | No | Whether the file input is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string dropzone: string hiddenInput: string trigger: string label: string item: (id: string) => string itemName: (id: string) => string itemSizeText: (id: string) => string itemPreview: (id: string) => string }>` | No | The ids of the elements. Useful for composition. | | `invalid` | `boolean` | No | Whether the file input is invalid | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `maxFiles` | `number` | No | The maximum number of files | | `maxFileSize` | `number` | No | The maximum file size in bytes | | `minFileSize` | `number` | No | The minimum file size in bytes | | `name` | `string` | No | The name of the underlying file input | | `onFileAccept` | `(details: FileAcceptDetails) => void` | No | Function called when the file is accepted | | `onFileChange` | `(details: FileChangeDetails) => void` | No | Function called when the value changes, whether accepted or rejected | | `onFileReject` | `(details: FileRejectDetails) => void` | No | Function called when the file is rejected | | `preventDocumentDrop` | `boolean` | No | Whether to prevent the drop event on the document | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the file input is required | | `transformFiles` | `(files: File[]) => Promise` | No | Function to transform the accepted files to apply transformations | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `validate` | `(file: File, details: FileValidateDetails) => FileError[] | null` | No | Function to validate a file | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | clear-trigger | | `[data-disabled]` | Present when disabled | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseFileUploadContext]>` | No | | **Dropzone Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disableClick` | `boolean` | No | Whether to disable the click event on the dropzone | | `ref` | `Element` | No | | **Dropzone Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | dropzone | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `type` | `ItemType` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemName Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemName Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-name | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreviewImage Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'img'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemPreviewImage Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview-image | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `type` | `string` | No | The file type to match against. Matches all file types by default. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `file` | `File` | Yes | | | `asChild` | `Snippet<[PropsFn<'li'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemSizeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemSizeText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-size-text | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFileUploadReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `dragging` | `boolean` | Whether the user is dragging something over the root element | | `focused` | `boolean` | Whether the user is focused on the dropzone element | | `disabled` | `boolean` | Whether the file input is disabled | | `transforming` | `boolean` | Whether files are currently being transformed via `transformFiles` | | `openFilePicker` | `VoidFunction` | Function to open the file dialog | | `deleteFile` | `(file: File, type?: ItemType) => void` | Function to delete the file from the list | | `acceptedFiles` | `File[]` | The accepted files that have been dropped or selected | | `rejectedFiles` | `FileRejection[]` | The files that have been rejected | | `setFiles` | `(files: File[]) => void` | Sets the accepted files | | `clearFiles` | `VoidFunction` | Clears the accepted files | | `clearRejectedFiles` | `VoidFunction` | Clears the rejected files | | `getFileSize` | `(file: File) => string` | Returns the formatted file size (e.g. 1.2MB) | | `createFileUrl` | `(file: File, cb: (url: string) => void) => VoidFunction` | Returns the preview url of a file. Returns a function to revoke the url. | | `setClipboardFiles` | `(dt: DataTransfer) => boolean` | Sets the clipboard files Returns `true` if the clipboard data contains files, `false` otherwise. | --- # File Upload (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { PaperclipIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const Basic = () => ( File Upload Choose file(s) {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) } ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const Basic = () => ( File Upload Choose file(s) {(context) => ( {(file) => ( X )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload Choose file(s) {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} X {/each} {/snippet} ``` ### Initial Files Use the `defaultAcceptedFiles` prop to set the initial files in the file upload component. **Example: initial-files** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { FileIcon, PaperclipIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const InitialFiles = () => ( File Upload Choose file(s) {({ acceptedFiles }) => acceptedFiles.map((file) => (
                    )) }
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const InitialFiles = () => ( File Upload Choose file(s) {(context) => ( {(file) => (
                    📄
                    )}
                    )}
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload Choose file(s) {#snippet render(context)} {#each context().acceptedFiles as file (file.name)}
                    📄
                    {/each} {/snippet}
                    ``` ### Clear Trigger Use the `ClearTrigger` to remove all uploaded files at once. **Example: clear-trigger** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { PaperclipIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const ClearTrigger = () => ( File Upload
                    Choose file(s) Clear Files
                    {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) }
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const ClearTrigger = () => ( File Upload Choose file(s) Clear Files {(context) => ( {(file) => ( )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload Drag your file(s) here Choose file(s) {#snippet render(context)} {#if context().acceptedFiles.length > 0} {/if} {/snippet} {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} X {/each} {/snippet} ``` ### Dropzone Use the `Dropzone` to enable drag-and-drop. It exposes a `data-dragging` attribute for styling. **Example: dropzone** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { FileIcon, UploadIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const Dropzone = () => ( File Upload
                    Drag and drop files here or click to browse
                    {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) }
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const Dropzone = () => ( File Upload Drag and drop files here {(context) => ( {(file) => ( File X )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload Drag and drop files here {#snippet render(fileUpload)} {#each fileUpload().acceptedFiles as file (file.name)} X {/each} {/snippet} ``` ### Directory Upload Use the `directory` prop to upload entire folders. Access file paths through `file.webkitRelativePath`. **Example: directory-upload** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { FileIcon, FolderIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const DirectoryUpload = () => ( Upload Folder Select Folder {({ acceptedFiles }) => acceptedFiles.map((file) => (
                    {file.webkitRelativePath || file.name}
                    )) }
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const DirectoryUpload = () => ( Upload Folder {(fileUpload) => ( {(file) => ( {file.webkitRelativePath ?? file.name} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Upload Folder {#snippet render(fileUpload)} {#each fileUpload().acceptedFiles as file (file.name)} {file.webkitRelativePath ?? file.name} {/each} {/snippet} ``` > 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`). **Example: accepted-file-types** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { AlertCircleIcon, ImageIcon, UploadIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const AcceptedFileTypes = () => ( Upload Images (PNG and JPEG only)
                    Drop your images here Only PNG and JPEG files
                    {({ acceptedFiles, rejectedFiles }) => ( <> {acceptedFiles.length > 0 && ( {acceptedFiles.map((file) => ( ))} )} {rejectedFiles.length > 0 && ( {rejectedFiles.map((fileRejection) => (
                    {fileRejection.errors.map((error) => (
                    {error}
                    ))}
                    ))}
                    )} )}
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const AcceptedFileTypes = () => ( File Upload (PNG and JPEG only) Drop your files here Select Files {(context) => ( {(file) => ( Remove )} )} {(context) => ( {(fileRejection) => (
                    {(error) =>
                    {error}
                    }
                    )}
                    )}
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload (PNG and JPEG only) Drop your files here Select Files {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} Remove {/each} {/snippet} {#snippet render(context)} {#each context().rejectedFiles as fileRejection (fileRejection.file.name)}
                    {#each fileRejection.errors as error}
                    {error}
                    {/each}
                    {/each} {/snippet}
                    ``` ### 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`. **Example: error-handling** #### React ```tsx import { FileUpload, type FileUploadFileError } from '@ark-ui/react/file-upload' import { AlertCircleIcon, CheckCircleIcon, FileIcon, UploadIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' const errorMessages: Record = { TOO_MANY_FILES: 'Too many files selected (max 3 allowed)', FILE_INVALID_TYPE: 'Invalid file type (only images and PDFs allowed)', FILE_TOO_LARGE: 'File too large (max 1MB)', FILE_TOO_SMALL: 'File too small (min 1KB)', FILE_INVALID: 'Invalid file', FILE_EXISTS: 'File already exists', } export const ErrorHandling = () => ( Upload Documents
                    Drop files here Images and PDFs, max 1MB each
                    {({ acceptedFiles, rejectedFiles }) => ( <> {acceptedFiles.length > 0 && (
                    Accepted Files
                    {acceptedFiles.map((file) => ( ))}
                    )} {rejectedFiles.length > 0 && (
                    Rejected Files
                    {rejectedFiles.map((fileRejection) => (
                    {fileRejection.errors.map((error, index) => (
                    {errorMessages[error as FileUploadFileError] || error}
                    ))}
                    ))}
                    )} )}
                    ) ``` #### Solid ```tsx import { FileUpload, type FileUploadFileError } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' const errorMessages: Record = { TOO_MANY_FILES: '📊 Too many files selected (max 3 allowed)', FILE_INVALID_TYPE: '🚫 Invalid file type (only images and PDFs allowed)', FILE_TOO_LARGE: '📏 File too large (max 1MB)', FILE_TOO_SMALL: '📐 File too small (min 1KB)', FILE_INVALID: '⚠️ Invalid file', FILE_EXISTS: '🔄 File already exists', } export const ErrorHandling = () => ( File Upload with Validation Select Files {/* Accepted Files Section */}

                    ✅ Accepted Files

                    {(fileUpload) => fileUpload().acceptedFiles.length === 0 ? (
                    No files uploaded yet
                    ) : ( {(file) => (
                    PDF
                    Remove
                    )}
                    ) }
                    {/* Rejected Files Section */}

                    ❌ Rejected Files

                    {(fileUpload) => fileUpload().rejectedFiles.length === 0 ? (
                    No rejected files
                    ) : ( {(fileRejection) => (
                    Validation Errors: {(error) =>
                    {errorMessages[error] || `❓ ${error}`}
                    }
                    )}
                    ) }
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte File Upload with Validation Select Files

                    ✅ Accepted Files

                    {#snippet render(fileUpload)} {#if fileUpload().acceptedFiles.length === 0}
                    No files uploaded yet
                    {:else} {#each fileUpload().acceptedFiles as file (file.name)}
                    PDF
                    Remove
                    {/each} {/if} {/snippet}

                    ❌ Rejected Files

                    {#snippet render(fileUpload)} {#if fileUpload().rejectedFiles.length === 0}
                    No rejected files
                    {:else} {#each fileUpload().rejectedFiles as fileRejection (fileRejection.file.name)}
                    Validation Errors: {#each fileRejection.errors as error}
                    {errorMessages[error] || `❓ ${error}`}
                    {/each}
                    {/each} {/if} {/snippet}
                    ``` ### File Transformations Use `transformFiles` to process files before they're added. Useful for image compression, format conversion, or resizing. **Example: transform-files** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { compressAccurately } from 'image-conversion' import { ImageIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const TransformFiles = () => { const transformFiles = async (files: File[]) => { return Promise.all( files.map(async (file) => { if (file.type.startsWith('image/')) { try { const blob = await compressAccurately(file, 200) return new File([blob], file.name, { type: blob.type }) } catch (error) { console.error('Compression failed for:', file.name, error) return file } } return file }), ) } return ( Upload with Compression Choose Images {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) } ) } ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { compressAccurately } from 'image-conversion' import { For } from 'solid-js' export const TransformFiles = () => { const transformFiles = async (files: File[]) => { return Promise.all( files.map(async (file) => { if (file.type.startsWith('image/')) { try { const blob = await compressAccurately(file, 200) return new File([blob], file.name, { type: blob.type }) } catch (error) { console.error('Compression failed for:', file.name, error) return file } } return file }), ) } return ( File Upload with Compression Choose Images {(fileUpload) => ( {(file) => ( Remove )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Upload with Compression Choose Images {#snippet render(fileUpload)} {#each fileUpload().acceptedFiles as file (file.name)} X {/each} {/snippet} ``` ### Field Use `Field` to add helper text and error handling. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { FileUpload } from '@ark-ui/react/file-upload' import { FileIcon, UploadIcon, XIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/file-upload.module.css' export const WithField = () => ( Attachments
                    Drop files here or click to browse
                    {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) }
                    Upload up to 5 files Please upload at least one file
                    ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { FileUpload } from '@ark-ui/solid/file-upload' export const WithField = (props: Field.RootProps) => ( Label Select Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Select Additional Info Error Info ``` ### 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. **Example: root-provider** #### React ```tsx import { FileUpload, useFileUpload } from '@ark-ui/react/file-upload' import { FileIcon, UploadIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/file-upload.module.css' export const RootProvider = () => { const fileUpload = useFileUpload({ maxFiles: 5 }) return (
                    File Upload
                    Drop files here or click to browse
                    {({ acceptedFiles }) => acceptedFiles.map((file) => ( )) }
                    ) } ``` #### Solid ```tsx import { FileUpload, useFileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const RootProvider = () => { const fileUpload = useFileUpload({ maxFiles: 5 }) return ( <> File Upload Drag your file(s)here Choose file(s) {(context) => ( {(file) => ( Any Icon X )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    File Upload Drag your file(s) here Choose file(s) {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} X {/each} {/snippet}
                    ``` ### Pasting Files Use `setClipboardFiles` to enable pasting images from the clipboard. **Example: pasting-files** #### React ```tsx import { FileUpload, useFileUpload } from '@ark-ui/react/file-upload' import { ClipboardIcon, XIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/file-upload.module.css' export const PastingFiles = () => { const fileUpload = useFileUpload({ maxFiles: 3, accept: 'image/*' }) return ( Upload with Paste {#each fileUpload().acceptedFiles as file (file.name)} X {/each} ``` ### Media Capture Use `capture` to access the device camera. Set to `"environment"` for back camera or `"user"` for front camera. **Example: media-capture** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { CameraIcon, FileIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const MediaCapture = () => ( Capture Photo Open Camera {({ acceptedFiles }) => acceptedFiles.map((file) => ( {file.webkitRelativePath || file.name} )) } ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid/file-upload' import { For } from 'solid-js' export const MediaCapture = () => ( Open Camera {(context) => ( {(file) => ( {file.webkitRelativePath || file.name} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Camera {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} {file.webkitRelativePath ?? file.name} {/each} {/snippet} ``` ### Rejected Files Access `rejectedFiles` from the context to display validation errors. **Example: rejected-files** #### React ```tsx import { FileUpload } from '@ark-ui/react/file-upload' import { AlertCircleIcon, CheckCircleIcon, UploadIcon, XIcon } from 'lucide-react' import styles from 'styles/file-upload.module.css' export const RejectedFiles = () => ( { console.log('Rejected files:', details) }} > Upload Files (Max 2)
                    Drop files here Maximum 2 files allowed
                    {({ acceptedFiles, rejectedFiles }) => ( <> {acceptedFiles.length > 0 && (
                    Accepted Files
                    {acceptedFiles.map((file) => ( ))}
                    )} {rejectedFiles.length > 0 && (
                    Rejected Files
                    {rejectedFiles.map(({ file, errors }) => (
                    {errors.map((error, index) => ( {error} ))}
                    ))}
                    )} )}
                    ) ``` #### Solid ```tsx import { FileUpload } from '@ark-ui/solid' import { XIcon } from 'lucide-solid' import { For } from 'solid-js' export const RejectedFiles = () => { return ( { console.log(fileRejection) }} > Drag and drop your images here {/* Accepted Files */}

                    Accepted Files

                    {(context) => ( {(file) => ( )} )}
                    {/* Rejected Files */}

                    Rejected Files

                    {(context) => ( {(fileRejection) => ( )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte console.log(fileRejection)}> Drag and drop your images here

                    Accepted Files

                    {#snippet render(context)} {#each context().acceptedFiles as file (file.name)} {/each} {/snippet}

                    Rejected Files

                    {#snippet render(context)} {#each context().rejectedFiles as { file, errors } (file.name)} {errors.join(', ')} {/each} {/snippet}
                    ``` ## Guides ### File Previews Use `ItemPreview` with type matching to show appropriate previews based on file format. - `type="image/*"`: Shows image thumbnails using `ItemPreviewImage` - `type="video/*"`: For video file previews - `type="application/pdf"`: For PDF files - `type=".*"`: Generic fallback for any file type ```tsx ``` ### Disable Dropzone To disable drag-and-drop functionality, set `allowDrop` to `false`. ```tsx {/* ... */} ``` ### Prevent Document Drop By default, we prevent accidental navigation when files are dropped outside the dropzone. Set `preventDocumentDrop` to `false` to disable this. ```tsx {/* ... */} ``` ### Prevent Double Open Use `disableClick` on `Dropzone` when delegating clicks to a nested `Trigger`. This prevents the file picker from opening twice. ```tsx Choose Files Drag files here ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `accept` | `Record | FileMimeType | FileMimeType[]` | No | The accept file types | | `acceptedFiles` | `File[]` | No | The controlled accepted files | | `allowDrop` | `boolean` | No | Whether to allow drag and drop in the dropzone element | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `capture` | `'user' | 'environment'` | No | The default camera to use when capturing media | | `defaultAcceptedFiles` | `File[]` | No | The default accepted files when rendered. Use when you don't need to control the accepted files of the input. | | `directory` | `boolean` | No | Whether to accept directories, only works in webkit browsers | | `disabled` | `boolean` | No | Whether the file input is disabled | | `ids` | `Partial<{ root: string dropzone: string hiddenInput: string trigger: string label: string item: (id: string) => string itemName: (id: string) => string itemSizeText: (id: string) => string itemPreview: (id: string) => string }>` | No | The ids of the elements. Useful for composition. | | `invalid` | `boolean` | No | Whether the file input is invalid | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `maxFiles` | `number` | No | The maximum number of files | | `maxFileSize` | `number` | No | The maximum file size in bytes | | `minFileSize` | `number` | No | The minimum file size in bytes | | `name` | `string` | No | The name of the underlying file input | | `onFileAccept` | `(details: FileAcceptDetails) => void` | No | Function called when the file is accepted | | `onFileChange` | `(details: FileChangeDetails) => void` | No | Function called when the value changes, whether accepted or rejected | | `onFileReject` | `(details: FileRejectDetails) => void` | No | Function called when the file is rejected | | `preventDocumentDrop` | `boolean` | No | Whether to prevent the drop event on the document | | `required` | `boolean` | No | Whether the file input is required | | `transformFiles` | `(files: File[]) => Promise` | No | Function to transform the accepted files to apply transformations | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `validate` | `(file: File, details: FileValidateDetails) => FileError[] | null` | No | Function to validate a file | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | clear-trigger | | `[data-disabled]` | Present when disabled | **Dropzone Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disableClick` | `boolean` | No | Whether to disable the click event on the dropzone | **Dropzone Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | dropzone | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `ItemType` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemName Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemName Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-name | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreviewImage Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreviewImage Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview-image | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `string` | No | The file type to match against. Matches all file types by default. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `file` | `File` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemSizeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemSizeText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-size-text | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFileUploadReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `accept` | `Record | FileMimeType | FileMimeType[]` | No | The accept file types | | `acceptedFiles` | `File[]` | No | The controlled accepted files | | `allowDrop` | `boolean` | No | Whether to allow drag and drop in the dropzone element | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `capture` | `'user' | 'environment'` | No | The default camera to use when capturing media | | `defaultAcceptedFiles` | `File[]` | No | The default accepted files when rendered. Use when you don't need to control the accepted files of the input. | | `directory` | `boolean` | No | Whether to accept directories, only works in webkit browsers | | `disabled` | `boolean` | No | Whether the file input is disabled | | `ids` | `Partial<{ root: string dropzone: string hiddenInput: string trigger: string label: string item: (id: string) => string itemName: (id: string) => string itemSizeText: (id: string) => string itemPreview: (id: string) => string }>` | No | The ids of the elements. Useful for composition. | | `invalid` | `boolean` | No | Whether the file input is invalid | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `maxFiles` | `number` | No | The maximum number of files | | `maxFileSize` | `number` | No | The maximum file size in bytes | | `minFileSize` | `number` | No | The minimum file size in bytes | | `name` | `string` | No | The name of the underlying file input | | `onFileAccept` | `(details: FileAcceptDetails) => void` | No | Function called when the file is accepted | | `onFileChange` | `(details: FileChangeDetails) => void` | No | Function called when the value changes, whether accepted or rejected | | `onFileReject` | `(details: FileRejectDetails) => void` | No | Function called when the file is rejected | | `preventDocumentDrop` | `boolean` | No | Whether to prevent the drop event on the document | | `required` | `boolean` | No | Whether the file input is required | | `transformFiles` | `(files: File[]) => Promise` | No | Function to transform the accepted files to apply transformations | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `validate` | `(file: File, details: FileValidateDetails) => FileError[] | null` | No | Function to validate a file | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | clear-trigger | | `[data-disabled]` | Present when disabled | **Dropzone Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disableClick` | `boolean` | No | Whether to disable the click event on the dropzone | **Dropzone Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | dropzone | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'ul'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `ItemType` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemName Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemName Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-name | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreviewImage Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'img'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreviewImage Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview-image | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `string` | No | The file type to match against. Matches all file types by default. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `file` | `File` | Yes | | | `asChild` | `(props: ParentProps<'li'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemSizeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemSizeText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-size-text | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFileUploadReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `accept` | `Record | FileMimeType | FileMimeType[]` | No | The accept file types | | `allowDrop` | `boolean` | No | Whether to allow drag and drop in the dropzone element | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `capture` | `'user' | 'environment'` | No | The default camera to use when capturing media | | `defaultAcceptedFiles` | `File[]` | No | The default accepted files | | `directory` | `boolean` | No | Whether to accept directories, only works in webkit browsers | | `disabled` | `boolean` | No | Whether the file input is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string dropzone: string hiddenInput: string trigger: string label: string item(id: string): string itemName(id: string): string itemSizeText(id: string): string itemPreview(id: string): string }>` | No | The ids of the elements. Useful for composition. | | `invalid` | `boolean` | No | Whether the file input is invalid | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `maxFiles` | `number` | No | The maximum number of files | | `maxFileSize` | `number` | No | The maximum file size in bytes | | `minFileSize` | `number` | No | The minimum file size in bytes | | `name` | `string` | No | The name of the underlying file input | | `preventDocumentDrop` | `boolean` | No | Whether to prevent the drop event on the document | | `required` | `boolean` | No | Whether the file input is required | | `transformFiles` | `(files: File[]) => Promise` | No | Function to transform the files | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `validate` | `(file: File, details: FileValidateDetails) => FileError[] | null` | No | Function to validate a file | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | clear-trigger | | `[data-disabled]` | Present when disabled | **Dropzone Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disableClick` | `boolean` | No | Whether to disable the click event on the dropzone | **Dropzone Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | dropzone | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `ItemType` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemName Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemName Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-name | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreviewImage Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreviewImage Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview-image | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `string` | No | The file type to match against. Matches all file types by default. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `file` | `File` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `type` | `ItemType` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemSizeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemSizeText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-size-text | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `FileUploadApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `accept` | `Record | FileMimeType | FileMimeType[]` | No | The accept file types | | `acceptedFiles` | `File[]` | No | The controlled accepted files | | `allowDrop` | `boolean` | No | Whether to allow drag and drop in the dropzone element | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `capture` | `'user' | 'environment'` | No | The default camera to use when capturing media | | `defaultAcceptedFiles` | `File[]` | No | The default accepted files when rendered. Use when you don't need to control the accepted files of the input. | | `directory` | `boolean` | No | Whether to accept directories, only works in webkit browsers | | `disabled` | `boolean` | No | Whether the file input is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string dropzone: string hiddenInput: string trigger: string label: string item: (id: string) => string itemName: (id: string) => string itemSizeText: (id: string) => string itemPreview: (id: string) => string }>` | No | The ids of the elements. Useful for composition. | | `invalid` | `boolean` | No | Whether the file input is invalid | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `maxFiles` | `number` | No | The maximum number of files | | `maxFileSize` | `number` | No | The maximum file size in bytes | | `minFileSize` | `number` | No | The minimum file size in bytes | | `name` | `string` | No | The name of the underlying file input | | `onFileAccept` | `(details: FileAcceptDetails) => void` | No | Function called when the file is accepted | | `onFileChange` | `(details: FileChangeDetails) => void` | No | Function called when the value changes, whether accepted or rejected | | `onFileReject` | `(details: FileRejectDetails) => void` | No | Function called when the file is rejected | | `preventDocumentDrop` | `boolean` | No | Whether to prevent the drop event on the document | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the file input is required | | `transformFiles` | `(files: File[]) => Promise` | No | Function to transform the accepted files to apply transformations | | `translations` | `IntlTranslations` | No | The localized messages to use. | | `validate` | `(file: File, details: FileValidateDetails) => FileError[] | null` | No | Function to validate a file | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | clear-trigger | | `[data-disabled]` | Present when disabled | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseFileUploadContext]>` | No | | **Dropzone Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disableClick` | `boolean` | No | Whether to disable the click event on the dropzone | | `ref` | `Element` | No | | **Dropzone Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | dropzone | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-dragging]` | Present when in the dragging state | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `type` | `ItemType` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemName Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemName Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-name | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreviewImage Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'img'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemPreviewImage Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview-image | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | | `type` | `string` | No | The file type to match against. Matches all file types by default. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-preview | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `file` | `File` | Yes | | | `asChild` | `Snippet<[PropsFn<'li'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **ItemSizeText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemSizeText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | item-size-text | | `[data-disabled]` | Present when disabled | | `[data-type]` | The type of the item | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFileUploadReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | file-upload | | `[data-part]` | trigger | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `dragging` | `boolean` | Whether the user is dragging something over the root element | | `focused` | `boolean` | Whether the user is focused on the dropzone element | | `disabled` | `boolean` | Whether the file input is disabled | | `transforming` | `boolean` | Whether files are currently being transformed via `transformFiles` | | `openFilePicker` | `VoidFunction` | Function to open the file dialog | | `deleteFile` | `(file: File, type?: ItemType) => void` | Function to delete the file from the list | | `acceptedFiles` | `File[]` | The accepted files that have been dropped or selected | | `rejectedFiles` | `FileRejection[]` | The files that have been rejected | | `setFiles` | `(files: File[]) => void` | Sets the accepted files | | `clearFiles` | `VoidFunction` | Clears the accepted files | | `clearRejectedFiles` | `VoidFunction` | Clears the rejected files | | `getFileSize` | `(file: File) => string` | Returns the formatted file size (e.g. 1.2MB) | | `createFileUrl` | `(file: File, cb: (url: string) => void) => VoidFunction` | Returns the preview url of a file. Returns a function to revoke the url. | | `setClipboardFiles` | `(dt: DataTransfer) => boolean` | Sets the clipboard files Returns `true` if the clipboard data contains files, `false` otherwise. | --- # Floating Panel (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import styles from 'styles/floating-panel.module.css' export const Basic = () => ( Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const Basic = () => ( Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel Floating Panel

                    Some content

                    ``` ### Controlled size To control the size of the floating panel programmatically, you can pass the `size` `onResize` prop to the machine. **Example: controlled-size** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/floating-panel.module.css' export const ControlledSize = () => { const [size, setSize] = useState({ width: 400, height: 300 }) return ( setSize(e.size)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const ControlledSize = () => { const [size, setSize] = createSignal({ width: 400, height: 300 }) return ( setSize(e.size)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel Floating Panel

                    Some content

                    ``` ### Controlled position To control the position of the floating panel programmatically, you can pass the `position` and `onPositionChange` prop to the machine. **Example: controlled-position** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/floating-panel.module.css' export const ControlledPosition = () => { const [position, setPosition] = useState({ x: 200, y: 200 }) return ( setPosition(e.position)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const ControlledPosition = () => { const [position, setPosition] = createSignal({ x: 200, y: 200 }) return ( setPosition(e.position)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel Floating Panel

                    Some content

                    Position: x={position.x}, y={position.y}

                    ``` ### 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`. **Example: anchor-position** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import styles from 'styles/floating-panel.module.css' export const AnchorPosition = () => ( { if (!triggerRect) return { x: 0, y: 0 } return { x: triggerRect.x + triggerRect.width / 2, y: triggerRect.y + triggerRect.height / 2, } }} > Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const AnchorPosition = () => ( { if (!triggerRect) return { x: 0, y: 0 } return { x: triggerRect.x + triggerRect.width / 2, y: triggerRect.y + triggerRect.height / 2, } }} > Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte { if (!triggerRect) return { x: 0, y: 0 } return { x: triggerRect.x + triggerRect.width / 2, y: triggerRect.y + triggerRect.height / 2, } }} > Toggle Panel Floating Panel

                    Some content

                    Anchored to trigger center

                    ``` ### Open State To control the open state of the floating panel programmatically, you can pass the `open` and `onOpenChange` prop to the machine. **Example: controlled-open** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/floating-panel.module.css' export const ControlledOpen = () => { const [open, setOpen] = useState(false) return ( setOpen(e.open)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const ControlledOpen = () => { const [open, setOpen] = createSignal(false) return ( setOpen(e.open)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel Floating Panel

                    Some content

                    Panel is {open ? 'open' : 'closed'}

                    ``` ### Lazy Mount To lazy mount the floating panel, you can pass the `lazyMount` prop to the machine. **Example: lazy-mount** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import styles from 'styles/floating-panel.module.css' export const LazyMount = () => ( console.log('onExitComplete invoked')}> Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const LazyMount = () => ( console.log('onExitComplete invoked')}> Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte console.log('onExitComplete invoked')}> Toggle Panel Floating Panel

                    Some content

                    ``` ### Context To access the context of the floating panel, you can use the `useFloatingPanelContext` hook or the `FloatingPanel.Context` component. **Example: context** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import styles from 'styles/floating-panel.module.css' export const Context = () => ( Toggle Panel {(floatingPanel) =>

                    floatingPanel is {floatingPanel.open ? 'open' : 'closed'}

                    }
                    Floating Panel

                    Some content

                    ) ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const Context = () => ( Toggle Panel {(floatingPanel) =>

                    floatingPanel is {floatingPanel().open ? 'open' : 'closed'}

                    }
                    Floating Panel

                    Some content

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel {#snippet render(floatingPanel)}

                    floatingPanel is {floatingPanel().open ? 'open' : 'closed'}

                    {/snippet}
                    Floating Panel

                    Some content

                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowOverflow` | `boolean` | No | Whether the panel should be strictly contained within the boundary when dragging | | `closeOnEscape` | `boolean` | No | Whether the panel should close when the escape key is pressed | | `defaultOpen` | `boolean` | No | The initial open state of the panel when rendered. Use when you don't need to control the open state of the panel. | | `defaultPosition` | `Point` | No | The initial position of the panel when rendered. Use when you don't need to control the position of the panel. | | `defaultSize` | `Size` | No | The default size of the panel | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the panel is disabled | | `draggable` | `boolean` | No | Whether the panel is draggable | | `getAnchorPosition` | `(details: AnchorPositionDetails) => Point` | No | Function that returns the initial position of the panel when it is opened. If provided, will be used instead of the default position. | | `getBoundaryEl` | `() => HTMLElement | null` | No | The boundary of the panel. Useful for recalculating the boundary rect when the it is resized. | | `gridSize` | `number` | No | The snap grid for the panel | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; positioner: string; content: string; title: string; header: string }>` | No | The ids of the elements in the floating panel. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `lockAspectRatio` | `boolean` | No | Whether the panel is locked to its aspect ratio | | `maxSize` | `Size` | No | The maximum size of the panel | | `minSize` | `Size` | No | The minimum size of the panel | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the panel is opened or closed | | `onPositionChange` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging | | `onPositionChangeEnd` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging ends | | `onSizeChange` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing | | `onSizeChangeEnd` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing ends | | `onStageChange` | `(details: StageChangeDetails) => void` | No | Function called when the stage of the panel changes | | `open` | `boolean` | No | The controlled open state of the panel | | `persistRect` | `boolean` | No | Whether the panel size and position should be preserved when it is closed | | `position` | `Point` | No | The controlled position of the panel | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `resizable` | `boolean` | No | Whether the panel is resizable | | `size` | `Size` | No | The size of the panel | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `strategy` | `'absolute' | 'fixed'` | No | The strategy to use for positioning | | `translations` | `IntlTranslations` | No | The translations for the floating panel. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Body Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Body Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | body | | `[data-dragging]` | Present when in the dragging state | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-stage]` | The stage of the control | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **DragTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DragTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | drag-trigger | | `[data-disabled]` | Present when disabled | **Header Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Header Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | header | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--width` | The width of the element | | `--height` | The height of the element | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `ResizeTriggerAxis` | Yes | The axis of the resize handle | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | resize-trigger | | `[data-disabled]` | Present when disabled | | `[data-axis]` | The axis to resize | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFloatingPanelReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **StageTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `stage` | `Stage` | Yes | The stage of the panel | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowOverflow` | `boolean` | No | Whether the panel should be strictly contained within the boundary when dragging | | `closeOnEscape` | `boolean` | No | Whether the panel should close when the escape key is pressed | | `defaultOpen` | `boolean` | No | The initial open state of the panel when rendered. Use when you don't need to control the open state of the panel. | | `defaultPosition` | `Point` | No | The initial position of the panel when rendered. Use when you don't need to control the position of the panel. | | `defaultSize` | `Size` | No | The default size of the panel | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the panel is disabled | | `draggable` | `boolean` | No | Whether the panel is draggable | | `getAnchorPosition` | `(details: AnchorPositionDetails) => Point` | No | Function that returns the initial position of the panel when it is opened. If provided, will be used instead of the default position. | | `getBoundaryEl` | `() => HTMLElement | null` | No | The boundary of the panel. Useful for recalculating the boundary rect when the it is resized. | | `gridSize` | `number` | No | The snap grid for the panel | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; positioner: string; content: string; title: string; header: string }>` | No | The ids of the elements in the floating panel. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `lockAspectRatio` | `boolean` | No | Whether the panel is locked to its aspect ratio | | `maxSize` | `Size` | No | The maximum size of the panel | | `minSize` | `Size` | No | The minimum size of the panel | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the panel is opened or closed | | `onPositionChange` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging | | `onPositionChangeEnd` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging ends | | `onSizeChange` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing | | `onSizeChangeEnd` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing ends | | `onStageChange` | `(details: StageChangeDetails) => void` | No | Function called when the stage of the panel changes | | `open` | `boolean` | No | The controlled open state of the panel | | `persistRect` | `boolean` | No | Whether the panel size and position should be preserved when it is closed | | `position` | `Point` | No | The controlled position of the panel | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `resizable` | `boolean` | No | Whether the panel is resizable | | `size` | `Size` | No | The size of the panel | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `strategy` | `'absolute' | 'fixed'` | No | The strategy to use for positioning | | `translations` | `IntlTranslations` | No | The translations for the floating panel. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Body Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Body Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | body | | `[data-dragging]` | Present when in the dragging state | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-stage]` | The stage of the control | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **DragTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DragTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | drag-trigger | | `[data-disabled]` | Present when disabled | **Header Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Header Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | header | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--width` | The width of the element | | `--height` | The height of the element | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `ResizeTriggerAxis` | Yes | The axis of the resize handle | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | resize-trigger | | `[data-disabled]` | Present when disabled | | `[data-axis]` | The axis to resize | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFloatingPanelReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **StageTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `stage` | `Stage` | Yes | The stage of the panel | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'h2'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowOverflow` | `boolean` | No | Whether the panel should be strictly contained within the boundary when dragging | | `closeOnEscape` | `boolean` | No | Whether the panel should close when the escape key is pressed | | `defaultOpen` | `boolean` | No | The initial open state of the panel when rendered. Use when you don't need to control the open state of the panel. | | `defaultPosition` | `Point` | No | The initial position of the panel when rendered. Use when you don't need to control the position of the panel. | | `defaultSize` | `Size` | No | The default size of the panel | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the panel is disabled | | `draggable` | `boolean` | No | Whether the panel is draggable | | `getAnchorPosition` | `(details: AnchorPositionDetails) => Point` | No | Function that returns the initial position of the panel when it is opened. If provided, will be used instead of the default position. | | `getBoundaryEl` | `() => HTMLElement | null` | No | The boundary of the panel. Useful for recalculating the boundary rect when the it is resized. | | `gridSize` | `number` | No | The snap grid for the panel | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; positioner: string; content: string; title: string; header: string }>` | No | The ids of the elements in the floating panel. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `lockAspectRatio` | `boolean` | No | Whether the panel is locked to its aspect ratio | | `maxSize` | `Size` | No | The maximum size of the panel | | `minSize` | `Size` | No | The minimum size of the panel | | `open` | `boolean` | No | The controlled open state of the panel | | `persistRect` | `boolean` | No | Whether the panel size and position should be preserved when it is closed | | `position` | `Point` | No | The controlled position of the panel | | `resizable` | `boolean` | No | Whether the panel is resizable | | `size` | `Size` | No | The size of the panel | | `strategy` | `'absolute' | 'fixed'` | No | The strategy to use for positioning | | `translations` | `IntlTranslations` | No | The translations for the floating panel. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Body Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Body Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | body | | `[data-dragging]` | Present when in the dragging state | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-stage]` | The stage of the control | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **DragTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DragTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | drag-trigger | | `[data-disabled]` | Present when disabled | **Header Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Header Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | header | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--width` | The width of the element | | `--height` | The height of the element | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `ResizeTriggerAxis` | Yes | The axis of the resize handle | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | resize-trigger | | `[data-disabled]` | Present when disabled | | `[data-axis]` | The axis to resize | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `FloatingPanelApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **StageTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `stage` | `Stage` | Yes | The stage of the panel | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowOverflow` | `boolean` | No | Whether the panel should be strictly contained within the boundary when dragging | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnEscape` | `boolean` | No | Whether the panel should close when the escape key is pressed | | `defaultOpen` | `boolean` | No | The initial open state of the panel when rendered. Use when you don't need to control the open state of the panel. | | `defaultPosition` | `Point` | No | The initial position of the panel when rendered. Use when you don't need to control the position of the panel. | | `defaultSize` | `Size` | No | The default size of the panel | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the panel is disabled | | `draggable` | `boolean` | No | Whether the panel is draggable | | `getAnchorPosition` | `(details: AnchorPositionDetails) => Point` | No | Function that returns the initial position of the panel when it is opened. If provided, will be used instead of the default position. | | `getBoundaryEl` | `() => HTMLElement | null` | No | The boundary of the panel. Useful for recalculating the boundary rect when the it is resized. | | `gridSize` | `number` | No | The snap grid for the panel | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; positioner: string; content: string; title: string; header: string }>` | No | The ids of the elements in the floating panel. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `lockAspectRatio` | `boolean` | No | Whether the panel is locked to its aspect ratio | | `maxSize` | `Size` | No | The maximum size of the panel | | `minSize` | `Size` | No | The minimum size of the panel | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the panel is opened or closed | | `onPositionChange` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging | | `onPositionChangeEnd` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging ends | | `onSizeChange` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing | | `onSizeChangeEnd` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing ends | | `onStageChange` | `(details: StageChangeDetails) => void` | No | Function called when the stage of the panel changes | | `open` | `boolean` | No | The controlled open state of the panel | | `persistRect` | `boolean` | No | Whether the panel size and position should be preserved when it is closed | | `position` | `Point` | No | The controlled position of the panel | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `resizable` | `boolean` | No | Whether the panel is resizable | | `size` | `Size` | No | The size of the panel | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `strategy` | `'absolute' | 'fixed'` | No | The strategy to use for positioning | | `translations` | `IntlTranslations` | No | The translations for the floating panel. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Body Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Body Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | body | | `[data-dragging]` | Present when in the dragging state | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseFloatingPanelContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-stage]` | The stage of the control | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **DragTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **DragTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | drag-trigger | | `[data-disabled]` | Present when disabled | **Header Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Header Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | header | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--width` | The width of the element | | `--height` | The height of the element | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `ResizeTriggerAxis` | Yes | The axis of the resize handle | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | resize-trigger | | `[data-disabled]` | Present when disabled | | `[data-axis]` | The axis to resize | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFloatingPanelReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **StageTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `stage` | `Stage` | Yes | The stage of the panel | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the panel is open | | `setOpen` | `(open: boolean) => void` | Function to open or close the panel | | `dragging` | `boolean` | Whether the panel is being dragged | | `resizing` | `boolean` | Whether the panel is being resized | | `position` | `Point` | The position of the panel | | `setPosition` | `(position: Point) => void` | Function to set the position of the panel | | `size` | `Size` | The size of the panel | | `setSize` | `(size: Size) => void` | Function to set the size of the panel | | `minimize` | `VoidFunction` | Function to minimize the panel | | `maximize` | `VoidFunction` | Function to maximize the panel | | `restore` | `VoidFunction` | Function to restore the panel before it was minimized or maximized | | `resizable` | `boolean` | Whether the panel is resizable | | `draggable` | `boolean` | Whether the panel is draggable | --- # Floating Panel (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import styles from 'styles/floating-panel.module.css' export const Basic = () => ( Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const Basic = () => ( Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel Floating Panel

                    Some content

                    ``` ### Controlled size To control the size of the floating panel programmatically, you can pass the `size` `onResize` prop to the machine. **Example: controlled-size** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/floating-panel.module.css' export const ControlledSize = () => { const [size, setSize] = useState({ width: 400, height: 300 }) return ( setSize(e.size)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const ControlledSize = () => { const [size, setSize] = createSignal({ width: 400, height: 300 }) return ( setSize(e.size)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel Floating Panel

                    Some content

                    ``` ### Controlled position To control the position of the floating panel programmatically, you can pass the `position` and `onPositionChange` prop to the machine. **Example: controlled-position** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/floating-panel.module.css' export const ControlledPosition = () => { const [position, setPosition] = useState({ x: 200, y: 200 }) return ( setPosition(e.position)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const ControlledPosition = () => { const [position, setPosition] = createSignal({ x: 200, y: 200 }) return ( setPosition(e.position)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel Floating Panel

                    Some content

                    Position: x={position.x}, y={position.y}

                    ``` ### 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`. **Example: anchor-position** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import styles from 'styles/floating-panel.module.css' export const AnchorPosition = () => ( { if (!triggerRect) return { x: 0, y: 0 } return { x: triggerRect.x + triggerRect.width / 2, y: triggerRect.y + triggerRect.height / 2, } }} > Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const AnchorPosition = () => ( { if (!triggerRect) return { x: 0, y: 0 } return { x: triggerRect.x + triggerRect.width / 2, y: triggerRect.y + triggerRect.height / 2, } }} > Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte { if (!triggerRect) return { x: 0, y: 0 } return { x: triggerRect.x + triggerRect.width / 2, y: triggerRect.y + triggerRect.height / 2, } }} > Toggle Panel Floating Panel

                    Some content

                    Anchored to trigger center

                    ``` ### Open State To control the open state of the floating panel programmatically, you can pass the `open` and `onOpenChange` prop to the machine. **Example: controlled-open** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/floating-panel.module.css' export const ControlledOpen = () => { const [open, setOpen] = useState(false) return ( setOpen(e.open)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const ControlledOpen = () => { const [open, setOpen] = createSignal(false) return ( setOpen(e.open)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel Floating Panel

                    Some content

                    Panel is {open ? 'open' : 'closed'}

                    ``` ### Lazy Mount To lazy mount the floating panel, you can pass the `lazyMount` prop to the machine. **Example: lazy-mount** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import styles from 'styles/floating-panel.module.css' export const LazyMount = () => ( console.log('onExitComplete invoked')}> Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const LazyMount = () => ( console.log('onExitComplete invoked')}> Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte console.log('onExitComplete invoked')}> Toggle Panel Floating Panel

                    Some content

                    ``` ### Context To access the context of the floating panel, you can use the `useFloatingPanelContext` hook or the `FloatingPanel.Context` component. **Example: context** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import styles from 'styles/floating-panel.module.css' export const Context = () => ( Toggle Panel {(floatingPanel) =>

                    floatingPanel is {floatingPanel.open ? 'open' : 'closed'}

                    }
                    Floating Panel

                    Some content

                    ) ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const Context = () => ( Toggle Panel {(floatingPanel) =>

                    floatingPanel is {floatingPanel().open ? 'open' : 'closed'}

                    }
                    Floating Panel

                    Some content

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel {#snippet render(floatingPanel)}

                    floatingPanel is {floatingPanel().open ? 'open' : 'closed'}

                    {/snippet}
                    Floating Panel

                    Some content

                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowOverflow` | `boolean` | No | Whether the panel should be strictly contained within the boundary when dragging | | `closeOnEscape` | `boolean` | No | Whether the panel should close when the escape key is pressed | | `defaultOpen` | `boolean` | No | The initial open state of the panel when rendered. Use when you don't need to control the open state of the panel. | | `defaultPosition` | `Point` | No | The initial position of the panel when rendered. Use when you don't need to control the position of the panel. | | `defaultSize` | `Size` | No | The default size of the panel | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the panel is disabled | | `draggable` | `boolean` | No | Whether the panel is draggable | | `getAnchorPosition` | `(details: AnchorPositionDetails) => Point` | No | Function that returns the initial position of the panel when it is opened. If provided, will be used instead of the default position. | | `getBoundaryEl` | `() => HTMLElement | null` | No | The boundary of the panel. Useful for recalculating the boundary rect when the it is resized. | | `gridSize` | `number` | No | The snap grid for the panel | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; positioner: string; content: string; title: string; header: string }>` | No | The ids of the elements in the floating panel. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `lockAspectRatio` | `boolean` | No | Whether the panel is locked to its aspect ratio | | `maxSize` | `Size` | No | The maximum size of the panel | | `minSize` | `Size` | No | The minimum size of the panel | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the panel is opened or closed | | `onPositionChange` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging | | `onPositionChangeEnd` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging ends | | `onSizeChange` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing | | `onSizeChangeEnd` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing ends | | `onStageChange` | `(details: StageChangeDetails) => void` | No | Function called when the stage of the panel changes | | `open` | `boolean` | No | The controlled open state of the panel | | `persistRect` | `boolean` | No | Whether the panel size and position should be preserved when it is closed | | `position` | `Point` | No | The controlled position of the panel | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `resizable` | `boolean` | No | Whether the panel is resizable | | `size` | `Size` | No | The size of the panel | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `strategy` | `'absolute' | 'fixed'` | No | The strategy to use for positioning | | `translations` | `IntlTranslations` | No | The translations for the floating panel. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Body Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Body Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | body | | `[data-dragging]` | Present when in the dragging state | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-stage]` | The stage of the control | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **DragTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DragTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | drag-trigger | | `[data-disabled]` | Present when disabled | **Header Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Header Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | header | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--width` | The width of the element | | `--height` | The height of the element | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `ResizeTriggerAxis` | Yes | The axis of the resize handle | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | resize-trigger | | `[data-disabled]` | Present when disabled | | `[data-axis]` | The axis to resize | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFloatingPanelReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **StageTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `stage` | `Stage` | Yes | The stage of the panel | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowOverflow` | `boolean` | No | Whether the panel should be strictly contained within the boundary when dragging | | `closeOnEscape` | `boolean` | No | Whether the panel should close when the escape key is pressed | | `defaultOpen` | `boolean` | No | The initial open state of the panel when rendered. Use when you don't need to control the open state of the panel. | | `defaultPosition` | `Point` | No | The initial position of the panel when rendered. Use when you don't need to control the position of the panel. | | `defaultSize` | `Size` | No | The default size of the panel | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the panel is disabled | | `draggable` | `boolean` | No | Whether the panel is draggable | | `getAnchorPosition` | `(details: AnchorPositionDetails) => Point` | No | Function that returns the initial position of the panel when it is opened. If provided, will be used instead of the default position. | | `getBoundaryEl` | `() => HTMLElement | null` | No | The boundary of the panel. Useful for recalculating the boundary rect when the it is resized. | | `gridSize` | `number` | No | The snap grid for the panel | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; positioner: string; content: string; title: string; header: string }>` | No | The ids of the elements in the floating panel. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `lockAspectRatio` | `boolean` | No | Whether the panel is locked to its aspect ratio | | `maxSize` | `Size` | No | The maximum size of the panel | | `minSize` | `Size` | No | The minimum size of the panel | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the panel is opened or closed | | `onPositionChange` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging | | `onPositionChangeEnd` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging ends | | `onSizeChange` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing | | `onSizeChangeEnd` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing ends | | `onStageChange` | `(details: StageChangeDetails) => void` | No | Function called when the stage of the panel changes | | `open` | `boolean` | No | The controlled open state of the panel | | `persistRect` | `boolean` | No | Whether the panel size and position should be preserved when it is closed | | `position` | `Point` | No | The controlled position of the panel | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `resizable` | `boolean` | No | Whether the panel is resizable | | `size` | `Size` | No | The size of the panel | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `strategy` | `'absolute' | 'fixed'` | No | The strategy to use for positioning | | `translations` | `IntlTranslations` | No | The translations for the floating panel. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Body Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Body Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | body | | `[data-dragging]` | Present when in the dragging state | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-stage]` | The stage of the control | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **DragTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DragTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | drag-trigger | | `[data-disabled]` | Present when disabled | **Header Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Header Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | header | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--width` | The width of the element | | `--height` | The height of the element | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `ResizeTriggerAxis` | Yes | The axis of the resize handle | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | resize-trigger | | `[data-disabled]` | Present when disabled | | `[data-axis]` | The axis to resize | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFloatingPanelReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **StageTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `stage` | `Stage` | Yes | The stage of the panel | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'h2'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowOverflow` | `boolean` | No | Whether the panel should be strictly contained within the boundary when dragging | | `closeOnEscape` | `boolean` | No | Whether the panel should close when the escape key is pressed | | `defaultOpen` | `boolean` | No | The initial open state of the panel when rendered. Use when you don't need to control the open state of the panel. | | `defaultPosition` | `Point` | No | The initial position of the panel when rendered. Use when you don't need to control the position of the panel. | | `defaultSize` | `Size` | No | The default size of the panel | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the panel is disabled | | `draggable` | `boolean` | No | Whether the panel is draggable | | `getAnchorPosition` | `(details: AnchorPositionDetails) => Point` | No | Function that returns the initial position of the panel when it is opened. If provided, will be used instead of the default position. | | `getBoundaryEl` | `() => HTMLElement | null` | No | The boundary of the panel. Useful for recalculating the boundary rect when the it is resized. | | `gridSize` | `number` | No | The snap grid for the panel | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; positioner: string; content: string; title: string; header: string }>` | No | The ids of the elements in the floating panel. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `lockAspectRatio` | `boolean` | No | Whether the panel is locked to its aspect ratio | | `maxSize` | `Size` | No | The maximum size of the panel | | `minSize` | `Size` | No | The minimum size of the panel | | `open` | `boolean` | No | The controlled open state of the panel | | `persistRect` | `boolean` | No | Whether the panel size and position should be preserved when it is closed | | `position` | `Point` | No | The controlled position of the panel | | `resizable` | `boolean` | No | Whether the panel is resizable | | `size` | `Size` | No | The size of the panel | | `strategy` | `'absolute' | 'fixed'` | No | The strategy to use for positioning | | `translations` | `IntlTranslations` | No | The translations for the floating panel. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Body Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Body Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | body | | `[data-dragging]` | Present when in the dragging state | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-stage]` | The stage of the control | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **DragTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DragTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | drag-trigger | | `[data-disabled]` | Present when disabled | **Header Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Header Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | header | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--width` | The width of the element | | `--height` | The height of the element | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `ResizeTriggerAxis` | Yes | The axis of the resize handle | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | resize-trigger | | `[data-disabled]` | Present when disabled | | `[data-axis]` | The axis to resize | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `FloatingPanelApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **StageTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `stage` | `Stage` | Yes | The stage of the panel | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowOverflow` | `boolean` | No | Whether the panel should be strictly contained within the boundary when dragging | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnEscape` | `boolean` | No | Whether the panel should close when the escape key is pressed | | `defaultOpen` | `boolean` | No | The initial open state of the panel when rendered. Use when you don't need to control the open state of the panel. | | `defaultPosition` | `Point` | No | The initial position of the panel when rendered. Use when you don't need to control the position of the panel. | | `defaultSize` | `Size` | No | The default size of the panel | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the panel is disabled | | `draggable` | `boolean` | No | Whether the panel is draggable | | `getAnchorPosition` | `(details: AnchorPositionDetails) => Point` | No | Function that returns the initial position of the panel when it is opened. If provided, will be used instead of the default position. | | `getBoundaryEl` | `() => HTMLElement | null` | No | The boundary of the panel. Useful for recalculating the boundary rect when the it is resized. | | `gridSize` | `number` | No | The snap grid for the panel | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; positioner: string; content: string; title: string; header: string }>` | No | The ids of the elements in the floating panel. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `lockAspectRatio` | `boolean` | No | Whether the panel is locked to its aspect ratio | | `maxSize` | `Size` | No | The maximum size of the panel | | `minSize` | `Size` | No | The minimum size of the panel | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the panel is opened or closed | | `onPositionChange` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging | | `onPositionChangeEnd` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging ends | | `onSizeChange` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing | | `onSizeChangeEnd` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing ends | | `onStageChange` | `(details: StageChangeDetails) => void` | No | Function called when the stage of the panel changes | | `open` | `boolean` | No | The controlled open state of the panel | | `persistRect` | `boolean` | No | Whether the panel size and position should be preserved when it is closed | | `position` | `Point` | No | The controlled position of the panel | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `resizable` | `boolean` | No | Whether the panel is resizable | | `size` | `Size` | No | The size of the panel | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `strategy` | `'absolute' | 'fixed'` | No | The strategy to use for positioning | | `translations` | `IntlTranslations` | No | The translations for the floating panel. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Body Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Body Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | body | | `[data-dragging]` | Present when in the dragging state | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseFloatingPanelContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-stage]` | The stage of the control | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **DragTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **DragTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | drag-trigger | | `[data-disabled]` | Present when disabled | **Header Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Header Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | header | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--width` | The width of the element | | `--height` | The height of the element | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `ResizeTriggerAxis` | Yes | The axis of the resize handle | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | resize-trigger | | `[data-disabled]` | Present when disabled | | `[data-axis]` | The axis to resize | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFloatingPanelReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **StageTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `stage` | `Stage` | Yes | The stage of the panel | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the panel is open | | `setOpen` | `(open: boolean) => void` | Function to open or close the panel | | `dragging` | `boolean` | Whether the panel is being dragged | | `resizing` | `boolean` | Whether the panel is being resized | | `position` | `Point` | The position of the panel | | `setPosition` | `(position: Point) => void` | Function to set the position of the panel | | `size` | `Size` | The size of the panel | | `setSize` | `(size: Size) => void` | Function to set the size of the panel | | `minimize` | `VoidFunction` | Function to minimize the panel | | `maximize` | `VoidFunction` | Function to maximize the panel | | `restore` | `VoidFunction` | Function to restore the panel before it was minimized or maximized | | `resizable` | `boolean` | Whether the panel is resizable | | `draggable` | `boolean` | Whether the panel is draggable | --- # Floating Panel (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import styles from 'styles/floating-panel.module.css' export const Basic = () => ( Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const Basic = () => ( Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel Floating Panel

                    Some content

                    ``` ### Controlled size To control the size of the floating panel programmatically, you can pass the `size` `onResize` prop to the machine. **Example: controlled-size** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/floating-panel.module.css' export const ControlledSize = () => { const [size, setSize] = useState({ width: 400, height: 300 }) return ( setSize(e.size)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const ControlledSize = () => { const [size, setSize] = createSignal({ width: 400, height: 300 }) return ( setSize(e.size)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel Floating Panel

                    Some content

                    ``` ### Controlled position To control the position of the floating panel programmatically, you can pass the `position` and `onPositionChange` prop to the machine. **Example: controlled-position** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/floating-panel.module.css' export const ControlledPosition = () => { const [position, setPosition] = useState({ x: 200, y: 200 }) return ( setPosition(e.position)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const ControlledPosition = () => { const [position, setPosition] = createSignal({ x: 200, y: 200 }) return ( setPosition(e.position)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel Floating Panel

                    Some content

                    Position: x={position.x}, y={position.y}

                    ``` ### 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`. **Example: anchor-position** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import styles from 'styles/floating-panel.module.css' export const AnchorPosition = () => ( { if (!triggerRect) return { x: 0, y: 0 } return { x: triggerRect.x + triggerRect.width / 2, y: triggerRect.y + triggerRect.height / 2, } }} > Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const AnchorPosition = () => ( { if (!triggerRect) return { x: 0, y: 0 } return { x: triggerRect.x + triggerRect.width / 2, y: triggerRect.y + triggerRect.height / 2, } }} > Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte { if (!triggerRect) return { x: 0, y: 0 } return { x: triggerRect.x + triggerRect.width / 2, y: triggerRect.y + triggerRect.height / 2, } }} > Toggle Panel Floating Panel

                    Some content

                    Anchored to trigger center

                    ``` ### Open State To control the open state of the floating panel programmatically, you can pass the `open` and `onOpenChange` prop to the machine. **Example: controlled-open** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/floating-panel.module.css' export const ControlledOpen = () => { const [open, setOpen] = useState(false) return ( setOpen(e.open)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const ControlledOpen = () => { const [open, setOpen] = createSignal(false) return ( setOpen(e.open)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel Floating Panel

                    Some content

                    Panel is {open ? 'open' : 'closed'}

                    ``` ### Lazy Mount To lazy mount the floating panel, you can pass the `lazyMount` prop to the machine. **Example: lazy-mount** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import styles from 'styles/floating-panel.module.css' export const LazyMount = () => ( console.log('onExitComplete invoked')}> Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const LazyMount = () => ( console.log('onExitComplete invoked')}> Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte console.log('onExitComplete invoked')}> Toggle Panel Floating Panel

                    Some content

                    ``` ### Context To access the context of the floating panel, you can use the `useFloatingPanelContext` hook or the `FloatingPanel.Context` component. **Example: context** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import styles from 'styles/floating-panel.module.css' export const Context = () => ( Toggle Panel {(floatingPanel) =>

                    floatingPanel is {floatingPanel.open ? 'open' : 'closed'}

                    }
                    Floating Panel

                    Some content

                    ) ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const Context = () => ( Toggle Panel {(floatingPanel) =>

                    floatingPanel is {floatingPanel().open ? 'open' : 'closed'}

                    }
                    Floating Panel

                    Some content

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel {#snippet render(floatingPanel)}

                    floatingPanel is {floatingPanel().open ? 'open' : 'closed'}

                    {/snippet}
                    Floating Panel

                    Some content

                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowOverflow` | `boolean` | No | Whether the panel should be strictly contained within the boundary when dragging | | `closeOnEscape` | `boolean` | No | Whether the panel should close when the escape key is pressed | | `defaultOpen` | `boolean` | No | The initial open state of the panel when rendered. Use when you don't need to control the open state of the panel. | | `defaultPosition` | `Point` | No | The initial position of the panel when rendered. Use when you don't need to control the position of the panel. | | `defaultSize` | `Size` | No | The default size of the panel | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the panel is disabled | | `draggable` | `boolean` | No | Whether the panel is draggable | | `getAnchorPosition` | `(details: AnchorPositionDetails) => Point` | No | Function that returns the initial position of the panel when it is opened. If provided, will be used instead of the default position. | | `getBoundaryEl` | `() => HTMLElement | null` | No | The boundary of the panel. Useful for recalculating the boundary rect when the it is resized. | | `gridSize` | `number` | No | The snap grid for the panel | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; positioner: string; content: string; title: string; header: string }>` | No | The ids of the elements in the floating panel. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `lockAspectRatio` | `boolean` | No | Whether the panel is locked to its aspect ratio | | `maxSize` | `Size` | No | The maximum size of the panel | | `minSize` | `Size` | No | The minimum size of the panel | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the panel is opened or closed | | `onPositionChange` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging | | `onPositionChangeEnd` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging ends | | `onSizeChange` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing | | `onSizeChangeEnd` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing ends | | `onStageChange` | `(details: StageChangeDetails) => void` | No | Function called when the stage of the panel changes | | `open` | `boolean` | No | The controlled open state of the panel | | `persistRect` | `boolean` | No | Whether the panel size and position should be preserved when it is closed | | `position` | `Point` | No | The controlled position of the panel | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `resizable` | `boolean` | No | Whether the panel is resizable | | `size` | `Size` | No | The size of the panel | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `strategy` | `'absolute' | 'fixed'` | No | The strategy to use for positioning | | `translations` | `IntlTranslations` | No | The translations for the floating panel. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Body Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Body Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | body | | `[data-dragging]` | Present when in the dragging state | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-stage]` | The stage of the control | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **DragTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DragTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | drag-trigger | | `[data-disabled]` | Present when disabled | **Header Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Header Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | header | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--width` | The width of the element | | `--height` | The height of the element | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `ResizeTriggerAxis` | Yes | The axis of the resize handle | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | resize-trigger | | `[data-disabled]` | Present when disabled | | `[data-axis]` | The axis to resize | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFloatingPanelReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **StageTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `stage` | `Stage` | Yes | The stage of the panel | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowOverflow` | `boolean` | No | Whether the panel should be strictly contained within the boundary when dragging | | `closeOnEscape` | `boolean` | No | Whether the panel should close when the escape key is pressed | | `defaultOpen` | `boolean` | No | The initial open state of the panel when rendered. Use when you don't need to control the open state of the panel. | | `defaultPosition` | `Point` | No | The initial position of the panel when rendered. Use when you don't need to control the position of the panel. | | `defaultSize` | `Size` | No | The default size of the panel | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the panel is disabled | | `draggable` | `boolean` | No | Whether the panel is draggable | | `getAnchorPosition` | `(details: AnchorPositionDetails) => Point` | No | Function that returns the initial position of the panel when it is opened. If provided, will be used instead of the default position. | | `getBoundaryEl` | `() => HTMLElement | null` | No | The boundary of the panel. Useful for recalculating the boundary rect when the it is resized. | | `gridSize` | `number` | No | The snap grid for the panel | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; positioner: string; content: string; title: string; header: string }>` | No | The ids of the elements in the floating panel. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `lockAspectRatio` | `boolean` | No | Whether the panel is locked to its aspect ratio | | `maxSize` | `Size` | No | The maximum size of the panel | | `minSize` | `Size` | No | The minimum size of the panel | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the panel is opened or closed | | `onPositionChange` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging | | `onPositionChangeEnd` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging ends | | `onSizeChange` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing | | `onSizeChangeEnd` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing ends | | `onStageChange` | `(details: StageChangeDetails) => void` | No | Function called when the stage of the panel changes | | `open` | `boolean` | No | The controlled open state of the panel | | `persistRect` | `boolean` | No | Whether the panel size and position should be preserved when it is closed | | `position` | `Point` | No | The controlled position of the panel | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `resizable` | `boolean` | No | Whether the panel is resizable | | `size` | `Size` | No | The size of the panel | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `strategy` | `'absolute' | 'fixed'` | No | The strategy to use for positioning | | `translations` | `IntlTranslations` | No | The translations for the floating panel. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Body Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Body Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | body | | `[data-dragging]` | Present when in the dragging state | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-stage]` | The stage of the control | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **DragTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DragTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | drag-trigger | | `[data-disabled]` | Present when disabled | **Header Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Header Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | header | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--width` | The width of the element | | `--height` | The height of the element | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `ResizeTriggerAxis` | Yes | The axis of the resize handle | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | resize-trigger | | `[data-disabled]` | Present when disabled | | `[data-axis]` | The axis to resize | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFloatingPanelReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **StageTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `stage` | `Stage` | Yes | The stage of the panel | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'h2'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowOverflow` | `boolean` | No | Whether the panel should be strictly contained within the boundary when dragging | | `closeOnEscape` | `boolean` | No | Whether the panel should close when the escape key is pressed | | `defaultOpen` | `boolean` | No | The initial open state of the panel when rendered. Use when you don't need to control the open state of the panel. | | `defaultPosition` | `Point` | No | The initial position of the panel when rendered. Use when you don't need to control the position of the panel. | | `defaultSize` | `Size` | No | The default size of the panel | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the panel is disabled | | `draggable` | `boolean` | No | Whether the panel is draggable | | `getAnchorPosition` | `(details: AnchorPositionDetails) => Point` | No | Function that returns the initial position of the panel when it is opened. If provided, will be used instead of the default position. | | `getBoundaryEl` | `() => HTMLElement | null` | No | The boundary of the panel. Useful for recalculating the boundary rect when the it is resized. | | `gridSize` | `number` | No | The snap grid for the panel | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; positioner: string; content: string; title: string; header: string }>` | No | The ids of the elements in the floating panel. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `lockAspectRatio` | `boolean` | No | Whether the panel is locked to its aspect ratio | | `maxSize` | `Size` | No | The maximum size of the panel | | `minSize` | `Size` | No | The minimum size of the panel | | `open` | `boolean` | No | The controlled open state of the panel | | `persistRect` | `boolean` | No | Whether the panel size and position should be preserved when it is closed | | `position` | `Point` | No | The controlled position of the panel | | `resizable` | `boolean` | No | Whether the panel is resizable | | `size` | `Size` | No | The size of the panel | | `strategy` | `'absolute' | 'fixed'` | No | The strategy to use for positioning | | `translations` | `IntlTranslations` | No | The translations for the floating panel. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Body Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Body Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | body | | `[data-dragging]` | Present when in the dragging state | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-stage]` | The stage of the control | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **DragTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DragTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | drag-trigger | | `[data-disabled]` | Present when disabled | **Header Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Header Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | header | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--width` | The width of the element | | `--height` | The height of the element | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `ResizeTriggerAxis` | Yes | The axis of the resize handle | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | resize-trigger | | `[data-disabled]` | Present when disabled | | `[data-axis]` | The axis to resize | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `FloatingPanelApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **StageTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `stage` | `Stage` | Yes | The stage of the panel | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowOverflow` | `boolean` | No | Whether the panel should be strictly contained within the boundary when dragging | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnEscape` | `boolean` | No | Whether the panel should close when the escape key is pressed | | `defaultOpen` | `boolean` | No | The initial open state of the panel when rendered. Use when you don't need to control the open state of the panel. | | `defaultPosition` | `Point` | No | The initial position of the panel when rendered. Use when you don't need to control the position of the panel. | | `defaultSize` | `Size` | No | The default size of the panel | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the panel is disabled | | `draggable` | `boolean` | No | Whether the panel is draggable | | `getAnchorPosition` | `(details: AnchorPositionDetails) => Point` | No | Function that returns the initial position of the panel when it is opened. If provided, will be used instead of the default position. | | `getBoundaryEl` | `() => HTMLElement | null` | No | The boundary of the panel. Useful for recalculating the boundary rect when the it is resized. | | `gridSize` | `number` | No | The snap grid for the panel | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; positioner: string; content: string; title: string; header: string }>` | No | The ids of the elements in the floating panel. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `lockAspectRatio` | `boolean` | No | Whether the panel is locked to its aspect ratio | | `maxSize` | `Size` | No | The maximum size of the panel | | `minSize` | `Size` | No | The minimum size of the panel | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the panel is opened or closed | | `onPositionChange` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging | | `onPositionChangeEnd` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging ends | | `onSizeChange` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing | | `onSizeChangeEnd` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing ends | | `onStageChange` | `(details: StageChangeDetails) => void` | No | Function called when the stage of the panel changes | | `open` | `boolean` | No | The controlled open state of the panel | | `persistRect` | `boolean` | No | Whether the panel size and position should be preserved when it is closed | | `position` | `Point` | No | The controlled position of the panel | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `resizable` | `boolean` | No | Whether the panel is resizable | | `size` | `Size` | No | The size of the panel | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `strategy` | `'absolute' | 'fixed'` | No | The strategy to use for positioning | | `translations` | `IntlTranslations` | No | The translations for the floating panel. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Body Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Body Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | body | | `[data-dragging]` | Present when in the dragging state | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseFloatingPanelContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-stage]` | The stage of the control | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **DragTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **DragTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | drag-trigger | | `[data-disabled]` | Present when disabled | **Header Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Header Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | header | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--width` | The width of the element | | `--height` | The height of the element | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `ResizeTriggerAxis` | Yes | The axis of the resize handle | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | resize-trigger | | `[data-disabled]` | Present when disabled | | `[data-axis]` | The axis to resize | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFloatingPanelReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **StageTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `stage` | `Stage` | Yes | The stage of the panel | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the panel is open | | `setOpen` | `(open: boolean) => void` | Function to open or close the panel | | `dragging` | `boolean` | Whether the panel is being dragged | | `resizing` | `boolean` | Whether the panel is being resized | | `position` | `Point` | The position of the panel | | `setPosition` | `(position: Point) => void` | Function to set the position of the panel | | `size` | `Size` | The size of the panel | | `setSize` | `(size: Size) => void` | Function to set the size of the panel | | `minimize` | `VoidFunction` | Function to minimize the panel | | `maximize` | `VoidFunction` | Function to maximize the panel | | `restore` | `VoidFunction` | Function to restore the panel before it was minimized or maximized | | `resizable` | `boolean` | Whether the panel is resizable | | `draggable` | `boolean` | Whether the panel is draggable | --- # Floating Panel (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import styles from 'styles/floating-panel.module.css' export const Basic = () => ( Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const Basic = () => ( Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel Floating Panel

                    Some content

                    ``` ### Controlled size To control the size of the floating panel programmatically, you can pass the `size` `onResize` prop to the machine. **Example: controlled-size** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/floating-panel.module.css' export const ControlledSize = () => { const [size, setSize] = useState({ width: 400, height: 300 }) return ( setSize(e.size)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const ControlledSize = () => { const [size, setSize] = createSignal({ width: 400, height: 300 }) return ( setSize(e.size)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel Floating Panel

                    Some content

                    ``` ### Controlled position To control the position of the floating panel programmatically, you can pass the `position` and `onPositionChange` prop to the machine. **Example: controlled-position** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/floating-panel.module.css' export const ControlledPosition = () => { const [position, setPosition] = useState({ x: 200, y: 200 }) return ( setPosition(e.position)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const ControlledPosition = () => { const [position, setPosition] = createSignal({ x: 200, y: 200 }) return ( setPosition(e.position)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel Floating Panel

                    Some content

                    Position: x={position.x}, y={position.y}

                    ``` ### 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`. **Example: anchor-position** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import styles from 'styles/floating-panel.module.css' export const AnchorPosition = () => ( { if (!triggerRect) return { x: 0, y: 0 } return { x: triggerRect.x + triggerRect.width / 2, y: triggerRect.y + triggerRect.height / 2, } }} > Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const AnchorPosition = () => ( { if (!triggerRect) return { x: 0, y: 0 } return { x: triggerRect.x + triggerRect.width / 2, y: triggerRect.y + triggerRect.height / 2, } }} > Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte { if (!triggerRect) return { x: 0, y: 0 } return { x: triggerRect.x + triggerRect.width / 2, y: triggerRect.y + triggerRect.height / 2, } }} > Toggle Panel Floating Panel

                    Some content

                    Anchored to trigger center

                    ``` ### Open State To control the open state of the floating panel programmatically, you can pass the `open` and `onOpenChange` prop to the machine. **Example: controlled-open** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/floating-panel.module.css' export const ControlledOpen = () => { const [open, setOpen] = useState(false) return ( setOpen(e.open)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const ControlledOpen = () => { const [open, setOpen] = createSignal(false) return ( setOpen(e.open)}> Toggle Panel Floating Panel

                    Some content

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel Floating Panel

                    Some content

                    Panel is {open ? 'open' : 'closed'}

                    ``` ### Lazy Mount To lazy mount the floating panel, you can pass the `lazyMount` prop to the machine. **Example: lazy-mount** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import styles from 'styles/floating-panel.module.css' export const LazyMount = () => ( console.log('onExitComplete invoked')}> Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const LazyMount = () => ( console.log('onExitComplete invoked')}> Toggle Panel Floating Panel

                    Some content

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte console.log('onExitComplete invoked')}> Toggle Panel Floating Panel

                    Some content

                    ``` ### Context To access the context of the floating panel, you can use the `useFloatingPanelContext` hook or the `FloatingPanel.Context` component. **Example: context** #### React ```tsx import { FloatingPanel } from '@ark-ui/react/floating-panel' import { Portal } from '@ark-ui/react/portal' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-react' import styles from 'styles/floating-panel.module.css' export const Context = () => ( Toggle Panel {(floatingPanel) =>

                    floatingPanel is {floatingPanel.open ? 'open' : 'closed'}

                    }
                    Floating Panel

                    Some content

                    ) ``` #### Solid ```tsx import { FloatingPanel } from '@ark-ui/solid/floating-panel' import { ArrowDownLeft, GripVertical, Maximize2, Minus, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/floating-panel.module.css' export const Context = () => ( Toggle Panel {(floatingPanel) =>

                    floatingPanel is {floatingPanel().open ? 'open' : 'closed'}

                    }
                    Floating Panel

                    Some content

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Panel {#snippet render(floatingPanel)}

                    floatingPanel is {floatingPanel().open ? 'open' : 'closed'}

                    {/snippet}
                    Floating Panel

                    Some content

                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowOverflow` | `boolean` | No | Whether the panel should be strictly contained within the boundary when dragging | | `closeOnEscape` | `boolean` | No | Whether the panel should close when the escape key is pressed | | `defaultOpen` | `boolean` | No | The initial open state of the panel when rendered. Use when you don't need to control the open state of the panel. | | `defaultPosition` | `Point` | No | The initial position of the panel when rendered. Use when you don't need to control the position of the panel. | | `defaultSize` | `Size` | No | The default size of the panel | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the panel is disabled | | `draggable` | `boolean` | No | Whether the panel is draggable | | `getAnchorPosition` | `(details: AnchorPositionDetails) => Point` | No | Function that returns the initial position of the panel when it is opened. If provided, will be used instead of the default position. | | `getBoundaryEl` | `() => HTMLElement | null` | No | The boundary of the panel. Useful for recalculating the boundary rect when the it is resized. | | `gridSize` | `number` | No | The snap grid for the panel | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; positioner: string; content: string; title: string; header: string }>` | No | The ids of the elements in the floating panel. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `lockAspectRatio` | `boolean` | No | Whether the panel is locked to its aspect ratio | | `maxSize` | `Size` | No | The maximum size of the panel | | `minSize` | `Size` | No | The minimum size of the panel | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the panel is opened or closed | | `onPositionChange` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging | | `onPositionChangeEnd` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging ends | | `onSizeChange` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing | | `onSizeChangeEnd` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing ends | | `onStageChange` | `(details: StageChangeDetails) => void` | No | Function called when the stage of the panel changes | | `open` | `boolean` | No | The controlled open state of the panel | | `persistRect` | `boolean` | No | Whether the panel size and position should be preserved when it is closed | | `position` | `Point` | No | The controlled position of the panel | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `resizable` | `boolean` | No | Whether the panel is resizable | | `size` | `Size` | No | The size of the panel | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `strategy` | `'absolute' | 'fixed'` | No | The strategy to use for positioning | | `translations` | `IntlTranslations` | No | The translations for the floating panel. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Body Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Body Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | body | | `[data-dragging]` | Present when in the dragging state | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-stage]` | The stage of the control | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **DragTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DragTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | drag-trigger | | `[data-disabled]` | Present when disabled | **Header Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Header Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | header | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--width` | The width of the element | | `--height` | The height of the element | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `ResizeTriggerAxis` | Yes | The axis of the resize handle | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | resize-trigger | | `[data-disabled]` | Present when disabled | | `[data-axis]` | The axis to resize | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFloatingPanelReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **StageTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `stage` | `Stage` | Yes | The stage of the panel | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowOverflow` | `boolean` | No | Whether the panel should be strictly contained within the boundary when dragging | | `closeOnEscape` | `boolean` | No | Whether the panel should close when the escape key is pressed | | `defaultOpen` | `boolean` | No | The initial open state of the panel when rendered. Use when you don't need to control the open state of the panel. | | `defaultPosition` | `Point` | No | The initial position of the panel when rendered. Use when you don't need to control the position of the panel. | | `defaultSize` | `Size` | No | The default size of the panel | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the panel is disabled | | `draggable` | `boolean` | No | Whether the panel is draggable | | `getAnchorPosition` | `(details: AnchorPositionDetails) => Point` | No | Function that returns the initial position of the panel when it is opened. If provided, will be used instead of the default position. | | `getBoundaryEl` | `() => HTMLElement | null` | No | The boundary of the panel. Useful for recalculating the boundary rect when the it is resized. | | `gridSize` | `number` | No | The snap grid for the panel | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; positioner: string; content: string; title: string; header: string }>` | No | The ids of the elements in the floating panel. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `lockAspectRatio` | `boolean` | No | Whether the panel is locked to its aspect ratio | | `maxSize` | `Size` | No | The maximum size of the panel | | `minSize` | `Size` | No | The minimum size of the panel | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the panel is opened or closed | | `onPositionChange` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging | | `onPositionChangeEnd` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging ends | | `onSizeChange` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing | | `onSizeChangeEnd` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing ends | | `onStageChange` | `(details: StageChangeDetails) => void` | No | Function called when the stage of the panel changes | | `open` | `boolean` | No | The controlled open state of the panel | | `persistRect` | `boolean` | No | Whether the panel size and position should be preserved when it is closed | | `position` | `Point` | No | The controlled position of the panel | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `resizable` | `boolean` | No | Whether the panel is resizable | | `size` | `Size` | No | The size of the panel | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `strategy` | `'absolute' | 'fixed'` | No | The strategy to use for positioning | | `translations` | `IntlTranslations` | No | The translations for the floating panel. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Body Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Body Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | body | | `[data-dragging]` | Present when in the dragging state | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-stage]` | The stage of the control | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **DragTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DragTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | drag-trigger | | `[data-disabled]` | Present when disabled | **Header Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Header Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | header | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--width` | The width of the element | | `--height` | The height of the element | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `ResizeTriggerAxis` | Yes | The axis of the resize handle | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | resize-trigger | | `[data-disabled]` | Present when disabled | | `[data-axis]` | The axis to resize | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFloatingPanelReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **StageTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `stage` | `Stage` | Yes | The stage of the panel | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'h2'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowOverflow` | `boolean` | No | Whether the panel should be strictly contained within the boundary when dragging | | `closeOnEscape` | `boolean` | No | Whether the panel should close when the escape key is pressed | | `defaultOpen` | `boolean` | No | The initial open state of the panel when rendered. Use when you don't need to control the open state of the panel. | | `defaultPosition` | `Point` | No | The initial position of the panel when rendered. Use when you don't need to control the position of the panel. | | `defaultSize` | `Size` | No | The default size of the panel | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the panel is disabled | | `draggable` | `boolean` | No | Whether the panel is draggable | | `getAnchorPosition` | `(details: AnchorPositionDetails) => Point` | No | Function that returns the initial position of the panel when it is opened. If provided, will be used instead of the default position. | | `getBoundaryEl` | `() => HTMLElement | null` | No | The boundary of the panel. Useful for recalculating the boundary rect when the it is resized. | | `gridSize` | `number` | No | The snap grid for the panel | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; positioner: string; content: string; title: string; header: string }>` | No | The ids of the elements in the floating panel. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `lockAspectRatio` | `boolean` | No | Whether the panel is locked to its aspect ratio | | `maxSize` | `Size` | No | The maximum size of the panel | | `minSize` | `Size` | No | The minimum size of the panel | | `open` | `boolean` | No | The controlled open state of the panel | | `persistRect` | `boolean` | No | Whether the panel size and position should be preserved when it is closed | | `position` | `Point` | No | The controlled position of the panel | | `resizable` | `boolean` | No | Whether the panel is resizable | | `size` | `Size` | No | The size of the panel | | `strategy` | `'absolute' | 'fixed'` | No | The strategy to use for positioning | | `translations` | `IntlTranslations` | No | The translations for the floating panel. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Body Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Body Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | body | | `[data-dragging]` | Present when in the dragging state | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-stage]` | The stage of the control | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **DragTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DragTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | drag-trigger | | `[data-disabled]` | Present when disabled | **Header Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Header Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | header | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--width` | The width of the element | | `--height` | The height of the element | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `ResizeTriggerAxis` | Yes | The axis of the resize handle | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | resize-trigger | | `[data-disabled]` | Present when disabled | | `[data-axis]` | The axis to resize | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `FloatingPanelApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **StageTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `stage` | `Stage` | Yes | The stage of the panel | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowOverflow` | `boolean` | No | Whether the panel should be strictly contained within the boundary when dragging | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnEscape` | `boolean` | No | Whether the panel should close when the escape key is pressed | | `defaultOpen` | `boolean` | No | The initial open state of the panel when rendered. Use when you don't need to control the open state of the panel. | | `defaultPosition` | `Point` | No | The initial position of the panel when rendered. Use when you don't need to control the position of the panel. | | `defaultSize` | `Size` | No | The default size of the panel | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the panel is disabled | | `draggable` | `boolean` | No | Whether the panel is draggable | | `getAnchorPosition` | `(details: AnchorPositionDetails) => Point` | No | Function that returns the initial position of the panel when it is opened. If provided, will be used instead of the default position. | | `getBoundaryEl` | `() => HTMLElement | null` | No | The boundary of the panel. Useful for recalculating the boundary rect when the it is resized. | | `gridSize` | `number` | No | The snap grid for the panel | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; positioner: string; content: string; title: string; header: string }>` | No | The ids of the elements in the floating panel. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `lockAspectRatio` | `boolean` | No | Whether the panel is locked to its aspect ratio | | `maxSize` | `Size` | No | The maximum size of the panel | | `minSize` | `Size` | No | The minimum size of the panel | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the panel is opened or closed | | `onPositionChange` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging | | `onPositionChangeEnd` | `(details: PositionChangeDetails) => void` | No | Function called when the position of the panel changes via dragging ends | | `onSizeChange` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing | | `onSizeChangeEnd` | `(details: SizeChangeDetails) => void` | No | Function called when the size of the panel changes via resizing ends | | `onStageChange` | `(details: StageChangeDetails) => void` | No | Function called when the stage of the panel changes | | `open` | `boolean` | No | The controlled open state of the panel | | `persistRect` | `boolean` | No | Whether the panel size and position should be preserved when it is closed | | `position` | `Point` | No | The controlled position of the panel | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `resizable` | `boolean` | No | Whether the panel is resizable | | `size` | `Size` | No | The size of the panel | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `strategy` | `'absolute' | 'fixed'` | No | The strategy to use for positioning | | `translations` | `IntlTranslations` | No | The translations for the floating panel. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Body Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Body Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | body | | `[data-dragging]` | Present when in the dragging state | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseFloatingPanelContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-stage]` | The stage of the control | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **DragTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **DragTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | drag-trigger | | `[data-disabled]` | Present when disabled | **Header Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Header Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | header | | `[data-dragging]` | Present when in the dragging state | | `[data-topmost]` | Present when topmost | | `[data-behind]` | Present when not topmost | | `[data-minimized]` | Present when minimized | | `[data-maximized]` | Present when maximized | | `[data-staged]` | Present when not in default stage | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--width` | The width of the element | | `--height` | The height of the element | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `ResizeTriggerAxis` | Yes | The axis of the resize handle | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | resize-trigger | | `[data-disabled]` | Present when disabled | | `[data-axis]` | The axis to resize | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseFloatingPanelReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **StageTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `stage` | `Stage` | Yes | The stage of the panel | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | floating-panel | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-dragging]` | Present when in the dragging state | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the panel is open | | `setOpen` | `(open: boolean) => void` | Function to open or close the panel | | `dragging` | `boolean` | Whether the panel is being dragged | | `resizing` | `boolean` | Whether the panel is being resized | | `position` | `Point` | The position of the panel | | `setPosition` | `(position: Point) => void` | Function to set the position of the panel | | `size` | `Size` | The size of the panel | | `setSize` | `(size: Size) => void` | Function to set the size of the panel | | `minimize` | `VoidFunction` | Function to minimize the panel | | `maximize` | `VoidFunction` | Function to maximize the panel | | `restore` | `VoidFunction` | Function to restore the panel before it was minimized or maximized | | `resizable` | `boolean` | Whether the panel is resizable | | `draggable` | `boolean` | Whether the panel is draggable | --- # Hover Card (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/hover-card.module.css' export const Basic = () => (

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc. Building beautiful interfaces and design systems.

                    2,456 Following
                    14.5K Followers
                    ) ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const Basic = () => (

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc. Building beautiful interfaces and design systems.

                    2,456 Following
                    14.5K Followers
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc. Building beautiful interfaces and design systems.

                    2,456 Following
                    14.5K Followers
                    ``` ### Controlled The controlled `HoverCard` component provides an interface for managing the state of the hover card using the `open` and `onOpenChange` props: **Example: controlled** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/hover-card.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return (
                    setOpen(e.open)}>

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) } ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/hover-card.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return (
                    setOpen(e.open)}>

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ### 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. **Example: root-provider** #### React ```tsx import { HoverCard, useHoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/hover-card.module.css' export const RootProvider = () => { const hoverCard = useHoverCard() return (
                    Open: {String(hoverCard.open)}

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) } ``` #### Solid ```tsx import { HoverCard, useHoverCard } from '@ark-ui/solid/hover-card' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const RootProvider = () => { const hoverCard = useHoverCard() return (
                    Open: {String(hoverCard().open)}

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Open: {String(hoverCard().open)}

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ### Delay Control the open and close delay of the hover card using the `openDelay` and `closeDelay` props: **Example: delay** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/hover-card.module.css' export const Delay = () => (

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const Delay = () => (

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ### Positioning The `HoverCard` component can be customized in its placement and distance from the trigger element through the `positioning` prop: **Example: positioning** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/hover-card.module.css' export const Positioning = () => (

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const Positioning = () => (

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ### Context Use the `Context` component to access the hover card's state and methods from within the component tree: **Example: context** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/hover-card.module.css' export const Context = () => ( {(context) => (

                    Liked by{' '} @sarah_chen {context.open ? : } {' '} and 3 others

                    )}
                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const Context = () => ( {(context) => (

                    Liked by{' '} ( @sarah_chen {context().open ? : } )} />{' '} and 3 others

                    )}
                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(context)}

                    Liked by {#snippet asChild(props)} @sarah_chen {#if context().open} {:else} {/if} {/snippet} and 3 others

                    {/snippet}
                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `closeDelay` | `number` | No | The duration from when the mouse leaves the trigger or content until the hover card closes. | | `defaultOpen` | `boolean` | No | The initial open state of the hover card when rendered. Use when you don't need to control the open state of the hover card. | | `disabled` | `boolean` | No | Whether the hover card is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; positioner: string; arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the hover card opens or closes. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `open` | `boolean` | No | The controlled open state of the hover card | | `openDelay` | `number` | No | The duration from when the mouse enters the trigger until the hover card opens. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested hover-cards | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseHoverCardReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `closeDelay` | `number` | No | The duration from when the mouse leaves the trigger or content until the hover card closes. | | `defaultOpen` | `boolean` | No | The initial open state of the hover card when rendered. Use when you don't need to control the open state of the hover card. | | `disabled` | `boolean` | No | Whether the hover card is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; positioner: string; arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the hover card opens or closes. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `open` | `boolean` | No | The controlled open state of the hover card | | `openDelay` | `number` | No | The duration from when the mouse enters the trigger until the hover card opens. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested hover-cards | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseHoverCardReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `closeDelay` | `number` | No | The duration from when the mouse leaves the trigger or content until the hover card closes. | | `defaultOpen` | `boolean` | No | The initial open state of the hover card when rendered. Use when you don't need to control the open state of the hover card. | | `disabled` | `boolean` | No | Whether the hover card is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; positioner: string; arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `open` | `boolean` | No | The controlled open state of the hover card | | `openDelay` | `number` | No | The duration from when the mouse enters the trigger until the hover card opens. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested hover-cards | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `HoverCardApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `closeDelay` | `number` | No | The duration from when the mouse leaves the trigger or content until the hover card closes. | | `defaultOpen` | `boolean` | No | The initial open state of the hover card when rendered. Use when you don't need to control the open state of the hover card. | | `disabled` | `boolean` | No | Whether the hover card is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; positioner: string; arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the hover card opens or closes. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `open` | `boolean` | No | The controlled open state of the hover card | | `openDelay` | `number` | No | The duration from when the mouse enters the trigger until the hover card opens. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested hover-cards | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseHoverCardContext]>` | Yes | | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseHoverCardReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the hover card is open | | `setOpen` | `(open: boolean) => void` | Function to open the hover card | | `reposition` | `(options?: Partial) => void` | Function to reposition the popover | --- # Hover Card (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/hover-card.module.css' export const Basic = () => (

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc. Building beautiful interfaces and design systems.

                    2,456 Following
                    14.5K Followers
                    ) ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const Basic = () => (

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc. Building beautiful interfaces and design systems.

                    2,456 Following
                    14.5K Followers
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc. Building beautiful interfaces and design systems.

                    2,456 Following
                    14.5K Followers
                    ``` ### Controlled The controlled `HoverCard` component provides an interface for managing the state of the hover card using the `open` and `onOpenChange` props: **Example: controlled** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/hover-card.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return (
                    setOpen(e.open)}>

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) } ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/hover-card.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return (
                    setOpen(e.open)}>

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ### 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. **Example: root-provider** #### React ```tsx import { HoverCard, useHoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/hover-card.module.css' export const RootProvider = () => { const hoverCard = useHoverCard() return (
                    Open: {String(hoverCard.open)}

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) } ``` #### Solid ```tsx import { HoverCard, useHoverCard } from '@ark-ui/solid/hover-card' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const RootProvider = () => { const hoverCard = useHoverCard() return (
                    Open: {String(hoverCard().open)}

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Open: {String(hoverCard().open)}

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ### Delay Control the open and close delay of the hover card using the `openDelay` and `closeDelay` props: **Example: delay** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/hover-card.module.css' export const Delay = () => (

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const Delay = () => (

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ### Positioning The `HoverCard` component can be customized in its placement and distance from the trigger element through the `positioning` prop: **Example: positioning** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/hover-card.module.css' export const Positioning = () => (

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const Positioning = () => (

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ### Context Use the `Context` component to access the hover card's state and methods from within the component tree: **Example: context** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/hover-card.module.css' export const Context = () => ( {(context) => (

                    Liked by{' '} @sarah_chen {context.open ? : } {' '} and 3 others

                    )}
                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const Context = () => ( {(context) => (

                    Liked by{' '} ( @sarah_chen {context().open ? : } )} />{' '} and 3 others

                    )}
                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(context)}

                    Liked by {#snippet asChild(props)} @sarah_chen {#if context().open} {:else} {/if} {/snippet} and 3 others

                    {/snippet}
                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `closeDelay` | `number` | No | The duration from when the mouse leaves the trigger or content until the hover card closes. | | `defaultOpen` | `boolean` | No | The initial open state of the hover card when rendered. Use when you don't need to control the open state of the hover card. | | `disabled` | `boolean` | No | Whether the hover card is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; positioner: string; arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the hover card opens or closes. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `open` | `boolean` | No | The controlled open state of the hover card | | `openDelay` | `number` | No | The duration from when the mouse enters the trigger until the hover card opens. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested hover-cards | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseHoverCardReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `closeDelay` | `number` | No | The duration from when the mouse leaves the trigger or content until the hover card closes. | | `defaultOpen` | `boolean` | No | The initial open state of the hover card when rendered. Use when you don't need to control the open state of the hover card. | | `disabled` | `boolean` | No | Whether the hover card is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; positioner: string; arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the hover card opens or closes. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `open` | `boolean` | No | The controlled open state of the hover card | | `openDelay` | `number` | No | The duration from when the mouse enters the trigger until the hover card opens. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested hover-cards | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseHoverCardReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `closeDelay` | `number` | No | The duration from when the mouse leaves the trigger or content until the hover card closes. | | `defaultOpen` | `boolean` | No | The initial open state of the hover card when rendered. Use when you don't need to control the open state of the hover card. | | `disabled` | `boolean` | No | Whether the hover card is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; positioner: string; arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `open` | `boolean` | No | The controlled open state of the hover card | | `openDelay` | `number` | No | The duration from when the mouse enters the trigger until the hover card opens. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested hover-cards | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `HoverCardApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `closeDelay` | `number` | No | The duration from when the mouse leaves the trigger or content until the hover card closes. | | `defaultOpen` | `boolean` | No | The initial open state of the hover card when rendered. Use when you don't need to control the open state of the hover card. | | `disabled` | `boolean` | No | Whether the hover card is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; positioner: string; arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the hover card opens or closes. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `open` | `boolean` | No | The controlled open state of the hover card | | `openDelay` | `number` | No | The duration from when the mouse enters the trigger until the hover card opens. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested hover-cards | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseHoverCardContext]>` | Yes | | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseHoverCardReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the hover card is open | | `setOpen` | `(open: boolean) => void` | Function to open the hover card | | `reposition` | `(options?: Partial) => void` | Function to reposition the popover | --- # Hover Card (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/hover-card.module.css' export const Basic = () => (

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc. Building beautiful interfaces and design systems.

                    2,456 Following
                    14.5K Followers
                    ) ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const Basic = () => (

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc. Building beautiful interfaces and design systems.

                    2,456 Following
                    14.5K Followers
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc. Building beautiful interfaces and design systems.

                    2,456 Following
                    14.5K Followers
                    ``` ### Controlled The controlled `HoverCard` component provides an interface for managing the state of the hover card using the `open` and `onOpenChange` props: **Example: controlled** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/hover-card.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return (
                    setOpen(e.open)}>

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) } ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/hover-card.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return (
                    setOpen(e.open)}>

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ### 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. **Example: root-provider** #### React ```tsx import { HoverCard, useHoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/hover-card.module.css' export const RootProvider = () => { const hoverCard = useHoverCard() return (
                    Open: {String(hoverCard.open)}

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) } ``` #### Solid ```tsx import { HoverCard, useHoverCard } from '@ark-ui/solid/hover-card' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const RootProvider = () => { const hoverCard = useHoverCard() return (
                    Open: {String(hoverCard().open)}

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Open: {String(hoverCard().open)}

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ### Delay Control the open and close delay of the hover card using the `openDelay` and `closeDelay` props: **Example: delay** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/hover-card.module.css' export const Delay = () => (

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const Delay = () => (

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ### Positioning The `HoverCard` component can be customized in its placement and distance from the trigger element through the `positioning` prop: **Example: positioning** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/hover-card.module.css' export const Positioning = () => (

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const Positioning = () => (

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ### Context Use the `Context` component to access the hover card's state and methods from within the component tree: **Example: context** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/hover-card.module.css' export const Context = () => ( {(context) => (

                    Liked by{' '} @sarah_chen {context.open ? : } {' '} and 3 others

                    )}
                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const Context = () => ( {(context) => (

                    Liked by{' '} ( @sarah_chen {context().open ? : } )} />{' '} and 3 others

                    )}
                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(context)}

                    Liked by {#snippet asChild(props)} @sarah_chen {#if context().open} {:else} {/if} {/snippet} and 3 others

                    {/snippet}
                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `closeDelay` | `number` | No | The duration from when the mouse leaves the trigger or content until the hover card closes. | | `defaultOpen` | `boolean` | No | The initial open state of the hover card when rendered. Use when you don't need to control the open state of the hover card. | | `disabled` | `boolean` | No | Whether the hover card is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; positioner: string; arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the hover card opens or closes. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `open` | `boolean` | No | The controlled open state of the hover card | | `openDelay` | `number` | No | The duration from when the mouse enters the trigger until the hover card opens. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested hover-cards | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseHoverCardReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `closeDelay` | `number` | No | The duration from when the mouse leaves the trigger or content until the hover card closes. | | `defaultOpen` | `boolean` | No | The initial open state of the hover card when rendered. Use when you don't need to control the open state of the hover card. | | `disabled` | `boolean` | No | Whether the hover card is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; positioner: string; arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the hover card opens or closes. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `open` | `boolean` | No | The controlled open state of the hover card | | `openDelay` | `number` | No | The duration from when the mouse enters the trigger until the hover card opens. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested hover-cards | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseHoverCardReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `closeDelay` | `number` | No | The duration from when the mouse leaves the trigger or content until the hover card closes. | | `defaultOpen` | `boolean` | No | The initial open state of the hover card when rendered. Use when you don't need to control the open state of the hover card. | | `disabled` | `boolean` | No | Whether the hover card is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; positioner: string; arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `open` | `boolean` | No | The controlled open state of the hover card | | `openDelay` | `number` | No | The duration from when the mouse enters the trigger until the hover card opens. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested hover-cards | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `HoverCardApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `closeDelay` | `number` | No | The duration from when the mouse leaves the trigger or content until the hover card closes. | | `defaultOpen` | `boolean` | No | The initial open state of the hover card when rendered. Use when you don't need to control the open state of the hover card. | | `disabled` | `boolean` | No | Whether the hover card is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; positioner: string; arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the hover card opens or closes. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `open` | `boolean` | No | The controlled open state of the hover card | | `openDelay` | `number` | No | The duration from when the mouse enters the trigger until the hover card opens. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested hover-cards | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseHoverCardContext]>` | Yes | | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseHoverCardReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the hover card is open | | `setOpen` | `(open: boolean) => void` | Function to open the hover card | | `reposition` | `(options?: Partial) => void` | Function to reposition the popover | --- # Hover Card (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/hover-card.module.css' export const Basic = () => (

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc. Building beautiful interfaces and design systems.

                    2,456 Following
                    14.5K Followers
                    ) ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const Basic = () => (

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc. Building beautiful interfaces and design systems.

                    2,456 Following
                    14.5K Followers
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc. Building beautiful interfaces and design systems.

                    2,456 Following
                    14.5K Followers
                    ``` ### Controlled The controlled `HoverCard` component provides an interface for managing the state of the hover card using the `open` and `onOpenChange` props: **Example: controlled** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/hover-card.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return (
                    setOpen(e.open)}>

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) } ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/hover-card.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return (
                    setOpen(e.open)}>

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ### 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. **Example: root-provider** #### React ```tsx import { HoverCard, useHoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/hover-card.module.css' export const RootProvider = () => { const hoverCard = useHoverCard() return (
                    Open: {String(hoverCard.open)}

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) } ``` #### Solid ```tsx import { HoverCard, useHoverCard } from '@ark-ui/solid/hover-card' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const RootProvider = () => { const hoverCard = useHoverCard() return (
                    Open: {String(hoverCard().open)}

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Open: {String(hoverCard().open)}

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ### Delay Control the open and close delay of the hover card using the `openDelay` and `closeDelay` props: **Example: delay** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/hover-card.module.css' export const Delay = () => (

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const Delay = () => (

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ### Positioning The `HoverCard` component can be customized in its placement and distance from the trigger element through the `positioning` prop: **Example: positioning** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/hover-card.module.css' export const Positioning = () => (

                    Liked by{' '} @sarah_chen {' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const Positioning = () => (

                    Liked by{' '} ( @sarah_chen )} />{' '} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Liked by {#snippet asChild(props)} @sarah_chen {/snippet} and 3 others

                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ### Context Use the `Context` component to access the hover card's state and methods from within the component tree: **Example: context** #### React ```tsx import { HoverCard } from '@ark-ui/react/hover-card' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/hover-card.module.css' export const Context = () => ( {(context) => (

                    Liked by{' '} @sarah_chen {context.open ? : } {' '} and 3 others

                    )}
                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Solid ```tsx import { HoverCard } from '@ark-ui/solid/hover-card' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/hover-card.module.css' export const Context = () => ( {(context) => (

                    Liked by{' '} ( @sarah_chen {context().open ? : } )} />{' '} and 3 others

                    )}
                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(context)}

                    Liked by {#snippet asChild(props)} @sarah_chen {#if context().open} {:else} {/if} {/snippet} and 3 others

                    {/snippet}
                    Sarah Chen

                    Sarah Chen

                    @sarah_chen

                    Design Engineer at Acme Inc.

                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `closeDelay` | `number` | No | The duration from when the mouse leaves the trigger or content until the hover card closes. | | `defaultOpen` | `boolean` | No | The initial open state of the hover card when rendered. Use when you don't need to control the open state of the hover card. | | `disabled` | `boolean` | No | Whether the hover card is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; positioner: string; arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the hover card opens or closes. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `open` | `boolean` | No | The controlled open state of the hover card | | `openDelay` | `number` | No | The duration from when the mouse enters the trigger until the hover card opens. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested hover-cards | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseHoverCardReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `closeDelay` | `number` | No | The duration from when the mouse leaves the trigger or content until the hover card closes. | | `defaultOpen` | `boolean` | No | The initial open state of the hover card when rendered. Use when you don't need to control the open state of the hover card. | | `disabled` | `boolean` | No | Whether the hover card is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; positioner: string; arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the hover card opens or closes. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `open` | `boolean` | No | The controlled open state of the hover card | | `openDelay` | `number` | No | The duration from when the mouse enters the trigger until the hover card opens. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested hover-cards | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseHoverCardReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `closeDelay` | `number` | No | The duration from when the mouse leaves the trigger or content until the hover card closes. | | `defaultOpen` | `boolean` | No | The initial open state of the hover card when rendered. Use when you don't need to control the open state of the hover card. | | `disabled` | `boolean` | No | Whether the hover card is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; positioner: string; arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `open` | `boolean` | No | The controlled open state of the hover card | | `openDelay` | `number` | No | The duration from when the mouse enters the trigger until the hover card opens. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested hover-cards | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `HoverCardApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `closeDelay` | `number` | No | The duration from when the mouse leaves the trigger or content until the hover card closes. | | `defaultOpen` | `boolean` | No | The initial open state of the hover card when rendered. Use when you don't need to control the open state of the hover card. | | `disabled` | `boolean` | No | Whether the hover card is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; positioner: string; arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the hover card opens or closes. | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `open` | `boolean` | No | The controlled open state of the hover card | | `openDelay` | `number` | No | The duration from when the mouse enters the trigger until the hover card opens. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested hover-cards | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseHoverCardContext]>` | Yes | | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseHoverCardReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | hover-card | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the hover card is open | | `setOpen` | `(open: boolean) => void` | Function to open the hover card | | `reposition` | `(options?: Partial) => void` | Function to reposition the popover | --- # Listbox (REACT) ## Anatomy {/* */} ```tsx ``` ## Examples ### Basic Here's a basic example of the Listbox component. **Example: basic** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const Basic = () => { const collection = createListCollection({ items: [ { label: 'United States', value: 'us' }, { label: 'United Kingdom', value: 'uk' }, { label: 'Canada', value: 'ca' }, { label: 'Australia', value: 'au' }, { label: 'Germany', value: 'de' }, { label: 'France', value: 'fr' }, { label: 'Japan', value: 'jp' }, ], }) return ( Select Country {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const Basic = () => { const collection = createListCollection({ items: [ { label: 'United States', value: 'us' }, { label: 'United Kingdom', value: 'uk' }, { label: 'Canada', value: 'ca' }, { label: 'Australia', value: 'au' }, { label: 'Germany', value: 'de' }, { label: 'France', value: 'fr' }, { label: 'Japan', value: 'jp' }, ], }) return ( Select Country {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Country {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Controlled The Listbox component can be controlled by using the `value` and `onValueChange` props. This allows you to manage the selected value externally. **Example: controlled** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/listbox.module.css' export const Controlled = () => { const collection = createListCollection({ items: [ { label: 'Small', value: 'sm' }, { label: 'Medium', value: 'md' }, { label: 'Large', value: 'lg' }, { label: 'Extra Large', value: 'xl' }, ], }) const [value, setValue] = useState(['md']) return ( setValue(e.value)} > Select Size {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/listbox.module.css' export const Controlled = () => { const collection = createListCollection({ items: [ { label: 'Small', value: 'sm' }, { label: 'Medium', value: 'md' }, { label: 'Large', value: 'lg' }, { label: 'Extra Large', value: 'xl' }, ], }) const [value, setValue] = createSignal(['md']) return ( setValue(e.value)}> Select Size {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte (value = e.value)}> Select Size {#each collection.items as item (item.value)} {item.label} {/each} ``` ### 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. **Example: root-provider** #### React ```tsx import { Listbox, createListCollection, useListbox } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/listbox.module.css' export const RootProvider = () => { const collection = createListCollection({ items: [ { label: 'Low', value: 'low' }, { label: 'Medium', value: 'medium' }, { label: 'High', value: 'high' }, { label: 'Critical', value: 'critical' }, ], }) const listbox = useListbox({ collection }) return (
                    Select Priority {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Listbox, createListCollection, useListbox } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/listbox.module.css' export const RootProvider = () => { const collection = createListCollection({ items: [ { label: 'Low', value: 'low' }, { label: 'Medium', value: 'medium' }, { label: 'High', value: 'high' }, { label: 'Critical', value: 'critical' }, ], }) const listbox = useListbox({ collection }) return (
                    Select Priority {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Select Priority {#each collection.items as item (item.value)} {item.label} {/each}
                    ``` ### Disabled Item Listbox items can be disabled using the `disabled` prop on the collection item. **Example: disabled-item** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const DisabledItem = () => { const collection = createListCollection({ items: [ { label: 'Free', value: 'free' }, { label: 'Pro', value: 'pro' }, { label: 'Enterprise', value: 'enterprise', disabled: true }, { label: 'Custom', value: 'custom' }, ], }) return ( Select Plan {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const DisabledItem = () => { const collection = createListCollection({ items: [ { label: 'Free', value: 'free' }, { label: 'Pro', value: 'pro' }, { label: 'Enterprise', value: 'enterprise', disabled: true }, { label: 'Custom', value: 'custom' }, ], }) return ( Select Plan {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Plan {#each collection.items as item (item.value)} {item.label} {/each} ``` > You can also use the `isItemDisabled` within the `createListCollection` to disable items based on a condition. ### Multiple You can set the `selectionMode` property as `multiple` to allow the user to select multiple items at a time. **Example: multiple** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const Multiple = () => { const collection = createListCollection({ items: [ { label: 'Monday', value: 'mon' }, { label: 'Tuesday', value: 'tue' }, { label: 'Wednesday', value: 'wed' }, { label: 'Thursday', value: 'thu' }, { label: 'Friday', value: 'fri' }, { label: 'Saturday', value: 'sat' }, { label: 'Sunday', value: 'sun' }, ], }) return ( Select Days {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const Multiple = () => { const collection = createListCollection({ items: [ { label: 'Monday', value: 'mon' }, { label: 'Tuesday', value: 'tue' }, { label: 'Wednesday', value: 'wed' }, { label: 'Thursday', value: 'thu' }, { label: 'Friday', value: 'fri' }, { label: 'Saturday', value: 'sat' }, { label: 'Sunday', value: 'sun' }, ], }) return ( Select Days {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Days {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Grouping The Listbox component supports grouping items. You can use the `groupBy` function to group items based on a specific property. **Example: group** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const Group = () => { const collection = createListCollection({ items: [ { label: 'New York', value: 'nyc', region: 'North America' }, { label: 'Los Angeles', value: 'lax', region: 'North America' }, { label: 'Toronto', value: 'yyz', region: 'North America' }, { label: 'London', value: 'lhr', region: 'Europe' }, { label: 'Paris', value: 'cdg', region: 'Europe' }, { label: 'Berlin', value: 'ber', region: 'Europe' }, { label: 'Tokyo', value: 'nrt', region: 'Asia Pacific' }, { label: 'Singapore', value: 'sin', region: 'Asia Pacific' }, { label: 'Sydney', value: 'syd', region: 'Asia Pacific' }, ], groupBy: (item) => item.region, }) return ( Select Region {collection.group().map(([region, items]) => ( {region} {items.map((item) => ( {item.label} ))} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/listbox.module.css' export const Group = () => { const collection = createListCollection({ items: [ { label: 'New York', value: 'nyc', region: 'North America' }, { label: 'Los Angeles', value: 'lax', region: 'North America' }, { label: 'Toronto', value: 'yyz', region: 'North America' }, { label: 'London', value: 'lhr', region: 'Europe' }, { label: 'Paris', value: 'cdg', region: 'Europe' }, { label: 'Berlin', value: 'ber', region: 'Europe' }, { label: 'Tokyo', value: 'nrt', region: 'Asia Pacific' }, { label: 'Singapore', value: 'sin', region: 'Asia Pacific' }, { label: 'Sydney', value: 'syd', region: 'Asia Pacific' }, ], groupBy: (item) => item.region, }) return ( Select Region {([region, items]) => ( {region} {(item) => ( {item.label} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Region {#each collection.group() as [region, items]} {region} {#each items as item (item.value)} {item.label} {/each} {/each} ``` ### Extended Selection The extended selection mode allows users to select multiple items using keyboard modifiers like `Cmd` (Mac) or `Ctrl` (Windows/Linux). **Example: extended-select** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const ExtendedSelect = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, { label: 'Preact', value: 'preact' }, ], }) return ( Hold or Ctrl to select multiple {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const ExtendedSelect = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, { label: 'Preact', value: 'preact' }, ], }) return ( Hold or Ctrl to select multiple {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Hold or Ctrl to select multiple {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Horizontal Use the `orientation` prop to display the listbox items horizontally. **Example: horizontal** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const Horizontal = () => { const collection = createListCollection({ items: [ { title: 'Midnight Dreams', artist: 'Luna Ray', image: 'https://picsum.photos/seed/album1/300/300', }, { title: 'Neon Skyline', artist: 'The Electric', image: 'https://picsum.photos/seed/album2/300/300', }, { title: 'Acoustic Sessions', artist: 'Sarah Woods', image: 'https://picsum.photos/seed/album3/300/300', }, { title: 'Urban Echoes', artist: 'Metro Collective', image: 'https://picsum.photos/seed/album4/300/300', }, { title: 'Summer Vibes', artist: 'Coastal Waves', image: 'https://picsum.photos/seed/album5/300/300', }, ], itemToValue: (item) => item.title, itemToString: (item) => item.title, }) return ( Select Album {collection.items.map((item) => ( {item.title} {item.title} {item.artist} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const Horizontal = () => { const collection = createListCollection({ items: [ { title: 'Midnight Dreams', artist: 'Luna Ray', image: 'https://picsum.photos/seed/album1/300/300', }, { title: 'Neon Skyline', artist: 'The Electric', image: 'https://picsum.photos/seed/album2/300/300', }, { title: 'Acoustic Sessions', artist: 'Sarah Woods', image: 'https://picsum.photos/seed/album3/300/300', }, { title: 'Urban Echoes', artist: 'Metro Collective', image: 'https://picsum.photos/seed/album4/300/300', }, { title: 'Summer Vibes', artist: 'Coastal Waves', image: 'https://picsum.photos/seed/album5/300/300', }, ], itemToValue: (item) => item.title, itemToString: (item) => item.title, }) return ( Select Album {(item) => ( {item().title} {item().title} {item().artist} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Album {#each collection.items as item (item.title)} {item.title} {item.title} {item.artist} {/each} ``` ### Grid Layout Use `createGridCollection` to display items in a grid layout with keyboard navigation support. **Example: grid** #### React ```tsx import { createGridCollection } from '@ark-ui/react/collection' import { Listbox } from '@ark-ui/react/listbox' import styles from 'styles/listbox.module.css' export const Grid = () => { const collection = createGridCollection({ items: [ { label: '😀', value: 'grinning' }, { label: '😍', value: 'heart-eyes' }, { label: '🥳', value: 'partying' }, { label: '😎', value: 'sunglasses' }, { label: '🤩', value: 'star-struck' }, { label: '😂', value: 'joy' }, { label: '🥰', value: 'smiling-hearts' }, { label: '😊', value: 'blush' }, { label: '🤗', value: 'hugging' }, { label: '😇', value: 'innocent' }, { label: '🔥', value: 'fire' }, { label: '✨', value: 'sparkles' }, { label: '💯', value: 'hundred' }, { label: '🎉', value: 'tada' }, { label: '❤️', value: 'heart' }, { label: '👍', value: 'thumbs-up' }, { label: '👏', value: 'clap' }, { label: '🚀', value: 'rocket' }, { label: '⭐', value: 'star' }, { label: '🌈', value: 'rainbow' }, ], columnCount: 5, }) return ( Pick a reaction {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { createGridCollection } from '@ark-ui/solid/collection' import { Listbox } from '@ark-ui/solid/listbox' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const Grid = () => { const collection = createGridCollection({ items: [ { label: '😀', value: 'grinning' }, { label: '😍', value: 'heart-eyes' }, { label: '🥳', value: 'partying' }, { label: '😎', value: 'sunglasses' }, { label: '🤩', value: 'star-struck' }, { label: '😂', value: 'joy' }, { label: '🥰', value: 'smiling-hearts' }, { label: '😊', value: 'blush' }, { label: '🤗', value: 'hugging' }, { label: '😇', value: 'innocent' }, { label: '🔥', value: 'fire' }, { label: '✨', value: 'sparkles' }, { label: '💯', value: 'hundred' }, { label: '🎉', value: 'tada' }, { label: '❤️', value: 'heart' }, { label: '👍', value: 'thumbs-up' }, { label: '👏', value: 'clap' }, { label: '🚀', value: 'rocket' }, { label: '⭐', value: 'star' }, { label: '🌈', value: 'rainbow' }, ], columnCount: 5, }) return ( Pick a reaction {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Pick a reaction {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Filtering Use `useListCollection` with the `filter` function to enable filtering of items. **Example: filtering** #### React ```tsx import { useListCollection } from '@ark-ui/react/collection' import { Listbox } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/listbox.module.css' export const Filtering = () => { const { collection, filter } = useListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, { label: 'Next.js', value: 'nextjs' }, { label: 'Nuxt.js', value: 'nuxtjs' }, { label: 'Remix', value: 'remix' }, { label: 'Gatsby', value: 'gatsby' }, { label: 'Preact', value: 'preact' }, ], filter: (itemText, filterText) => itemText.toLowerCase().includes(filterText.toLowerCase()), }) return ( Select Framework filter(e.target.value)} /> {collection.items.map((item) => ( {item.label} ))} No frameworks found ) } ``` #### Solid ```tsx import { useListCollection } from '@ark-ui/solid/collection' import { Listbox } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/listbox.module.css' export const Filtering = () => { const { collection, filter } = useListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, { label: 'Next.js', value: 'nextjs' }, { label: 'Nuxt.js', value: 'nuxtjs' }, { label: 'Remix', value: 'remix' }, { label: 'Gatsby', value: 'gatsby' }, { label: 'Preact', value: 'preact' }, ], filter: (itemText, filterText) => itemText.toLowerCase().includes(filterText.toLowerCase()), }) return ( Select Framework filter(e.target.value)} /> {(item) => ( {item().label} )} No frameworks found ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Framework filter(e.currentTarget.value)} /> {#each collection().items as item (item.value)} {item.label} {/each} No frameworks found ``` ### Select All Use `useListboxContext` to implement a "Select All" functionality that allows users to select or deselect all items at once. **Example: select-all** #### React ```tsx import { Listbox, createListCollection, useListboxContext } from '@ark-ui/react/listbox' import { CheckIcon, MinusIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Next.js', value: 'nextjs' }, { label: 'Nuxt.js', value: 'nuxtjs' }, { label: 'Remix', value: 'remix' }, { label: 'Gatsby', value: 'gatsby' }, ], }) const SelectAllHeader = () => { const listbox = useListboxContext() const isAllSelected = listbox.value.length === frameworks.items.length const isSomeSelected = listbox.value.length > 0 && listbox.value.length < frameworks.items.length const handleSelectAll = () => { if (isAllSelected) { listbox.setValue([]) } else { listbox.setValue(frameworks.items.map((item) => item.value)) } } return ( ) } export const SelectAll = () => { return ( {frameworks.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection, useListboxContext } from '@ark-ui/solid/listbox' import { CheckIcon, MinusIcon } from 'lucide-solid' import { Index, Show } from 'solid-js' import styles from 'styles/listbox.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Next.js', value: 'nextjs' }, { label: 'Nuxt.js', value: 'nuxtjs' }, { label: 'Remix', value: 'remix' }, { label: 'Gatsby', value: 'gatsby' }, ], }) const SelectAllHeader = () => { const listbox = useListboxContext() const isAllSelected = () => listbox().value.length === frameworks.items.length const isSomeSelected = () => listbox().value.length > 0 && listbox().value.length < frameworks.items.length const handleSelectAll = () => { if (isAllSelected()) { listbox().setValue([]) } else { listbox().setValue(frameworks.items.map((item) => item.value)) } } return ( ) } export const SelectAll = () => { return ( {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet selectAllHeader()} {/snippet} {@render selectAllHeader()} {#each frameworks.items as item (item.value)} {item.label} {/each} ``` ### Value Text Use `Listbox.ValueText` to display the selected values as a comma-separated string. **Example: value-text** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const ValueText = () => { const collection = createListCollection({ items: [ { label: 'Red', value: 'red' }, { label: 'Blue', value: 'blue' }, { label: 'Green', value: 'green' }, { label: 'Yellow', value: 'yellow' }, { label: 'Purple', value: 'purple' }, ], }) return ( Colors: {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const ValueText = () => { const collection = createListCollection({ items: [ { label: 'Red', value: 'red' }, { label: 'Blue', value: 'blue' }, { label: 'Green', value: 'green' }, { label: 'Yellow', value: 'yellow' }, { label: 'Purple', value: 'purple' }, ], }) return ( Colors: {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Colors: {#each collection.items as item (item.value)} {item.label} {/each} ``` ## Guides ### Type Safety The `Listbox.RootComponent` type enables you to create typed wrapper components that maintain full type safety for collection items. ```tsx const Listbox: ArkListbox.RootComponent = (props) => { return {/* ... */} } ``` Use the wrapper with full type inference on `onValueChange` and other callbacks: ```tsx const App = () => { const collection = createListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, ], }) return ( { // e.items is typed as Array<{ label: string, value: string }> console.log(e.items) }} > {/* ... */} ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the listbox. | | `defaultValue` | `string[]` | No | The initial default value of the listbox when rendered. Use when you don't need to control the value of the listbox. | | `deselectable` | `boolean` | No | Whether to disallow empty selection | | `disabled` | `boolean` | No | Whether the listbox is disabled | | `disallowSelectAll` | `boolean` | No | Whether to disallow selecting all items when `meta+a` is pressed | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string label: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the listbox. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the listbox. | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionMode` | `SelectionMode` | No | How multiple selection should behave in the listbox. - `single`: The user can select a single item. - `multiple`: The user can select multiple items without using modifier keys. - `extended`: The user can select multiple items by using modifier keys. | | `selectOnHighlight` | `boolean` | No | Whether to select the item when it is highlighted | | `typeahead` | `boolean` | No | Whether to enable typeahead on the listbox | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | root | | `[data-orientation]` | The orientation of the listbox | | `[data-disabled]` | Present when disabled | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | content | | `[data-activedescendant]` | The id the active descendant of the content | | `[data-orientation]` | The orientation of the content | | `[data-layout]` | | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--column-count` | The column count value for the Content | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoHighlight` | `boolean` | No | Whether to automatically highlight the item when typing | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `highlightOnHover` | `boolean` | No | Whether to highlight the item on hover | | `item` | `any` | No | The item to render | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-selected]` | Present when selected | | `[data-layout]` | | | `[data-state]` | "checked" | "unchecked" | | `[data-orientation]` | The orientation of the item | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseListboxReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is listboxed. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the listbox. | | `defaultValue` | `string[]` | No | The initial default value of the listbox when rendered. Use when you don't need to control the value of the listbox. | | `deselectable` | `boolean` | No | Whether to disallow empty selection | | `disabled` | `boolean` | No | Whether the listbox is disabled | | `disallowSelectAll` | `boolean` | No | Whether to disallow selecting all items when `meta+a` is pressed | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string label: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the listbox. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the listbox. | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionMode` | `SelectionMode` | No | How multiple selection should behave in the listbox. - `single`: The user can select a single item. - `multiple`: The user can select multiple items without using modifier keys. - `extended`: The user can select multiple items by using modifier keys. | | `selectOnHighlight` | `boolean` | No | Whether to select the item when it is highlighted | | `typeahead` | `boolean` | No | Whether to enable typeahead on the listbox | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | root | | `[data-orientation]` | The orientation of the listbox | | `[data-disabled]` | Present when disabled | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | content | | `[data-activedescendant]` | The id the active descendant of the content | | `[data-orientation]` | The orientation of the content | | `[data-layout]` | | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--column-count` | The column count value for the Content | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoHighlight` | `boolean` | No | Whether to automatically highlight the item when typing | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `highlightOnHover` | `boolean` | No | Whether to highlight the item on hover | | `item` | `any` | No | The item to render | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-selected]` | Present when selected | | `[data-layout]` | | | `[data-state]` | "checked" | "unchecked" | | `[data-orientation]` | The orientation of the item | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseListboxReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is selected. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the listbox. | | `defaultValue` | `string[]` | No | The initial default value of the listbox when rendered. Use when you don't need to control the value of the listbox. | | `deselectable` | `boolean` | No | Whether to disallow empty selection | | `disabled` | `boolean` | No | Whether the listbox is disabled | | `disallowSelectAll` | `boolean` | No | Whether to disallow selecting all items when `meta+a` is pressed | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string label: string item(id: string | number): string itemGroup(id: string | number): string itemGroupLabel(id: string | number): string }>` | No | The ids of the elements in the listbox. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `modelValue` | `string[]` | No | The model value of the listbox | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionMode` | `SelectionMode` | No | How multiple selection should behave in the listbox. - `single`: The user can select a single item. - `multiple`: The user can select multiple items without using modifier keys. - `extended`: The user can select multiple items by using modifier keys. | | `selectOnHighlight` | `boolean` | No | Whether to select the item when it is highlighted | | `typeahead` | `boolean` | No | Whether to enable typeahead on the listbox | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | root | | `[data-orientation]` | The orientation of the listbox | | `[data-disabled]` | Present when disabled | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | content | | `[data-activedescendant]` | The id the active descendant of the content | | `[data-orientation]` | The orientation of the content | | `[data-layout]` | | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--column-count` | The column count value for the Content | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `highlightOnHover` | `boolean` | No | Whether to highlight the item on hover | | `item` | `any` | No | The item to render | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-selected]` | Present when selected | | `[data-layout]` | | | `[data-state]` | "checked" | "unchecked" | | `[data-orientation]` | The orientation of the item | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ListboxApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the listbox. | | `defaultValue` | `string[]` | No | The initial default value of the listbox when rendered. Use when you don't need to control the value of the listbox. | | `deselectable` | `boolean` | No | Whether to disallow empty selection | | `disabled` | `boolean` | No | Whether the listbox is disabled | | `disallowSelectAll` | `boolean` | No | Whether to disallow selecting all items when `meta+a` is pressed | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string label: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the listbox. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the listbox. | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionMode` | `SelectionMode` | No | How multiple selection should behave in the listbox. - `single`: The user can select a single item. - `multiple`: The user can select multiple items without using modifier keys. - `extended`: The user can select multiple items by using modifier keys. | | `selectOnHighlight` | `boolean` | No | Whether to select the item when it is highlighted | | `typeahead` | `boolean` | No | Whether to enable typeahead on the listbox | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | root | | `[data-orientation]` | The orientation of the listbox | | `[data-disabled]` | Present when disabled | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | content | | `[data-activedescendant]` | The id the active descendant of the content | | `[data-orientation]` | The orientation of the content | | `[data-layout]` | | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--column-count` | The column count value for the Content | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseListboxContext]>` | Yes | | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoHighlight` | `boolean` | No | Whether to automatically highlight the item when typing | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseListboxItemContext]>` | Yes | | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `highlightOnHover` | `boolean` | No | Whether to highlight the item on hover | | `item` | `any` | No | The item to render | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-selected]` | Present when selected | | `[data-layout]` | | | `[data-state]` | "checked" | "unchecked" | | `[data-orientation]` | The orientation of the item | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseListboxReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is selected. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `empty` | `boolean` | Whether the select value is empty | | `highlightedValue` | `string` | The value of the highlighted item | | `highlightedItem` | `V` | The highlighted item | | `highlightValue` | `(value: string) => void` | Function to highlight a value | | `clearHighlightedValue` | `VoidFunction` | Function to clear the highlighted value | | `selectedItems` | `V[]` | The selected items | | `hasSelectedItems` | `boolean` | Whether there's a selected option | | `value` | `string[]` | The selected item keys | | `valueAsString` | `string` | The string representation of the selected items | | `selectValue` | `(value: string) => void` | Function to select a value | | `selectAll` | `VoidFunction` | Function to select all values. **Note**: This should only be called when the selectionMode is `multiple` or `extended`. Otherwise, an exception will be thrown. | | `setValue` | `(value: string[]) => void` | Function to set the value of the select | | `clearValue` | `(value?: string) => void` | Function to clear the value of the select. If a value is provided, it will only clear that value, otherwise, it will clear all values. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a select item | | `collection` | `ListCollection` | Function to toggle the select | | `disabled` | `boolean` | Whether the select is disabled | --- # Listbox (VUE) ## Anatomy {/* */} ```tsx ``` ## Examples ### Basic Here's a basic example of the Listbox component. **Example: basic** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const Basic = () => { const collection = createListCollection({ items: [ { label: 'United States', value: 'us' }, { label: 'United Kingdom', value: 'uk' }, { label: 'Canada', value: 'ca' }, { label: 'Australia', value: 'au' }, { label: 'Germany', value: 'de' }, { label: 'France', value: 'fr' }, { label: 'Japan', value: 'jp' }, ], }) return ( Select Country {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const Basic = () => { const collection = createListCollection({ items: [ { label: 'United States', value: 'us' }, { label: 'United Kingdom', value: 'uk' }, { label: 'Canada', value: 'ca' }, { label: 'Australia', value: 'au' }, { label: 'Germany', value: 'de' }, { label: 'France', value: 'fr' }, { label: 'Japan', value: 'jp' }, ], }) return ( Select Country {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Country {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Controlled The Listbox component can be controlled by using the `value` and `onValueChange` props. This allows you to manage the selected value externally. **Example: controlled** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/listbox.module.css' export const Controlled = () => { const collection = createListCollection({ items: [ { label: 'Small', value: 'sm' }, { label: 'Medium', value: 'md' }, { label: 'Large', value: 'lg' }, { label: 'Extra Large', value: 'xl' }, ], }) const [value, setValue] = useState(['md']) return ( setValue(e.value)} > Select Size {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/listbox.module.css' export const Controlled = () => { const collection = createListCollection({ items: [ { label: 'Small', value: 'sm' }, { label: 'Medium', value: 'md' }, { label: 'Large', value: 'lg' }, { label: 'Extra Large', value: 'xl' }, ], }) const [value, setValue] = createSignal(['md']) return ( setValue(e.value)}> Select Size {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte (value = e.value)}> Select Size {#each collection.items as item (item.value)} {item.label} {/each} ``` ### 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. **Example: root-provider** #### React ```tsx import { Listbox, createListCollection, useListbox } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/listbox.module.css' export const RootProvider = () => { const collection = createListCollection({ items: [ { label: 'Low', value: 'low' }, { label: 'Medium', value: 'medium' }, { label: 'High', value: 'high' }, { label: 'Critical', value: 'critical' }, ], }) const listbox = useListbox({ collection }) return (
                    Select Priority {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Listbox, createListCollection, useListbox } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/listbox.module.css' export const RootProvider = () => { const collection = createListCollection({ items: [ { label: 'Low', value: 'low' }, { label: 'Medium', value: 'medium' }, { label: 'High', value: 'high' }, { label: 'Critical', value: 'critical' }, ], }) const listbox = useListbox({ collection }) return (
                    Select Priority {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Select Priority {#each collection.items as item (item.value)} {item.label} {/each}
                    ``` ### Disabled Item Listbox items can be disabled using the `disabled` prop on the collection item. **Example: disabled-item** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const DisabledItem = () => { const collection = createListCollection({ items: [ { label: 'Free', value: 'free' }, { label: 'Pro', value: 'pro' }, { label: 'Enterprise', value: 'enterprise', disabled: true }, { label: 'Custom', value: 'custom' }, ], }) return ( Select Plan {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const DisabledItem = () => { const collection = createListCollection({ items: [ { label: 'Free', value: 'free' }, { label: 'Pro', value: 'pro' }, { label: 'Enterprise', value: 'enterprise', disabled: true }, { label: 'Custom', value: 'custom' }, ], }) return ( Select Plan {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Plan {#each collection.items as item (item.value)} {item.label} {/each} ``` > You can also use the `isItemDisabled` within the `createListCollection` to disable items based on a condition. ### Multiple You can set the `selectionMode` property as `multiple` to allow the user to select multiple items at a time. **Example: multiple** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const Multiple = () => { const collection = createListCollection({ items: [ { label: 'Monday', value: 'mon' }, { label: 'Tuesday', value: 'tue' }, { label: 'Wednesday', value: 'wed' }, { label: 'Thursday', value: 'thu' }, { label: 'Friday', value: 'fri' }, { label: 'Saturday', value: 'sat' }, { label: 'Sunday', value: 'sun' }, ], }) return ( Select Days {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const Multiple = () => { const collection = createListCollection({ items: [ { label: 'Monday', value: 'mon' }, { label: 'Tuesday', value: 'tue' }, { label: 'Wednesday', value: 'wed' }, { label: 'Thursday', value: 'thu' }, { label: 'Friday', value: 'fri' }, { label: 'Saturday', value: 'sat' }, { label: 'Sunday', value: 'sun' }, ], }) return ( Select Days {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Days {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Grouping The Listbox component supports grouping items. You can use the `groupBy` function to group items based on a specific property. **Example: group** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const Group = () => { const collection = createListCollection({ items: [ { label: 'New York', value: 'nyc', region: 'North America' }, { label: 'Los Angeles', value: 'lax', region: 'North America' }, { label: 'Toronto', value: 'yyz', region: 'North America' }, { label: 'London', value: 'lhr', region: 'Europe' }, { label: 'Paris', value: 'cdg', region: 'Europe' }, { label: 'Berlin', value: 'ber', region: 'Europe' }, { label: 'Tokyo', value: 'nrt', region: 'Asia Pacific' }, { label: 'Singapore', value: 'sin', region: 'Asia Pacific' }, { label: 'Sydney', value: 'syd', region: 'Asia Pacific' }, ], groupBy: (item) => item.region, }) return ( Select Region {collection.group().map(([region, items]) => ( {region} {items.map((item) => ( {item.label} ))} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/listbox.module.css' export const Group = () => { const collection = createListCollection({ items: [ { label: 'New York', value: 'nyc', region: 'North America' }, { label: 'Los Angeles', value: 'lax', region: 'North America' }, { label: 'Toronto', value: 'yyz', region: 'North America' }, { label: 'London', value: 'lhr', region: 'Europe' }, { label: 'Paris', value: 'cdg', region: 'Europe' }, { label: 'Berlin', value: 'ber', region: 'Europe' }, { label: 'Tokyo', value: 'nrt', region: 'Asia Pacific' }, { label: 'Singapore', value: 'sin', region: 'Asia Pacific' }, { label: 'Sydney', value: 'syd', region: 'Asia Pacific' }, ], groupBy: (item) => item.region, }) return ( Select Region {([region, items]) => ( {region} {(item) => ( {item.label} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Region {#each collection.group() as [region, items]} {region} {#each items as item (item.value)} {item.label} {/each} {/each} ``` ### Extended Selection The extended selection mode allows users to select multiple items using keyboard modifiers like `Cmd` (Mac) or `Ctrl` (Windows/Linux). **Example: extended-select** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const ExtendedSelect = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, { label: 'Preact', value: 'preact' }, ], }) return ( Hold or Ctrl to select multiple {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const ExtendedSelect = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, { label: 'Preact', value: 'preact' }, ], }) return ( Hold or Ctrl to select multiple {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Hold or Ctrl to select multiple {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Horizontal Use the `orientation` prop to display the listbox items horizontally. **Example: horizontal** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const Horizontal = () => { const collection = createListCollection({ items: [ { title: 'Midnight Dreams', artist: 'Luna Ray', image: 'https://picsum.photos/seed/album1/300/300', }, { title: 'Neon Skyline', artist: 'The Electric', image: 'https://picsum.photos/seed/album2/300/300', }, { title: 'Acoustic Sessions', artist: 'Sarah Woods', image: 'https://picsum.photos/seed/album3/300/300', }, { title: 'Urban Echoes', artist: 'Metro Collective', image: 'https://picsum.photos/seed/album4/300/300', }, { title: 'Summer Vibes', artist: 'Coastal Waves', image: 'https://picsum.photos/seed/album5/300/300', }, ], itemToValue: (item) => item.title, itemToString: (item) => item.title, }) return ( Select Album {collection.items.map((item) => ( {item.title} {item.title} {item.artist} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const Horizontal = () => { const collection = createListCollection({ items: [ { title: 'Midnight Dreams', artist: 'Luna Ray', image: 'https://picsum.photos/seed/album1/300/300', }, { title: 'Neon Skyline', artist: 'The Electric', image: 'https://picsum.photos/seed/album2/300/300', }, { title: 'Acoustic Sessions', artist: 'Sarah Woods', image: 'https://picsum.photos/seed/album3/300/300', }, { title: 'Urban Echoes', artist: 'Metro Collective', image: 'https://picsum.photos/seed/album4/300/300', }, { title: 'Summer Vibes', artist: 'Coastal Waves', image: 'https://picsum.photos/seed/album5/300/300', }, ], itemToValue: (item) => item.title, itemToString: (item) => item.title, }) return ( Select Album {(item) => ( {item().title} {item().title} {item().artist} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Album {#each collection.items as item (item.title)} {item.title} {item.title} {item.artist} {/each} ``` ### Grid Layout Use `createGridCollection` to display items in a grid layout with keyboard navigation support. **Example: grid** #### React ```tsx import { createGridCollection } from '@ark-ui/react/collection' import { Listbox } from '@ark-ui/react/listbox' import styles from 'styles/listbox.module.css' export const Grid = () => { const collection = createGridCollection({ items: [ { label: '😀', value: 'grinning' }, { label: '😍', value: 'heart-eyes' }, { label: '🥳', value: 'partying' }, { label: '😎', value: 'sunglasses' }, { label: '🤩', value: 'star-struck' }, { label: '😂', value: 'joy' }, { label: '🥰', value: 'smiling-hearts' }, { label: '😊', value: 'blush' }, { label: '🤗', value: 'hugging' }, { label: '😇', value: 'innocent' }, { label: '🔥', value: 'fire' }, { label: '✨', value: 'sparkles' }, { label: '💯', value: 'hundred' }, { label: '🎉', value: 'tada' }, { label: '❤️', value: 'heart' }, { label: '👍', value: 'thumbs-up' }, { label: '👏', value: 'clap' }, { label: '🚀', value: 'rocket' }, { label: '⭐', value: 'star' }, { label: '🌈', value: 'rainbow' }, ], columnCount: 5, }) return ( Pick a reaction {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { createGridCollection } from '@ark-ui/solid/collection' import { Listbox } from '@ark-ui/solid/listbox' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const Grid = () => { const collection = createGridCollection({ items: [ { label: '😀', value: 'grinning' }, { label: '😍', value: 'heart-eyes' }, { label: '🥳', value: 'partying' }, { label: '😎', value: 'sunglasses' }, { label: '🤩', value: 'star-struck' }, { label: '😂', value: 'joy' }, { label: '🥰', value: 'smiling-hearts' }, { label: '😊', value: 'blush' }, { label: '🤗', value: 'hugging' }, { label: '😇', value: 'innocent' }, { label: '🔥', value: 'fire' }, { label: '✨', value: 'sparkles' }, { label: '💯', value: 'hundred' }, { label: '🎉', value: 'tada' }, { label: '❤️', value: 'heart' }, { label: '👍', value: 'thumbs-up' }, { label: '👏', value: 'clap' }, { label: '🚀', value: 'rocket' }, { label: '⭐', value: 'star' }, { label: '🌈', value: 'rainbow' }, ], columnCount: 5, }) return ( Pick a reaction {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Pick a reaction {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Filtering Use `useListCollection` with the `filter` function to enable filtering of items. **Example: filtering** #### React ```tsx import { useListCollection } from '@ark-ui/react/collection' import { Listbox } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/listbox.module.css' export const Filtering = () => { const { collection, filter } = useListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, { label: 'Next.js', value: 'nextjs' }, { label: 'Nuxt.js', value: 'nuxtjs' }, { label: 'Remix', value: 'remix' }, { label: 'Gatsby', value: 'gatsby' }, { label: 'Preact', value: 'preact' }, ], filter: (itemText, filterText) => itemText.toLowerCase().includes(filterText.toLowerCase()), }) return ( Select Framework filter(e.target.value)} /> {collection.items.map((item) => ( {item.label} ))} No frameworks found ) } ``` #### Solid ```tsx import { useListCollection } from '@ark-ui/solid/collection' import { Listbox } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/listbox.module.css' export const Filtering = () => { const { collection, filter } = useListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, { label: 'Next.js', value: 'nextjs' }, { label: 'Nuxt.js', value: 'nuxtjs' }, { label: 'Remix', value: 'remix' }, { label: 'Gatsby', value: 'gatsby' }, { label: 'Preact', value: 'preact' }, ], filter: (itemText, filterText) => itemText.toLowerCase().includes(filterText.toLowerCase()), }) return ( Select Framework filter(e.target.value)} /> {(item) => ( {item().label} )} No frameworks found ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Framework filter(e.currentTarget.value)} /> {#each collection().items as item (item.value)} {item.label} {/each} No frameworks found ``` ### Select All Use `useListboxContext` to implement a "Select All" functionality that allows users to select or deselect all items at once. **Example: select-all** #### React ```tsx import { Listbox, createListCollection, useListboxContext } from '@ark-ui/react/listbox' import { CheckIcon, MinusIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Next.js', value: 'nextjs' }, { label: 'Nuxt.js', value: 'nuxtjs' }, { label: 'Remix', value: 'remix' }, { label: 'Gatsby', value: 'gatsby' }, ], }) const SelectAllHeader = () => { const listbox = useListboxContext() const isAllSelected = listbox.value.length === frameworks.items.length const isSomeSelected = listbox.value.length > 0 && listbox.value.length < frameworks.items.length const handleSelectAll = () => { if (isAllSelected) { listbox.setValue([]) } else { listbox.setValue(frameworks.items.map((item) => item.value)) } } return ( ) } export const SelectAll = () => { return ( {frameworks.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection, useListboxContext } from '@ark-ui/solid/listbox' import { CheckIcon, MinusIcon } from 'lucide-solid' import { Index, Show } from 'solid-js' import styles from 'styles/listbox.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Next.js', value: 'nextjs' }, { label: 'Nuxt.js', value: 'nuxtjs' }, { label: 'Remix', value: 'remix' }, { label: 'Gatsby', value: 'gatsby' }, ], }) const SelectAllHeader = () => { const listbox = useListboxContext() const isAllSelected = () => listbox().value.length === frameworks.items.length const isSomeSelected = () => listbox().value.length > 0 && listbox().value.length < frameworks.items.length const handleSelectAll = () => { if (isAllSelected()) { listbox().setValue([]) } else { listbox().setValue(frameworks.items.map((item) => item.value)) } } return ( ) } export const SelectAll = () => { return ( {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet selectAllHeader()} {/snippet} {@render selectAllHeader()} {#each frameworks.items as item (item.value)} {item.label} {/each} ``` ### Value Text Use `Listbox.ValueText` to display the selected values as a comma-separated string. **Example: value-text** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const ValueText = () => { const collection = createListCollection({ items: [ { label: 'Red', value: 'red' }, { label: 'Blue', value: 'blue' }, { label: 'Green', value: 'green' }, { label: 'Yellow', value: 'yellow' }, { label: 'Purple', value: 'purple' }, ], }) return ( Colors: {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const ValueText = () => { const collection = createListCollection({ items: [ { label: 'Red', value: 'red' }, { label: 'Blue', value: 'blue' }, { label: 'Green', value: 'green' }, { label: 'Yellow', value: 'yellow' }, { label: 'Purple', value: 'purple' }, ], }) return ( Colors: {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Colors: {#each collection.items as item (item.value)} {item.label} {/each} ``` ## Guides ### Type Safety The `Listbox.RootComponent` type enables you to create typed wrapper components that maintain full type safety for collection items. ```tsx const Listbox: ArkListbox.RootComponent = (props) => { return {/* ... */} } ``` Use the wrapper with full type inference on `onValueChange` and other callbacks: ```tsx const App = () => { const collection = createListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, ], }) return ( { // e.items is typed as Array<{ label: string, value: string }> console.log(e.items) }} > {/* ... */} ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the listbox. | | `defaultValue` | `string[]` | No | The initial default value of the listbox when rendered. Use when you don't need to control the value of the listbox. | | `deselectable` | `boolean` | No | Whether to disallow empty selection | | `disabled` | `boolean` | No | Whether the listbox is disabled | | `disallowSelectAll` | `boolean` | No | Whether to disallow selecting all items when `meta+a` is pressed | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string label: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the listbox. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the listbox. | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionMode` | `SelectionMode` | No | How multiple selection should behave in the listbox. - `single`: The user can select a single item. - `multiple`: The user can select multiple items without using modifier keys. - `extended`: The user can select multiple items by using modifier keys. | | `selectOnHighlight` | `boolean` | No | Whether to select the item when it is highlighted | | `typeahead` | `boolean` | No | Whether to enable typeahead on the listbox | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | root | | `[data-orientation]` | The orientation of the listbox | | `[data-disabled]` | Present when disabled | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | content | | `[data-activedescendant]` | The id the active descendant of the content | | `[data-orientation]` | The orientation of the content | | `[data-layout]` | | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--column-count` | The column count value for the Content | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoHighlight` | `boolean` | No | Whether to automatically highlight the item when typing | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `highlightOnHover` | `boolean` | No | Whether to highlight the item on hover | | `item` | `any` | No | The item to render | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-selected]` | Present when selected | | `[data-layout]` | | | `[data-state]` | "checked" | "unchecked" | | `[data-orientation]` | The orientation of the item | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseListboxReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is listboxed. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the listbox. | | `defaultValue` | `string[]` | No | The initial default value of the listbox when rendered. Use when you don't need to control the value of the listbox. | | `deselectable` | `boolean` | No | Whether to disallow empty selection | | `disabled` | `boolean` | No | Whether the listbox is disabled | | `disallowSelectAll` | `boolean` | No | Whether to disallow selecting all items when `meta+a` is pressed | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string label: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the listbox. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the listbox. | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionMode` | `SelectionMode` | No | How multiple selection should behave in the listbox. - `single`: The user can select a single item. - `multiple`: The user can select multiple items without using modifier keys. - `extended`: The user can select multiple items by using modifier keys. | | `selectOnHighlight` | `boolean` | No | Whether to select the item when it is highlighted | | `typeahead` | `boolean` | No | Whether to enable typeahead on the listbox | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | root | | `[data-orientation]` | The orientation of the listbox | | `[data-disabled]` | Present when disabled | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | content | | `[data-activedescendant]` | The id the active descendant of the content | | `[data-orientation]` | The orientation of the content | | `[data-layout]` | | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--column-count` | The column count value for the Content | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoHighlight` | `boolean` | No | Whether to automatically highlight the item when typing | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `highlightOnHover` | `boolean` | No | Whether to highlight the item on hover | | `item` | `any` | No | The item to render | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-selected]` | Present when selected | | `[data-layout]` | | | `[data-state]` | "checked" | "unchecked" | | `[data-orientation]` | The orientation of the item | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseListboxReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is selected. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the listbox. | | `defaultValue` | `string[]` | No | The initial default value of the listbox when rendered. Use when you don't need to control the value of the listbox. | | `deselectable` | `boolean` | No | Whether to disallow empty selection | | `disabled` | `boolean` | No | Whether the listbox is disabled | | `disallowSelectAll` | `boolean` | No | Whether to disallow selecting all items when `meta+a` is pressed | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string label: string item(id: string | number): string itemGroup(id: string | number): string itemGroupLabel(id: string | number): string }>` | No | The ids of the elements in the listbox. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `modelValue` | `string[]` | No | The model value of the listbox | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionMode` | `SelectionMode` | No | How multiple selection should behave in the listbox. - `single`: The user can select a single item. - `multiple`: The user can select multiple items without using modifier keys. - `extended`: The user can select multiple items by using modifier keys. | | `selectOnHighlight` | `boolean` | No | Whether to select the item when it is highlighted | | `typeahead` | `boolean` | No | Whether to enable typeahead on the listbox | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | root | | `[data-orientation]` | The orientation of the listbox | | `[data-disabled]` | Present when disabled | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | content | | `[data-activedescendant]` | The id the active descendant of the content | | `[data-orientation]` | The orientation of the content | | `[data-layout]` | | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--column-count` | The column count value for the Content | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `highlightOnHover` | `boolean` | No | Whether to highlight the item on hover | | `item` | `any` | No | The item to render | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-selected]` | Present when selected | | `[data-layout]` | | | `[data-state]` | "checked" | "unchecked" | | `[data-orientation]` | The orientation of the item | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ListboxApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the listbox. | | `defaultValue` | `string[]` | No | The initial default value of the listbox when rendered. Use when you don't need to control the value of the listbox. | | `deselectable` | `boolean` | No | Whether to disallow empty selection | | `disabled` | `boolean` | No | Whether the listbox is disabled | | `disallowSelectAll` | `boolean` | No | Whether to disallow selecting all items when `meta+a` is pressed | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string label: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the listbox. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the listbox. | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionMode` | `SelectionMode` | No | How multiple selection should behave in the listbox. - `single`: The user can select a single item. - `multiple`: The user can select multiple items without using modifier keys. - `extended`: The user can select multiple items by using modifier keys. | | `selectOnHighlight` | `boolean` | No | Whether to select the item when it is highlighted | | `typeahead` | `boolean` | No | Whether to enable typeahead on the listbox | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | root | | `[data-orientation]` | The orientation of the listbox | | `[data-disabled]` | Present when disabled | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | content | | `[data-activedescendant]` | The id the active descendant of the content | | `[data-orientation]` | The orientation of the content | | `[data-layout]` | | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--column-count` | The column count value for the Content | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseListboxContext]>` | Yes | | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoHighlight` | `boolean` | No | Whether to automatically highlight the item when typing | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseListboxItemContext]>` | Yes | | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `highlightOnHover` | `boolean` | No | Whether to highlight the item on hover | | `item` | `any` | No | The item to render | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-selected]` | Present when selected | | `[data-layout]` | | | `[data-state]` | "checked" | "unchecked" | | `[data-orientation]` | The orientation of the item | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseListboxReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is selected. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `empty` | `boolean` | Whether the select value is empty | | `highlightedValue` | `string` | The value of the highlighted item | | `highlightedItem` | `V` | The highlighted item | | `highlightValue` | `(value: string) => void` | Function to highlight a value | | `clearHighlightedValue` | `VoidFunction` | Function to clear the highlighted value | | `selectedItems` | `V[]` | The selected items | | `hasSelectedItems` | `boolean` | Whether there's a selected option | | `value` | `string[]` | The selected item keys | | `valueAsString` | `string` | The string representation of the selected items | | `selectValue` | `(value: string) => void` | Function to select a value | | `selectAll` | `VoidFunction` | Function to select all values. **Note**: This should only be called when the selectionMode is `multiple` or `extended`. Otherwise, an exception will be thrown. | | `setValue` | `(value: string[]) => void` | Function to set the value of the select | | `clearValue` | `(value?: string) => void` | Function to clear the value of the select. If a value is provided, it will only clear that value, otherwise, it will clear all values. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a select item | | `collection` | `ListCollection` | Function to toggle the select | | `disabled` | `boolean` | Whether the select is disabled | --- # Listbox (SVELTE) ## Anatomy {/* */} ```tsx ``` ## Examples ### Basic Here's a basic example of the Listbox component. **Example: basic** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const Basic = () => { const collection = createListCollection({ items: [ { label: 'United States', value: 'us' }, { label: 'United Kingdom', value: 'uk' }, { label: 'Canada', value: 'ca' }, { label: 'Australia', value: 'au' }, { label: 'Germany', value: 'de' }, { label: 'France', value: 'fr' }, { label: 'Japan', value: 'jp' }, ], }) return ( Select Country {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const Basic = () => { const collection = createListCollection({ items: [ { label: 'United States', value: 'us' }, { label: 'United Kingdom', value: 'uk' }, { label: 'Canada', value: 'ca' }, { label: 'Australia', value: 'au' }, { label: 'Germany', value: 'de' }, { label: 'France', value: 'fr' }, { label: 'Japan', value: 'jp' }, ], }) return ( Select Country {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Country {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Controlled The Listbox component can be controlled by using the `value` and `onValueChange` props. This allows you to manage the selected value externally. **Example: controlled** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/listbox.module.css' export const Controlled = () => { const collection = createListCollection({ items: [ { label: 'Small', value: 'sm' }, { label: 'Medium', value: 'md' }, { label: 'Large', value: 'lg' }, { label: 'Extra Large', value: 'xl' }, ], }) const [value, setValue] = useState(['md']) return ( setValue(e.value)} > Select Size {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/listbox.module.css' export const Controlled = () => { const collection = createListCollection({ items: [ { label: 'Small', value: 'sm' }, { label: 'Medium', value: 'md' }, { label: 'Large', value: 'lg' }, { label: 'Extra Large', value: 'xl' }, ], }) const [value, setValue] = createSignal(['md']) return ( setValue(e.value)}> Select Size {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte (value = e.value)}> Select Size {#each collection.items as item (item.value)} {item.label} {/each} ``` ### 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. **Example: root-provider** #### React ```tsx import { Listbox, createListCollection, useListbox } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/listbox.module.css' export const RootProvider = () => { const collection = createListCollection({ items: [ { label: 'Low', value: 'low' }, { label: 'Medium', value: 'medium' }, { label: 'High', value: 'high' }, { label: 'Critical', value: 'critical' }, ], }) const listbox = useListbox({ collection }) return (
                    Select Priority {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Listbox, createListCollection, useListbox } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/listbox.module.css' export const RootProvider = () => { const collection = createListCollection({ items: [ { label: 'Low', value: 'low' }, { label: 'Medium', value: 'medium' }, { label: 'High', value: 'high' }, { label: 'Critical', value: 'critical' }, ], }) const listbox = useListbox({ collection }) return (
                    Select Priority {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Select Priority {#each collection.items as item (item.value)} {item.label} {/each}
                    ``` ### Disabled Item Listbox items can be disabled using the `disabled` prop on the collection item. **Example: disabled-item** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const DisabledItem = () => { const collection = createListCollection({ items: [ { label: 'Free', value: 'free' }, { label: 'Pro', value: 'pro' }, { label: 'Enterprise', value: 'enterprise', disabled: true }, { label: 'Custom', value: 'custom' }, ], }) return ( Select Plan {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const DisabledItem = () => { const collection = createListCollection({ items: [ { label: 'Free', value: 'free' }, { label: 'Pro', value: 'pro' }, { label: 'Enterprise', value: 'enterprise', disabled: true }, { label: 'Custom', value: 'custom' }, ], }) return ( Select Plan {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Plan {#each collection.items as item (item.value)} {item.label} {/each} ``` > You can also use the `isItemDisabled` within the `createListCollection` to disable items based on a condition. ### Multiple You can set the `selectionMode` property as `multiple` to allow the user to select multiple items at a time. **Example: multiple** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const Multiple = () => { const collection = createListCollection({ items: [ { label: 'Monday', value: 'mon' }, { label: 'Tuesday', value: 'tue' }, { label: 'Wednesday', value: 'wed' }, { label: 'Thursday', value: 'thu' }, { label: 'Friday', value: 'fri' }, { label: 'Saturday', value: 'sat' }, { label: 'Sunday', value: 'sun' }, ], }) return ( Select Days {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const Multiple = () => { const collection = createListCollection({ items: [ { label: 'Monday', value: 'mon' }, { label: 'Tuesday', value: 'tue' }, { label: 'Wednesday', value: 'wed' }, { label: 'Thursday', value: 'thu' }, { label: 'Friday', value: 'fri' }, { label: 'Saturday', value: 'sat' }, { label: 'Sunday', value: 'sun' }, ], }) return ( Select Days {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Days {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Grouping The Listbox component supports grouping items. You can use the `groupBy` function to group items based on a specific property. **Example: group** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const Group = () => { const collection = createListCollection({ items: [ { label: 'New York', value: 'nyc', region: 'North America' }, { label: 'Los Angeles', value: 'lax', region: 'North America' }, { label: 'Toronto', value: 'yyz', region: 'North America' }, { label: 'London', value: 'lhr', region: 'Europe' }, { label: 'Paris', value: 'cdg', region: 'Europe' }, { label: 'Berlin', value: 'ber', region: 'Europe' }, { label: 'Tokyo', value: 'nrt', region: 'Asia Pacific' }, { label: 'Singapore', value: 'sin', region: 'Asia Pacific' }, { label: 'Sydney', value: 'syd', region: 'Asia Pacific' }, ], groupBy: (item) => item.region, }) return ( Select Region {collection.group().map(([region, items]) => ( {region} {items.map((item) => ( {item.label} ))} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/listbox.module.css' export const Group = () => { const collection = createListCollection({ items: [ { label: 'New York', value: 'nyc', region: 'North America' }, { label: 'Los Angeles', value: 'lax', region: 'North America' }, { label: 'Toronto', value: 'yyz', region: 'North America' }, { label: 'London', value: 'lhr', region: 'Europe' }, { label: 'Paris', value: 'cdg', region: 'Europe' }, { label: 'Berlin', value: 'ber', region: 'Europe' }, { label: 'Tokyo', value: 'nrt', region: 'Asia Pacific' }, { label: 'Singapore', value: 'sin', region: 'Asia Pacific' }, { label: 'Sydney', value: 'syd', region: 'Asia Pacific' }, ], groupBy: (item) => item.region, }) return ( Select Region {([region, items]) => ( {region} {(item) => ( {item.label} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Region {#each collection.group() as [region, items]} {region} {#each items as item (item.value)} {item.label} {/each} {/each} ``` ### Extended Selection The extended selection mode allows users to select multiple items using keyboard modifiers like `Cmd` (Mac) or `Ctrl` (Windows/Linux). **Example: extended-select** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const ExtendedSelect = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, { label: 'Preact', value: 'preact' }, ], }) return ( Hold or Ctrl to select multiple {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const ExtendedSelect = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, { label: 'Preact', value: 'preact' }, ], }) return ( Hold or Ctrl to select multiple {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Hold or Ctrl to select multiple {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Horizontal Use the `orientation` prop to display the listbox items horizontally. **Example: horizontal** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const Horizontal = () => { const collection = createListCollection({ items: [ { title: 'Midnight Dreams', artist: 'Luna Ray', image: 'https://picsum.photos/seed/album1/300/300', }, { title: 'Neon Skyline', artist: 'The Electric', image: 'https://picsum.photos/seed/album2/300/300', }, { title: 'Acoustic Sessions', artist: 'Sarah Woods', image: 'https://picsum.photos/seed/album3/300/300', }, { title: 'Urban Echoes', artist: 'Metro Collective', image: 'https://picsum.photos/seed/album4/300/300', }, { title: 'Summer Vibes', artist: 'Coastal Waves', image: 'https://picsum.photos/seed/album5/300/300', }, ], itemToValue: (item) => item.title, itemToString: (item) => item.title, }) return ( Select Album {collection.items.map((item) => ( {item.title} {item.title} {item.artist} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const Horizontal = () => { const collection = createListCollection({ items: [ { title: 'Midnight Dreams', artist: 'Luna Ray', image: 'https://picsum.photos/seed/album1/300/300', }, { title: 'Neon Skyline', artist: 'The Electric', image: 'https://picsum.photos/seed/album2/300/300', }, { title: 'Acoustic Sessions', artist: 'Sarah Woods', image: 'https://picsum.photos/seed/album3/300/300', }, { title: 'Urban Echoes', artist: 'Metro Collective', image: 'https://picsum.photos/seed/album4/300/300', }, { title: 'Summer Vibes', artist: 'Coastal Waves', image: 'https://picsum.photos/seed/album5/300/300', }, ], itemToValue: (item) => item.title, itemToString: (item) => item.title, }) return ( Select Album {(item) => ( {item().title} {item().title} {item().artist} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Album {#each collection.items as item (item.title)} {item.title} {item.title} {item.artist} {/each} ``` ### Grid Layout Use `createGridCollection` to display items in a grid layout with keyboard navigation support. **Example: grid** #### React ```tsx import { createGridCollection } from '@ark-ui/react/collection' import { Listbox } from '@ark-ui/react/listbox' import styles from 'styles/listbox.module.css' export const Grid = () => { const collection = createGridCollection({ items: [ { label: '😀', value: 'grinning' }, { label: '😍', value: 'heart-eyes' }, { label: '🥳', value: 'partying' }, { label: '😎', value: 'sunglasses' }, { label: '🤩', value: 'star-struck' }, { label: '😂', value: 'joy' }, { label: '🥰', value: 'smiling-hearts' }, { label: '😊', value: 'blush' }, { label: '🤗', value: 'hugging' }, { label: '😇', value: 'innocent' }, { label: '🔥', value: 'fire' }, { label: '✨', value: 'sparkles' }, { label: '💯', value: 'hundred' }, { label: '🎉', value: 'tada' }, { label: '❤️', value: 'heart' }, { label: '👍', value: 'thumbs-up' }, { label: '👏', value: 'clap' }, { label: '🚀', value: 'rocket' }, { label: '⭐', value: 'star' }, { label: '🌈', value: 'rainbow' }, ], columnCount: 5, }) return ( Pick a reaction {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { createGridCollection } from '@ark-ui/solid/collection' import { Listbox } from '@ark-ui/solid/listbox' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const Grid = () => { const collection = createGridCollection({ items: [ { label: '😀', value: 'grinning' }, { label: '😍', value: 'heart-eyes' }, { label: '🥳', value: 'partying' }, { label: '😎', value: 'sunglasses' }, { label: '🤩', value: 'star-struck' }, { label: '😂', value: 'joy' }, { label: '🥰', value: 'smiling-hearts' }, { label: '😊', value: 'blush' }, { label: '🤗', value: 'hugging' }, { label: '😇', value: 'innocent' }, { label: '🔥', value: 'fire' }, { label: '✨', value: 'sparkles' }, { label: '💯', value: 'hundred' }, { label: '🎉', value: 'tada' }, { label: '❤️', value: 'heart' }, { label: '👍', value: 'thumbs-up' }, { label: '👏', value: 'clap' }, { label: '🚀', value: 'rocket' }, { label: '⭐', value: 'star' }, { label: '🌈', value: 'rainbow' }, ], columnCount: 5, }) return ( Pick a reaction {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Pick a reaction {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Filtering Use `useListCollection` with the `filter` function to enable filtering of items. **Example: filtering** #### React ```tsx import { useListCollection } from '@ark-ui/react/collection' import { Listbox } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/listbox.module.css' export const Filtering = () => { const { collection, filter } = useListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, { label: 'Next.js', value: 'nextjs' }, { label: 'Nuxt.js', value: 'nuxtjs' }, { label: 'Remix', value: 'remix' }, { label: 'Gatsby', value: 'gatsby' }, { label: 'Preact', value: 'preact' }, ], filter: (itemText, filterText) => itemText.toLowerCase().includes(filterText.toLowerCase()), }) return ( Select Framework filter(e.target.value)} /> {collection.items.map((item) => ( {item.label} ))} No frameworks found ) } ``` #### Solid ```tsx import { useListCollection } from '@ark-ui/solid/collection' import { Listbox } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/listbox.module.css' export const Filtering = () => { const { collection, filter } = useListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, { label: 'Next.js', value: 'nextjs' }, { label: 'Nuxt.js', value: 'nuxtjs' }, { label: 'Remix', value: 'remix' }, { label: 'Gatsby', value: 'gatsby' }, { label: 'Preact', value: 'preact' }, ], filter: (itemText, filterText) => itemText.toLowerCase().includes(filterText.toLowerCase()), }) return ( Select Framework filter(e.target.value)} /> {(item) => ( {item().label} )} No frameworks found ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Framework filter(e.currentTarget.value)} /> {#each collection().items as item (item.value)} {item.label} {/each} No frameworks found ``` ### Select All Use `useListboxContext` to implement a "Select All" functionality that allows users to select or deselect all items at once. **Example: select-all** #### React ```tsx import { Listbox, createListCollection, useListboxContext } from '@ark-ui/react/listbox' import { CheckIcon, MinusIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Next.js', value: 'nextjs' }, { label: 'Nuxt.js', value: 'nuxtjs' }, { label: 'Remix', value: 'remix' }, { label: 'Gatsby', value: 'gatsby' }, ], }) const SelectAllHeader = () => { const listbox = useListboxContext() const isAllSelected = listbox.value.length === frameworks.items.length const isSomeSelected = listbox.value.length > 0 && listbox.value.length < frameworks.items.length const handleSelectAll = () => { if (isAllSelected) { listbox.setValue([]) } else { listbox.setValue(frameworks.items.map((item) => item.value)) } } return ( ) } export const SelectAll = () => { return ( {frameworks.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection, useListboxContext } from '@ark-ui/solid/listbox' import { CheckIcon, MinusIcon } from 'lucide-solid' import { Index, Show } from 'solid-js' import styles from 'styles/listbox.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Next.js', value: 'nextjs' }, { label: 'Nuxt.js', value: 'nuxtjs' }, { label: 'Remix', value: 'remix' }, { label: 'Gatsby', value: 'gatsby' }, ], }) const SelectAllHeader = () => { const listbox = useListboxContext() const isAllSelected = () => listbox().value.length === frameworks.items.length const isSomeSelected = () => listbox().value.length > 0 && listbox().value.length < frameworks.items.length const handleSelectAll = () => { if (isAllSelected()) { listbox().setValue([]) } else { listbox().setValue(frameworks.items.map((item) => item.value)) } } return ( ) } export const SelectAll = () => { return ( {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet selectAllHeader()} {/snippet} {@render selectAllHeader()} {#each frameworks.items as item (item.value)} {item.label} {/each} ``` ### Value Text Use `Listbox.ValueText` to display the selected values as a comma-separated string. **Example: value-text** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const ValueText = () => { const collection = createListCollection({ items: [ { label: 'Red', value: 'red' }, { label: 'Blue', value: 'blue' }, { label: 'Green', value: 'green' }, { label: 'Yellow', value: 'yellow' }, { label: 'Purple', value: 'purple' }, ], }) return ( Colors: {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const ValueText = () => { const collection = createListCollection({ items: [ { label: 'Red', value: 'red' }, { label: 'Blue', value: 'blue' }, { label: 'Green', value: 'green' }, { label: 'Yellow', value: 'yellow' }, { label: 'Purple', value: 'purple' }, ], }) return ( Colors: {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Colors: {#each collection.items as item (item.value)} {item.label} {/each} ``` ## Guides ### Type Safety The `Listbox.RootComponent` type enables you to create typed wrapper components that maintain full type safety for collection items. ```tsx const Listbox: ArkListbox.RootComponent = (props) => { return {/* ... */} } ``` Use the wrapper with full type inference on `onValueChange` and other callbacks: ```tsx const App = () => { const collection = createListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, ], }) return ( { // e.items is typed as Array<{ label: string, value: string }> console.log(e.items) }} > {/* ... */} ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the listbox. | | `defaultValue` | `string[]` | No | The initial default value of the listbox when rendered. Use when you don't need to control the value of the listbox. | | `deselectable` | `boolean` | No | Whether to disallow empty selection | | `disabled` | `boolean` | No | Whether the listbox is disabled | | `disallowSelectAll` | `boolean` | No | Whether to disallow selecting all items when `meta+a` is pressed | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string label: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the listbox. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the listbox. | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionMode` | `SelectionMode` | No | How multiple selection should behave in the listbox. - `single`: The user can select a single item. - `multiple`: The user can select multiple items without using modifier keys. - `extended`: The user can select multiple items by using modifier keys. | | `selectOnHighlight` | `boolean` | No | Whether to select the item when it is highlighted | | `typeahead` | `boolean` | No | Whether to enable typeahead on the listbox | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | root | | `[data-orientation]` | The orientation of the listbox | | `[data-disabled]` | Present when disabled | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | content | | `[data-activedescendant]` | The id the active descendant of the content | | `[data-orientation]` | The orientation of the content | | `[data-layout]` | | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--column-count` | The column count value for the Content | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoHighlight` | `boolean` | No | Whether to automatically highlight the item when typing | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `highlightOnHover` | `boolean` | No | Whether to highlight the item on hover | | `item` | `any` | No | The item to render | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-selected]` | Present when selected | | `[data-layout]` | | | `[data-state]` | "checked" | "unchecked" | | `[data-orientation]` | The orientation of the item | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseListboxReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is listboxed. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the listbox. | | `defaultValue` | `string[]` | No | The initial default value of the listbox when rendered. Use when you don't need to control the value of the listbox. | | `deselectable` | `boolean` | No | Whether to disallow empty selection | | `disabled` | `boolean` | No | Whether the listbox is disabled | | `disallowSelectAll` | `boolean` | No | Whether to disallow selecting all items when `meta+a` is pressed | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string label: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the listbox. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the listbox. | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionMode` | `SelectionMode` | No | How multiple selection should behave in the listbox. - `single`: The user can select a single item. - `multiple`: The user can select multiple items without using modifier keys. - `extended`: The user can select multiple items by using modifier keys. | | `selectOnHighlight` | `boolean` | No | Whether to select the item when it is highlighted | | `typeahead` | `boolean` | No | Whether to enable typeahead on the listbox | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | root | | `[data-orientation]` | The orientation of the listbox | | `[data-disabled]` | Present when disabled | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | content | | `[data-activedescendant]` | The id the active descendant of the content | | `[data-orientation]` | The orientation of the content | | `[data-layout]` | | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--column-count` | The column count value for the Content | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoHighlight` | `boolean` | No | Whether to automatically highlight the item when typing | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `highlightOnHover` | `boolean` | No | Whether to highlight the item on hover | | `item` | `any` | No | The item to render | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-selected]` | Present when selected | | `[data-layout]` | | | `[data-state]` | "checked" | "unchecked" | | `[data-orientation]` | The orientation of the item | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseListboxReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is selected. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the listbox. | | `defaultValue` | `string[]` | No | The initial default value of the listbox when rendered. Use when you don't need to control the value of the listbox. | | `deselectable` | `boolean` | No | Whether to disallow empty selection | | `disabled` | `boolean` | No | Whether the listbox is disabled | | `disallowSelectAll` | `boolean` | No | Whether to disallow selecting all items when `meta+a` is pressed | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string label: string item(id: string | number): string itemGroup(id: string | number): string itemGroupLabel(id: string | number): string }>` | No | The ids of the elements in the listbox. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `modelValue` | `string[]` | No | The model value of the listbox | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionMode` | `SelectionMode` | No | How multiple selection should behave in the listbox. - `single`: The user can select a single item. - `multiple`: The user can select multiple items without using modifier keys. - `extended`: The user can select multiple items by using modifier keys. | | `selectOnHighlight` | `boolean` | No | Whether to select the item when it is highlighted | | `typeahead` | `boolean` | No | Whether to enable typeahead on the listbox | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | root | | `[data-orientation]` | The orientation of the listbox | | `[data-disabled]` | Present when disabled | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | content | | `[data-activedescendant]` | The id the active descendant of the content | | `[data-orientation]` | The orientation of the content | | `[data-layout]` | | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--column-count` | The column count value for the Content | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `highlightOnHover` | `boolean` | No | Whether to highlight the item on hover | | `item` | `any` | No | The item to render | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-selected]` | Present when selected | | `[data-layout]` | | | `[data-state]` | "checked" | "unchecked" | | `[data-orientation]` | The orientation of the item | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ListboxApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the listbox. | | `defaultValue` | `string[]` | No | The initial default value of the listbox when rendered. Use when you don't need to control the value of the listbox. | | `deselectable` | `boolean` | No | Whether to disallow empty selection | | `disabled` | `boolean` | No | Whether the listbox is disabled | | `disallowSelectAll` | `boolean` | No | Whether to disallow selecting all items when `meta+a` is pressed | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string label: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the listbox. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the listbox. | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionMode` | `SelectionMode` | No | How multiple selection should behave in the listbox. - `single`: The user can select a single item. - `multiple`: The user can select multiple items without using modifier keys. - `extended`: The user can select multiple items by using modifier keys. | | `selectOnHighlight` | `boolean` | No | Whether to select the item when it is highlighted | | `typeahead` | `boolean` | No | Whether to enable typeahead on the listbox | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | root | | `[data-orientation]` | The orientation of the listbox | | `[data-disabled]` | Present when disabled | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | content | | `[data-activedescendant]` | The id the active descendant of the content | | `[data-orientation]` | The orientation of the content | | `[data-layout]` | | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--column-count` | The column count value for the Content | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseListboxContext]>` | Yes | | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoHighlight` | `boolean` | No | Whether to automatically highlight the item when typing | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseListboxItemContext]>` | Yes | | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `highlightOnHover` | `boolean` | No | Whether to highlight the item on hover | | `item` | `any` | No | The item to render | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-selected]` | Present when selected | | `[data-layout]` | | | `[data-state]` | "checked" | "unchecked" | | `[data-orientation]` | The orientation of the item | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseListboxReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is selected. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `empty` | `boolean` | Whether the select value is empty | | `highlightedValue` | `string` | The value of the highlighted item | | `highlightedItem` | `V` | The highlighted item | | `highlightValue` | `(value: string) => void` | Function to highlight a value | | `clearHighlightedValue` | `VoidFunction` | Function to clear the highlighted value | | `selectedItems` | `V[]` | The selected items | | `hasSelectedItems` | `boolean` | Whether there's a selected option | | `value` | `string[]` | The selected item keys | | `valueAsString` | `string` | The string representation of the selected items | | `selectValue` | `(value: string) => void` | Function to select a value | | `selectAll` | `VoidFunction` | Function to select all values. **Note**: This should only be called when the selectionMode is `multiple` or `extended`. Otherwise, an exception will be thrown. | | `setValue` | `(value: string[]) => void` | Function to set the value of the select | | `clearValue` | `(value?: string) => void` | Function to clear the value of the select. If a value is provided, it will only clear that value, otherwise, it will clear all values. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a select item | | `collection` | `ListCollection` | Function to toggle the select | | `disabled` | `boolean` | Whether the select is disabled | --- # Listbox (SOLID) ## Anatomy {/* */} ```tsx ``` ## Examples ### Basic Here's a basic example of the Listbox component. **Example: basic** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const Basic = () => { const collection = createListCollection({ items: [ { label: 'United States', value: 'us' }, { label: 'United Kingdom', value: 'uk' }, { label: 'Canada', value: 'ca' }, { label: 'Australia', value: 'au' }, { label: 'Germany', value: 'de' }, { label: 'France', value: 'fr' }, { label: 'Japan', value: 'jp' }, ], }) return ( Select Country {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const Basic = () => { const collection = createListCollection({ items: [ { label: 'United States', value: 'us' }, { label: 'United Kingdom', value: 'uk' }, { label: 'Canada', value: 'ca' }, { label: 'Australia', value: 'au' }, { label: 'Germany', value: 'de' }, { label: 'France', value: 'fr' }, { label: 'Japan', value: 'jp' }, ], }) return ( Select Country {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Country {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Controlled The Listbox component can be controlled by using the `value` and `onValueChange` props. This allows you to manage the selected value externally. **Example: controlled** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/listbox.module.css' export const Controlled = () => { const collection = createListCollection({ items: [ { label: 'Small', value: 'sm' }, { label: 'Medium', value: 'md' }, { label: 'Large', value: 'lg' }, { label: 'Extra Large', value: 'xl' }, ], }) const [value, setValue] = useState(['md']) return ( setValue(e.value)} > Select Size {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/listbox.module.css' export const Controlled = () => { const collection = createListCollection({ items: [ { label: 'Small', value: 'sm' }, { label: 'Medium', value: 'md' }, { label: 'Large', value: 'lg' }, { label: 'Extra Large', value: 'xl' }, ], }) const [value, setValue] = createSignal(['md']) return ( setValue(e.value)}> Select Size {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte (value = e.value)}> Select Size {#each collection.items as item (item.value)} {item.label} {/each} ``` ### 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. **Example: root-provider** #### React ```tsx import { Listbox, createListCollection, useListbox } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/listbox.module.css' export const RootProvider = () => { const collection = createListCollection({ items: [ { label: 'Low', value: 'low' }, { label: 'Medium', value: 'medium' }, { label: 'High', value: 'high' }, { label: 'Critical', value: 'critical' }, ], }) const listbox = useListbox({ collection }) return (
                    Select Priority {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Listbox, createListCollection, useListbox } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/listbox.module.css' export const RootProvider = () => { const collection = createListCollection({ items: [ { label: 'Low', value: 'low' }, { label: 'Medium', value: 'medium' }, { label: 'High', value: 'high' }, { label: 'Critical', value: 'critical' }, ], }) const listbox = useListbox({ collection }) return (
                    Select Priority {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Select Priority {#each collection.items as item (item.value)} {item.label} {/each}
                    ``` ### Disabled Item Listbox items can be disabled using the `disabled` prop on the collection item. **Example: disabled-item** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const DisabledItem = () => { const collection = createListCollection({ items: [ { label: 'Free', value: 'free' }, { label: 'Pro', value: 'pro' }, { label: 'Enterprise', value: 'enterprise', disabled: true }, { label: 'Custom', value: 'custom' }, ], }) return ( Select Plan {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const DisabledItem = () => { const collection = createListCollection({ items: [ { label: 'Free', value: 'free' }, { label: 'Pro', value: 'pro' }, { label: 'Enterprise', value: 'enterprise', disabled: true }, { label: 'Custom', value: 'custom' }, ], }) return ( Select Plan {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Plan {#each collection.items as item (item.value)} {item.label} {/each} ``` > You can also use the `isItemDisabled` within the `createListCollection` to disable items based on a condition. ### Multiple You can set the `selectionMode` property as `multiple` to allow the user to select multiple items at a time. **Example: multiple** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const Multiple = () => { const collection = createListCollection({ items: [ { label: 'Monday', value: 'mon' }, { label: 'Tuesday', value: 'tue' }, { label: 'Wednesday', value: 'wed' }, { label: 'Thursday', value: 'thu' }, { label: 'Friday', value: 'fri' }, { label: 'Saturday', value: 'sat' }, { label: 'Sunday', value: 'sun' }, ], }) return ( Select Days {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const Multiple = () => { const collection = createListCollection({ items: [ { label: 'Monday', value: 'mon' }, { label: 'Tuesday', value: 'tue' }, { label: 'Wednesday', value: 'wed' }, { label: 'Thursday', value: 'thu' }, { label: 'Friday', value: 'fri' }, { label: 'Saturday', value: 'sat' }, { label: 'Sunday', value: 'sun' }, ], }) return ( Select Days {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Days {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Grouping The Listbox component supports grouping items. You can use the `groupBy` function to group items based on a specific property. **Example: group** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const Group = () => { const collection = createListCollection({ items: [ { label: 'New York', value: 'nyc', region: 'North America' }, { label: 'Los Angeles', value: 'lax', region: 'North America' }, { label: 'Toronto', value: 'yyz', region: 'North America' }, { label: 'London', value: 'lhr', region: 'Europe' }, { label: 'Paris', value: 'cdg', region: 'Europe' }, { label: 'Berlin', value: 'ber', region: 'Europe' }, { label: 'Tokyo', value: 'nrt', region: 'Asia Pacific' }, { label: 'Singapore', value: 'sin', region: 'Asia Pacific' }, { label: 'Sydney', value: 'syd', region: 'Asia Pacific' }, ], groupBy: (item) => item.region, }) return ( Select Region {collection.group().map(([region, items]) => ( {region} {items.map((item) => ( {item.label} ))} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/listbox.module.css' export const Group = () => { const collection = createListCollection({ items: [ { label: 'New York', value: 'nyc', region: 'North America' }, { label: 'Los Angeles', value: 'lax', region: 'North America' }, { label: 'Toronto', value: 'yyz', region: 'North America' }, { label: 'London', value: 'lhr', region: 'Europe' }, { label: 'Paris', value: 'cdg', region: 'Europe' }, { label: 'Berlin', value: 'ber', region: 'Europe' }, { label: 'Tokyo', value: 'nrt', region: 'Asia Pacific' }, { label: 'Singapore', value: 'sin', region: 'Asia Pacific' }, { label: 'Sydney', value: 'syd', region: 'Asia Pacific' }, ], groupBy: (item) => item.region, }) return ( Select Region {([region, items]) => ( {region} {(item) => ( {item.label} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Region {#each collection.group() as [region, items]} {region} {#each items as item (item.value)} {item.label} {/each} {/each} ``` ### Extended Selection The extended selection mode allows users to select multiple items using keyboard modifiers like `Cmd` (Mac) or `Ctrl` (Windows/Linux). **Example: extended-select** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const ExtendedSelect = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, { label: 'Preact', value: 'preact' }, ], }) return ( Hold or Ctrl to select multiple {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const ExtendedSelect = () => { const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, { label: 'Preact', value: 'preact' }, ], }) return ( Hold or Ctrl to select multiple {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Hold or Ctrl to select multiple {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Horizontal Use the `orientation` prop to display the listbox items horizontally. **Example: horizontal** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const Horizontal = () => { const collection = createListCollection({ items: [ { title: 'Midnight Dreams', artist: 'Luna Ray', image: 'https://picsum.photos/seed/album1/300/300', }, { title: 'Neon Skyline', artist: 'The Electric', image: 'https://picsum.photos/seed/album2/300/300', }, { title: 'Acoustic Sessions', artist: 'Sarah Woods', image: 'https://picsum.photos/seed/album3/300/300', }, { title: 'Urban Echoes', artist: 'Metro Collective', image: 'https://picsum.photos/seed/album4/300/300', }, { title: 'Summer Vibes', artist: 'Coastal Waves', image: 'https://picsum.photos/seed/album5/300/300', }, ], itemToValue: (item) => item.title, itemToString: (item) => item.title, }) return ( Select Album {collection.items.map((item) => ( {item.title} {item.title} {item.artist} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const Horizontal = () => { const collection = createListCollection({ items: [ { title: 'Midnight Dreams', artist: 'Luna Ray', image: 'https://picsum.photos/seed/album1/300/300', }, { title: 'Neon Skyline', artist: 'The Electric', image: 'https://picsum.photos/seed/album2/300/300', }, { title: 'Acoustic Sessions', artist: 'Sarah Woods', image: 'https://picsum.photos/seed/album3/300/300', }, { title: 'Urban Echoes', artist: 'Metro Collective', image: 'https://picsum.photos/seed/album4/300/300', }, { title: 'Summer Vibes', artist: 'Coastal Waves', image: 'https://picsum.photos/seed/album5/300/300', }, ], itemToValue: (item) => item.title, itemToString: (item) => item.title, }) return ( Select Album {(item) => ( {item().title} {item().title} {item().artist} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Album {#each collection.items as item (item.title)} {item.title} {item.title} {item.artist} {/each} ``` ### Grid Layout Use `createGridCollection` to display items in a grid layout with keyboard navigation support. **Example: grid** #### React ```tsx import { createGridCollection } from '@ark-ui/react/collection' import { Listbox } from '@ark-ui/react/listbox' import styles from 'styles/listbox.module.css' export const Grid = () => { const collection = createGridCollection({ items: [ { label: '😀', value: 'grinning' }, { label: '😍', value: 'heart-eyes' }, { label: '🥳', value: 'partying' }, { label: '😎', value: 'sunglasses' }, { label: '🤩', value: 'star-struck' }, { label: '😂', value: 'joy' }, { label: '🥰', value: 'smiling-hearts' }, { label: '😊', value: 'blush' }, { label: '🤗', value: 'hugging' }, { label: '😇', value: 'innocent' }, { label: '🔥', value: 'fire' }, { label: '✨', value: 'sparkles' }, { label: '💯', value: 'hundred' }, { label: '🎉', value: 'tada' }, { label: '❤️', value: 'heart' }, { label: '👍', value: 'thumbs-up' }, { label: '👏', value: 'clap' }, { label: '🚀', value: 'rocket' }, { label: '⭐', value: 'star' }, { label: '🌈', value: 'rainbow' }, ], columnCount: 5, }) return ( Pick a reaction {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { createGridCollection } from '@ark-ui/solid/collection' import { Listbox } from '@ark-ui/solid/listbox' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const Grid = () => { const collection = createGridCollection({ items: [ { label: '😀', value: 'grinning' }, { label: '😍', value: 'heart-eyes' }, { label: '🥳', value: 'partying' }, { label: '😎', value: 'sunglasses' }, { label: '🤩', value: 'star-struck' }, { label: '😂', value: 'joy' }, { label: '🥰', value: 'smiling-hearts' }, { label: '😊', value: 'blush' }, { label: '🤗', value: 'hugging' }, { label: '😇', value: 'innocent' }, { label: '🔥', value: 'fire' }, { label: '✨', value: 'sparkles' }, { label: '💯', value: 'hundred' }, { label: '🎉', value: 'tada' }, { label: '❤️', value: 'heart' }, { label: '👍', value: 'thumbs-up' }, { label: '👏', value: 'clap' }, { label: '🚀', value: 'rocket' }, { label: '⭐', value: 'star' }, { label: '🌈', value: 'rainbow' }, ], columnCount: 5, }) return ( Pick a reaction {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Pick a reaction {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Filtering Use `useListCollection` with the `filter` function to enable filtering of items. **Example: filtering** #### React ```tsx import { useListCollection } from '@ark-ui/react/collection' import { Listbox } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/listbox.module.css' export const Filtering = () => { const { collection, filter } = useListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, { label: 'Next.js', value: 'nextjs' }, { label: 'Nuxt.js', value: 'nuxtjs' }, { label: 'Remix', value: 'remix' }, { label: 'Gatsby', value: 'gatsby' }, { label: 'Preact', value: 'preact' }, ], filter: (itemText, filterText) => itemText.toLowerCase().includes(filterText.toLowerCase()), }) return ( Select Framework filter(e.target.value)} /> {collection.items.map((item) => ( {item.label} ))} No frameworks found ) } ``` #### Solid ```tsx import { useListCollection } from '@ark-ui/solid/collection' import { Listbox } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/listbox.module.css' export const Filtering = () => { const { collection, filter } = useListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, { label: 'Next.js', value: 'nextjs' }, { label: 'Nuxt.js', value: 'nuxtjs' }, { label: 'Remix', value: 'remix' }, { label: 'Gatsby', value: 'gatsby' }, { label: 'Preact', value: 'preact' }, ], filter: (itemText, filterText) => itemText.toLowerCase().includes(filterText.toLowerCase()), }) return ( Select Framework filter(e.target.value)} /> {(item) => ( {item().label} )} No frameworks found ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Select Framework filter(e.currentTarget.value)} /> {#each collection().items as item (item.value)} {item.label} {/each} No frameworks found ``` ### Select All Use `useListboxContext` to implement a "Select All" functionality that allows users to select or deselect all items at once. **Example: select-all** #### React ```tsx import { Listbox, createListCollection, useListboxContext } from '@ark-ui/react/listbox' import { CheckIcon, MinusIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Next.js', value: 'nextjs' }, { label: 'Nuxt.js', value: 'nuxtjs' }, { label: 'Remix', value: 'remix' }, { label: 'Gatsby', value: 'gatsby' }, ], }) const SelectAllHeader = () => { const listbox = useListboxContext() const isAllSelected = listbox.value.length === frameworks.items.length const isSomeSelected = listbox.value.length > 0 && listbox.value.length < frameworks.items.length const handleSelectAll = () => { if (isAllSelected) { listbox.setValue([]) } else { listbox.setValue(frameworks.items.map((item) => item.value)) } } return ( ) } export const SelectAll = () => { return ( {frameworks.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection, useListboxContext } from '@ark-ui/solid/listbox' import { CheckIcon, MinusIcon } from 'lucide-solid' import { Index, Show } from 'solid-js' import styles from 'styles/listbox.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Angular', value: 'angular' }, { label: 'Svelte', value: 'svelte' }, { label: 'Next.js', value: 'nextjs' }, { label: 'Nuxt.js', value: 'nuxtjs' }, { label: 'Remix', value: 'remix' }, { label: 'Gatsby', value: 'gatsby' }, ], }) const SelectAllHeader = () => { const listbox = useListboxContext() const isAllSelected = () => listbox().value.length === frameworks.items.length const isSomeSelected = () => listbox().value.length > 0 && listbox().value.length < frameworks.items.length const handleSelectAll = () => { if (isAllSelected()) { listbox().setValue([]) } else { listbox().setValue(frameworks.items.map((item) => item.value)) } } return ( ) } export const SelectAll = () => { return ( {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet selectAllHeader()} {/snippet} {@render selectAllHeader()} {#each frameworks.items as item (item.value)} {item.label} {/each} ``` ### Value Text Use `Listbox.ValueText` to display the selected values as a comma-separated string. **Example: value-text** #### React ```tsx import { Listbox, createListCollection } from '@ark-ui/react/listbox' import { CheckIcon } from 'lucide-react' import styles from 'styles/listbox.module.css' export const ValueText = () => { const collection = createListCollection({ items: [ { label: 'Red', value: 'red' }, { label: 'Blue', value: 'blue' }, { label: 'Green', value: 'green' }, { label: 'Yellow', value: 'yellow' }, { label: 'Purple', value: 'purple' }, ], }) return ( Colors: {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Listbox, createListCollection } from '@ark-ui/solid/listbox' import { CheckIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/listbox.module.css' export const ValueText = () => { const collection = createListCollection({ items: [ { label: 'Red', value: 'red' }, { label: 'Blue', value: 'blue' }, { label: 'Green', value: 'green' }, { label: 'Yellow', value: 'yellow' }, { label: 'Purple', value: 'purple' }, ], }) return ( Colors: {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Colors: {#each collection.items as item (item.value)} {item.label} {/each} ``` ## Guides ### Type Safety The `Listbox.RootComponent` type enables you to create typed wrapper components that maintain full type safety for collection items. ```tsx const Listbox: ArkListbox.RootComponent = (props) => { return {/* ... */} } ``` Use the wrapper with full type inference on `onValueChange` and other callbacks: ```tsx const App = () => { const collection = createListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, ], }) return ( { // e.items is typed as Array<{ label: string, value: string }> console.log(e.items) }} > {/* ... */} ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the listbox. | | `defaultValue` | `string[]` | No | The initial default value of the listbox when rendered. Use when you don't need to control the value of the listbox. | | `deselectable` | `boolean` | No | Whether to disallow empty selection | | `disabled` | `boolean` | No | Whether the listbox is disabled | | `disallowSelectAll` | `boolean` | No | Whether to disallow selecting all items when `meta+a` is pressed | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string label: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the listbox. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the listbox. | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionMode` | `SelectionMode` | No | How multiple selection should behave in the listbox. - `single`: The user can select a single item. - `multiple`: The user can select multiple items without using modifier keys. - `extended`: The user can select multiple items by using modifier keys. | | `selectOnHighlight` | `boolean` | No | Whether to select the item when it is highlighted | | `typeahead` | `boolean` | No | Whether to enable typeahead on the listbox | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | root | | `[data-orientation]` | The orientation of the listbox | | `[data-disabled]` | Present when disabled | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | content | | `[data-activedescendant]` | The id the active descendant of the content | | `[data-orientation]` | The orientation of the content | | `[data-layout]` | | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--column-count` | The column count value for the Content | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoHighlight` | `boolean` | No | Whether to automatically highlight the item when typing | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `highlightOnHover` | `boolean` | No | Whether to highlight the item on hover | | `item` | `any` | No | The item to render | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-selected]` | Present when selected | | `[data-layout]` | | | `[data-state]` | "checked" | "unchecked" | | `[data-orientation]` | The orientation of the item | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseListboxReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is listboxed. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the listbox. | | `defaultValue` | `string[]` | No | The initial default value of the listbox when rendered. Use when you don't need to control the value of the listbox. | | `deselectable` | `boolean` | No | Whether to disallow empty selection | | `disabled` | `boolean` | No | Whether the listbox is disabled | | `disallowSelectAll` | `boolean` | No | Whether to disallow selecting all items when `meta+a` is pressed | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string label: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the listbox. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the listbox. | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionMode` | `SelectionMode` | No | How multiple selection should behave in the listbox. - `single`: The user can select a single item. - `multiple`: The user can select multiple items without using modifier keys. - `extended`: The user can select multiple items by using modifier keys. | | `selectOnHighlight` | `boolean` | No | Whether to select the item when it is highlighted | | `typeahead` | `boolean` | No | Whether to enable typeahead on the listbox | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | root | | `[data-orientation]` | The orientation of the listbox | | `[data-disabled]` | Present when disabled | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | content | | `[data-activedescendant]` | The id the active descendant of the content | | `[data-orientation]` | The orientation of the content | | `[data-layout]` | | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--column-count` | The column count value for the Content | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoHighlight` | `boolean` | No | Whether to automatically highlight the item when typing | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `highlightOnHover` | `boolean` | No | Whether to highlight the item on hover | | `item` | `any` | No | The item to render | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-selected]` | Present when selected | | `[data-layout]` | | | `[data-state]` | "checked" | "unchecked" | | `[data-orientation]` | The orientation of the item | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseListboxReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is selected. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the listbox. | | `defaultValue` | `string[]` | No | The initial default value of the listbox when rendered. Use when you don't need to control the value of the listbox. | | `deselectable` | `boolean` | No | Whether to disallow empty selection | | `disabled` | `boolean` | No | Whether the listbox is disabled | | `disallowSelectAll` | `boolean` | No | Whether to disallow selecting all items when `meta+a` is pressed | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string label: string item(id: string | number): string itemGroup(id: string | number): string itemGroupLabel(id: string | number): string }>` | No | The ids of the elements in the listbox. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `modelValue` | `string[]` | No | The model value of the listbox | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionMode` | `SelectionMode` | No | How multiple selection should behave in the listbox. - `single`: The user can select a single item. - `multiple`: The user can select multiple items without using modifier keys. - `extended`: The user can select multiple items by using modifier keys. | | `selectOnHighlight` | `boolean` | No | Whether to select the item when it is highlighted | | `typeahead` | `boolean` | No | Whether to enable typeahead on the listbox | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | root | | `[data-orientation]` | The orientation of the listbox | | `[data-disabled]` | Present when disabled | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | content | | `[data-activedescendant]` | The id the active descendant of the content | | `[data-orientation]` | The orientation of the content | | `[data-layout]` | | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--column-count` | The column count value for the Content | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `highlightOnHover` | `boolean` | No | Whether to highlight the item on hover | | `item` | `any` | No | The item to render | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-selected]` | Present when selected | | `[data-layout]` | | | `[data-state]` | "checked" | "unchecked" | | `[data-orientation]` | The orientation of the item | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ListboxApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the listbox. | | `defaultValue` | `string[]` | No | The initial default value of the listbox when rendered. Use when you don't need to control the value of the listbox. | | `deselectable` | `boolean` | No | Whether to disallow empty selection | | `disabled` | `boolean` | No | Whether the listbox is disabled | | `disallowSelectAll` | `boolean` | No | Whether to disallow selecting all items when `meta+a` is pressed | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string label: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the listbox. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the listbox. | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `selectionMode` | `SelectionMode` | No | How multiple selection should behave in the listbox. - `single`: The user can select a single item. - `multiple`: The user can select multiple items without using modifier keys. - `extended`: The user can select multiple items by using modifier keys. | | `selectOnHighlight` | `boolean` | No | Whether to select the item when it is highlighted | | `typeahead` | `boolean` | No | Whether to enable typeahead on the listbox | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | root | | `[data-orientation]` | The orientation of the listbox | | `[data-disabled]` | Present when disabled | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | content | | `[data-activedescendant]` | The id the active descendant of the content | | `[data-orientation]` | The orientation of the content | | `[data-layout]` | | | `[data-empty]` | Present when the content is empty | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--column-count` | The column count value for the Content | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseListboxContext]>` | Yes | | **Empty Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoHighlight` | `boolean` | No | Whether to automatically highlight the item when typing | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseListboxItemContext]>` | Yes | | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-empty]` | Present when the content is empty | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `highlightOnHover` | `boolean` | No | Whether to highlight the item on hover | | `item` | `any` | No | The item to render | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-selected]` | Present when selected | | `[data-layout]` | | | `[data-state]` | "checked" | "unchecked" | | `[data-orientation]` | The orientation of the item | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseListboxReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is selected. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | listbox | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `empty` | `boolean` | Whether the select value is empty | | `highlightedValue` | `string` | The value of the highlighted item | | `highlightedItem` | `V` | The highlighted item | | `highlightValue` | `(value: string) => void` | Function to highlight a value | | `clearHighlightedValue` | `VoidFunction` | Function to clear the highlighted value | | `selectedItems` | `V[]` | The selected items | | `hasSelectedItems` | `boolean` | Whether there's a selected option | | `value` | `string[]` | The selected item keys | | `valueAsString` | `string` | The string representation of the selected items | | `selectValue` | `(value: string) => void` | Function to select a value | | `selectAll` | `VoidFunction` | Function to select all values. **Note**: This should only be called when the selectionMode is `multiple` or `extended`. Otherwise, an exception will be thrown. | | `setValue` | `(value: string[]) => void` | Function to set the value of the select | | `clearValue` | `(value?: string) => void` | Function to clear the value of the select. If a value is provided, it will only clear that value, otherwise, it will clear all values. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a select item | | `collection` | `ListCollection` | Function to toggle the select | | `disabled` | `boolean` | Whether the select is disabled | --- # Marquee (REACT) ## Anatomy {/* */} ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Basic = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Basic = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Auto Fill Use the `autoFill` prop to automatically duplicate content to fill the viewport. The `spacing` prop controls the gap between duplicated content instances: **Example: auto-fill** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, ] export const AutoFill = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, ] export const AutoFill = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Reverse Set the `reverse` prop to reverse the scroll direction: **Example: reverse** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Reverse = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Reverse = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Vertical Set `side="bottom"` (or `side="top"`) to create a vertical marquee: **Example: vertical** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Vertical = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Vertical = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Speed Control the animation speed using the `speed` prop, which accepts values in pixels per second: **Example: speed** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Speed = () => (

                    Slow (25px/s)

                    {items.map((item, i) => ( {item.logo} {item.name} ))}

                    Normal (50px/s)

                    {items.map((item, i) => ( {item.logo} {item.name} ))}

                    Fast (100px/s)

                    {items.map((item, i) => ( {item.logo} {item.name} ))}
                    ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Speed = () => (

                    Slow (25px/s)

                    {(item) => ( {item.logo} {item.name} )}

                    Normal (50px/s)

                    {(item) => ( {item.logo} {item.name} )}

                    Fast (100px/s)

                    {(item) => ( {item.logo} {item.name} )}
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Slow (25px/s)

                    {#each items as item} {item.logo} {item.name} {/each}

                    Normal (50px/s)

                    {#each items as item} {item.logo} {item.name} {/each}

                    Fast (100px/s)

                    {#each items as item} {item.logo} {item.name} {/each}
                    ``` ### Pause on Interaction Enable `pauseOnInteraction` to pause the marquee when users hover or focus on it, improving accessibility: **Example: pause-on-interaction** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const PauseOnInteraction = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const PauseOnInteraction = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Programmatic Control Use the `useMarquee` hook with `Marquee.RootProvider` to access the marquee API and control playback programmatically: **Example: programmatic-control** #### React ```tsx import { Marquee, useMarquee } from '@ark-ui/react/marquee' import button from 'styles/button.module.css' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const ProgrammaticControl = () => { const marquee = useMarquee() return (
                    {items.map((item, i) => ( {item.logo} {item.name} ))}
                    ) } ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee, useMarquee } from '@ark-ui/solid/marquee' import button from 'styles/button.module.css' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const ProgrammaticControl = () => { const marquee = useMarquee() return (
                    {(item) => ( {item.logo} {item.name} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each items as item} {item.logo} {item.name} {/each}
                    ``` > 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: **Example: finite-loops** #### React ```tsx import { useState } from 'react' import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const FiniteLoops = () => { const [loopCount, setLoopCount] = useState(0) const [completedCount, setCompletedCount] = useState(0) return (
                    setLoopCount((prev) => prev + 1)} onComplete={() => setCompletedCount((prev) => prev + 1)} className={styles.Root} > {items.map((item, i) => ( {item.logo} {item.name} ))}

                    Loop completed: {loopCount} times

                    Animation completed: {completedCount} times

                    ) } ``` #### Solid ```tsx import { For, createSignal } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const FiniteLoops = () => { const [loopCount, setLoopCount] = createSignal(0) const [completedCount, setCompletedCount] = createSignal(0) return (
                    setLoopCount((prev) => prev + 1)} onComplete={() => setCompletedCount((prev) => prev + 1)} class={styles.Root} > {(item) => ( {item.logo} {item.name} )}

                    Loop completed: {loopCount()} times

                    Animation completed: {completedCount()} times

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    loopCount++} onComplete={() => completedCount++} class={styles.Root} > {#each items as item} {item.logo} {item.name} {/each}

                    Loop completed: {loopCount} times

                    Animation completed: {completedCount} times

                    ``` ### Edges Add `Marquee.Edge` components to create fade effects at the start and end of the scrolling area: **Example: with-edges** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const WithEdges = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const WithEdges = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ## Guides ### Content Animation The Marquee component requires CSS keyframe animations to function properly. You'll need to define animations for both horizontal and vertical scrolling: ```css @keyframes marqueeX { from { transform: translateX(0); } to { transform: translateX(var(--marquee-translate)); } } @keyframes marqueeY { from { transform: translateY(0); } to { transform: translateY(var(--marquee-translate)); } } ``` The component automatically applies the appropriate animation (`marqueeX` or `marqueeY`) based on the scroll direction and uses the `--marquee-translate` CSS variable for seamless looping. You can target specific parts of the marquee using `data-part` attributes for custom styling: - `[data-part="root"]` - The root container - `[data-part="viewport"]` - The scrolling viewport - `[data-part="content"]` - The content wrapper (receives animation) - `[data-part="item"]` - Individual marquee items - `[data-part="edge"]` - Edge gradient overlays ### Best Practices - **Enable pause-on-interaction**: Use `pauseOnInteraction` to allow users to pause animations on hover or focus, improving accessibility and readability - **Use descriptive labels**: Provide meaningful `aria-label` values that describe the marquee content (e.g., "Partner logos", "Latest announcements") - **Avoid for critical information**: Don't use marquees for essential content that users must read, as continuously moving text can be difficult to process. Consider static displays for important information ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFill` | `boolean` | No | Whether to automatically duplicate content to fill the container. | | `defaultPaused` | `boolean` | No | Whether the marquee is paused by default. | | `delay` | `number` | No | The delay before the animation starts (in seconds). | | `ids` | `Partial<{ root: string; viewport: string; content: (index: number) => string }>` | No | The ids of the elements in the marquee. Useful for composition. | | `loopCount` | `number` | No | The number of times to loop the animation (0 = infinite). | | `onComplete` | `() => void` | No | Function called when the marquee completes all loops and stops. Only fires for finite loops (loopCount > 0). | | `onLoopComplete` | `() => void` | No | Function called when the marquee completes one loop iteration. | | `onPauseChange` | `(details: PauseStatusDetails) => void` | No | Function called when the pause status changes. | | `paused` | `boolean` | No | Whether the marquee is paused. | | `pauseOnInteraction` | `boolean` | No | Whether to pause the marquee on user interaction (hover, focus). | | `reverse` | `boolean` | No | Whether to reverse the animation direction. | | `side` | `Side` | No | The side/direction the marquee scrolls towards. | | `spacing` | `string` | No | The spacing between marquee items. | | `speed` | `number` | No | The speed of the marquee animation in pixels per second. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | root | | `[data-state]` | "paused" | "idle" | | `[data-orientation]` | The orientation of the marquee | | `[data-paused]` | Present when paused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--marquee-duration` | The marquee duration value for the Root | | `--marquee-spacing` | The marquee spacing value for the Root | | `--marquee-delay` | The marquee delay value for the Root | | `--marquee-loop-count` | The marquee loop count value for the Root | | `--marquee-translate` | The marquee translate value for the Root | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-index]` | The index of the item | | `[data-orientation]` | The orientation of the content | | `[data-side]` | | | `[data-reverse]` | | | `[data-clone]` | | **Edge Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `side` | `Side` | Yes | The side where the edge gradient should appear. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Edge Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-side]` | | | `[data-orientation]` | The orientation of the edge | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMarqueeReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-orientation]` | The orientation of the viewport | | `[data-side]` | | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFill` | `boolean` | No | Whether to automatically duplicate content to fill the container. | | `defaultPaused` | `boolean` | No | Whether the marquee is paused by default. | | `delay` | `number` | No | The delay before the animation starts (in seconds). | | `ids` | `Partial<{ root: string; viewport: string; content: (index: number) => string }>` | No | The ids of the elements in the marquee. Useful for composition. | | `loopCount` | `number` | No | The number of times to loop the animation (0 = infinite). | | `onComplete` | `() => void` | No | Function called when the marquee completes all loops and stops. Only fires for finite loops (loopCount > 0). | | `onLoopComplete` | `() => void` | No | Function called when the marquee completes one loop iteration. | | `onPauseChange` | `(details: PauseStatusDetails) => void` | No | Function called when the pause status changes. | | `paused` | `boolean` | No | Whether the marquee is paused. | | `pauseOnInteraction` | `boolean` | No | Whether to pause the marquee on user interaction (hover, focus). | | `reverse` | `boolean` | No | Whether to reverse the animation direction. | | `side` | `Side` | No | The side/direction the marquee scrolls towards. | | `spacing` | `string` | No | The spacing between marquee items. | | `speed` | `number` | No | The speed of the marquee animation in pixels per second. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | root | | `[data-state]` | "paused" | "idle" | | `[data-orientation]` | The orientation of the marquee | | `[data-paused]` | Present when paused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--marquee-duration` | The marquee duration value for the Root | | `--marquee-spacing` | The marquee spacing value for the Root | | `--marquee-delay` | The marquee delay value for the Root | | `--marquee-loop-count` | The marquee loop count value for the Root | | `--marquee-translate` | The marquee translate value for the Root | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-index]` | The index of the item | | `[data-orientation]` | The orientation of the content | | `[data-side]` | | | `[data-reverse]` | | | `[data-clone]` | | **Edge Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `side` | `Side` | Yes | The side where the edge gradient should appear. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Edge Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-side]` | | | `[data-orientation]` | The orientation of the edge | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMarqueeReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-orientation]` | The orientation of the viewport | | `[data-side]` | | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFill` | `boolean` | No | Whether to automatically duplicate content to fill the container. | | `defaultPaused` | `boolean` | No | Whether the marquee is paused by default. | | `delay` | `number` | No | The delay before the animation starts (in seconds). | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: (index: number) => string }>` | No | The ids of the elements in the marquee. Useful for composition. | | `loopCount` | `number` | No | The number of times to loop the animation (0 = infinite). | | `paused` | `boolean` | No | Whether the marquee is paused. | | `pauseOnInteraction` | `boolean` | No | Whether to pause the marquee on user interaction (hover, focus). | | `reverse` | `boolean` | No | Whether to reverse the animation direction. | | `side` | `Side` | No | The side/direction the marquee scrolls towards. | | `spacing` | `string` | No | The spacing between marquee items. | | `speed` | `number` | No | The speed of the marquee animation in pixels per second. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | root | | `[data-state]` | "paused" | "idle" | | `[data-orientation]` | The orientation of the marquee | | `[data-paused]` | Present when paused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--marquee-duration` | The marquee duration value for the Root | | `--marquee-spacing` | The marquee spacing value for the Root | | `--marquee-delay` | The marquee delay value for the Root | | `--marquee-loop-count` | The marquee loop count value for the Root | | `--marquee-translate` | The marquee translate value for the Root | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-index]` | The index of the item | | `[data-orientation]` | The orientation of the content | | `[data-side]` | | | `[data-reverse]` | | | `[data-clone]` | | **Edge Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `side` | `Side` | Yes | The side where the edge gradient should appear. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Edge Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-side]` | | | `[data-orientation]` | The orientation of the edge | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `MarqueeApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-orientation]` | The orientation of the viewport | | `[data-side]` | | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFill` | `boolean` | No | Whether to automatically duplicate content to fill the container. | | `defaultPaused` | `boolean` | No | Whether the marquee is paused by default. | | `delay` | `number` | No | The delay before the animation starts (in seconds). | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: (index: number) => string }>` | No | The ids of the elements in the marquee. Useful for composition. | | `loopCount` | `number` | No | The number of times to loop the animation (0 = infinite). | | `onComplete` | `() => void` | No | Function called when the marquee completes all loops and stops. Only fires for finite loops (loopCount > 0). | | `onLoopComplete` | `() => void` | No | Function called when the marquee completes one loop iteration. | | `onPauseChange` | `(details: PauseStatusDetails) => void` | No | Function called when the pause status changes. | | `paused` | `boolean` | No | Whether the marquee is paused. | | `pauseOnInteraction` | `boolean` | No | Whether to pause the marquee on user interaction (hover, focus). | | `ref` | `Element` | No | | | `reverse` | `boolean` | No | Whether to reverse the animation direction. | | `side` | `Side` | No | The side/direction the marquee scrolls towards. | | `spacing` | `string` | No | The spacing between marquee items. | | `speed` | `number` | No | The speed of the marquee animation in pixels per second. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | root | | `[data-state]` | "paused" | "idle" | | `[data-orientation]` | The orientation of the marquee | | `[data-paused]` | Present when paused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--marquee-duration` | The marquee duration value for the Root | | `--marquee-spacing` | The marquee spacing value for the Root | | `--marquee-delay` | The marquee delay value for the Root | | `--marquee-loop-count` | The marquee loop count value for the Root | | `--marquee-translate` | The marquee translate value for the Root | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-index]` | The index of the item | | `[data-orientation]` | The orientation of the content | | `[data-side]` | | | `[data-reverse]` | | | `[data-clone]` | | **Edge Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `side` | `Side` | Yes | The side where the edge gradient should appear. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Edge Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-side]` | | | `[data-orientation]` | The orientation of the edge | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMarqueeReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-orientation]` | The orientation of the viewport | | `[data-side]` | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `paused` | `boolean` | Whether the marquee is currently paused. | | `orientation` | `"horizontal" | "vertical"` | The current orientation of the marquee. | | `side` | `Side` | The current side/direction of the marquee. | | `multiplier` | `number` | The multiplier for auto-fill. Indicates how many times to duplicate content. When autoFill is enabled and content is smaller than container, this returns the number of additional copies needed. Otherwise returns 1. | | `contentCount` | `number` | The total number of content elements to render (original + clones). Use this value when rendering your content in a loop. | | `pause` | `VoidFunction` | Pause the marquee animation. | | `resume` | `VoidFunction` | Resume the marquee animation. | | `togglePause` | `VoidFunction` | Toggle the pause state. | | `restart` | `VoidFunction` | Restart the marquee animation from the beginning. | --- # Marquee (VUE) ## Anatomy {/* */} ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Basic = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Basic = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Auto Fill Use the `autoFill` prop to automatically duplicate content to fill the viewport. The `spacing` prop controls the gap between duplicated content instances: **Example: auto-fill** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, ] export const AutoFill = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, ] export const AutoFill = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Reverse Set the `reverse` prop to reverse the scroll direction: **Example: reverse** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Reverse = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Reverse = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Vertical Set `side="bottom"` (or `side="top"`) to create a vertical marquee: **Example: vertical** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Vertical = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Vertical = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Speed Control the animation speed using the `speed` prop, which accepts values in pixels per second: **Example: speed** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Speed = () => (

                    Slow (25px/s)

                    {items.map((item, i) => ( {item.logo} {item.name} ))}

                    Normal (50px/s)

                    {items.map((item, i) => ( {item.logo} {item.name} ))}

                    Fast (100px/s)

                    {items.map((item, i) => ( {item.logo} {item.name} ))}
                    ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Speed = () => (

                    Slow (25px/s)

                    {(item) => ( {item.logo} {item.name} )}

                    Normal (50px/s)

                    {(item) => ( {item.logo} {item.name} )}

                    Fast (100px/s)

                    {(item) => ( {item.logo} {item.name} )}
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Slow (25px/s)

                    {#each items as item} {item.logo} {item.name} {/each}

                    Normal (50px/s)

                    {#each items as item} {item.logo} {item.name} {/each}

                    Fast (100px/s)

                    {#each items as item} {item.logo} {item.name} {/each}
                    ``` ### Pause on Interaction Enable `pauseOnInteraction` to pause the marquee when users hover or focus on it, improving accessibility: **Example: pause-on-interaction** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const PauseOnInteraction = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const PauseOnInteraction = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Programmatic Control Use the `useMarquee` hook with `Marquee.RootProvider` to access the marquee API and control playback programmatically: **Example: programmatic-control** #### React ```tsx import { Marquee, useMarquee } from '@ark-ui/react/marquee' import button from 'styles/button.module.css' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const ProgrammaticControl = () => { const marquee = useMarquee() return (
                    {items.map((item, i) => ( {item.logo} {item.name} ))}
                    ) } ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee, useMarquee } from '@ark-ui/solid/marquee' import button from 'styles/button.module.css' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const ProgrammaticControl = () => { const marquee = useMarquee() return (
                    {(item) => ( {item.logo} {item.name} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each items as item} {item.logo} {item.name} {/each}
                    ``` > 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: **Example: finite-loops** #### React ```tsx import { useState } from 'react' import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const FiniteLoops = () => { const [loopCount, setLoopCount] = useState(0) const [completedCount, setCompletedCount] = useState(0) return (
                    setLoopCount((prev) => prev + 1)} onComplete={() => setCompletedCount((prev) => prev + 1)} className={styles.Root} > {items.map((item, i) => ( {item.logo} {item.name} ))}

                    Loop completed: {loopCount} times

                    Animation completed: {completedCount} times

                    ) } ``` #### Solid ```tsx import { For, createSignal } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const FiniteLoops = () => { const [loopCount, setLoopCount] = createSignal(0) const [completedCount, setCompletedCount] = createSignal(0) return (
                    setLoopCount((prev) => prev + 1)} onComplete={() => setCompletedCount((prev) => prev + 1)} class={styles.Root} > {(item) => ( {item.logo} {item.name} )}

                    Loop completed: {loopCount()} times

                    Animation completed: {completedCount()} times

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    loopCount++} onComplete={() => completedCount++} class={styles.Root} > {#each items as item} {item.logo} {item.name} {/each}

                    Loop completed: {loopCount} times

                    Animation completed: {completedCount} times

                    ``` ### Edges Add `Marquee.Edge` components to create fade effects at the start and end of the scrolling area: **Example: with-edges** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const WithEdges = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const WithEdges = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ## Guides ### Content Animation The Marquee component requires CSS keyframe animations to function properly. You'll need to define animations for both horizontal and vertical scrolling: ```css @keyframes marqueeX { from { transform: translateX(0); } to { transform: translateX(var(--marquee-translate)); } } @keyframes marqueeY { from { transform: translateY(0); } to { transform: translateY(var(--marquee-translate)); } } ``` The component automatically applies the appropriate animation (`marqueeX` or `marqueeY`) based on the scroll direction and uses the `--marquee-translate` CSS variable for seamless looping. You can target specific parts of the marquee using `data-part` attributes for custom styling: - `[data-part="root"]` - The root container - `[data-part="viewport"]` - The scrolling viewport - `[data-part="content"]` - The content wrapper (receives animation) - `[data-part="item"]` - Individual marquee items - `[data-part="edge"]` - Edge gradient overlays ### Best Practices - **Enable pause-on-interaction**: Use `pauseOnInteraction` to allow users to pause animations on hover or focus, improving accessibility and readability - **Use descriptive labels**: Provide meaningful `aria-label` values that describe the marquee content (e.g., "Partner logos", "Latest announcements") - **Avoid for critical information**: Don't use marquees for essential content that users must read, as continuously moving text can be difficult to process. Consider static displays for important information ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFill` | `boolean` | No | Whether to automatically duplicate content to fill the container. | | `defaultPaused` | `boolean` | No | Whether the marquee is paused by default. | | `delay` | `number` | No | The delay before the animation starts (in seconds). | | `ids` | `Partial<{ root: string; viewport: string; content: (index: number) => string }>` | No | The ids of the elements in the marquee. Useful for composition. | | `loopCount` | `number` | No | The number of times to loop the animation (0 = infinite). | | `onComplete` | `() => void` | No | Function called when the marquee completes all loops and stops. Only fires for finite loops (loopCount > 0). | | `onLoopComplete` | `() => void` | No | Function called when the marquee completes one loop iteration. | | `onPauseChange` | `(details: PauseStatusDetails) => void` | No | Function called when the pause status changes. | | `paused` | `boolean` | No | Whether the marquee is paused. | | `pauseOnInteraction` | `boolean` | No | Whether to pause the marquee on user interaction (hover, focus). | | `reverse` | `boolean` | No | Whether to reverse the animation direction. | | `side` | `Side` | No | The side/direction the marquee scrolls towards. | | `spacing` | `string` | No | The spacing between marquee items. | | `speed` | `number` | No | The speed of the marquee animation in pixels per second. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | root | | `[data-state]` | "paused" | "idle" | | `[data-orientation]` | The orientation of the marquee | | `[data-paused]` | Present when paused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--marquee-duration` | The marquee duration value for the Root | | `--marquee-spacing` | The marquee spacing value for the Root | | `--marquee-delay` | The marquee delay value for the Root | | `--marquee-loop-count` | The marquee loop count value for the Root | | `--marquee-translate` | The marquee translate value for the Root | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-index]` | The index of the item | | `[data-orientation]` | The orientation of the content | | `[data-side]` | | | `[data-reverse]` | | | `[data-clone]` | | **Edge Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `side` | `Side` | Yes | The side where the edge gradient should appear. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Edge Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-side]` | | | `[data-orientation]` | The orientation of the edge | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMarqueeReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-orientation]` | The orientation of the viewport | | `[data-side]` | | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFill` | `boolean` | No | Whether to automatically duplicate content to fill the container. | | `defaultPaused` | `boolean` | No | Whether the marquee is paused by default. | | `delay` | `number` | No | The delay before the animation starts (in seconds). | | `ids` | `Partial<{ root: string; viewport: string; content: (index: number) => string }>` | No | The ids of the elements in the marquee. Useful for composition. | | `loopCount` | `number` | No | The number of times to loop the animation (0 = infinite). | | `onComplete` | `() => void` | No | Function called when the marquee completes all loops and stops. Only fires for finite loops (loopCount > 0). | | `onLoopComplete` | `() => void` | No | Function called when the marquee completes one loop iteration. | | `onPauseChange` | `(details: PauseStatusDetails) => void` | No | Function called when the pause status changes. | | `paused` | `boolean` | No | Whether the marquee is paused. | | `pauseOnInteraction` | `boolean` | No | Whether to pause the marquee on user interaction (hover, focus). | | `reverse` | `boolean` | No | Whether to reverse the animation direction. | | `side` | `Side` | No | The side/direction the marquee scrolls towards. | | `spacing` | `string` | No | The spacing between marquee items. | | `speed` | `number` | No | The speed of the marquee animation in pixels per second. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | root | | `[data-state]` | "paused" | "idle" | | `[data-orientation]` | The orientation of the marquee | | `[data-paused]` | Present when paused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--marquee-duration` | The marquee duration value for the Root | | `--marquee-spacing` | The marquee spacing value for the Root | | `--marquee-delay` | The marquee delay value for the Root | | `--marquee-loop-count` | The marquee loop count value for the Root | | `--marquee-translate` | The marquee translate value for the Root | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-index]` | The index of the item | | `[data-orientation]` | The orientation of the content | | `[data-side]` | | | `[data-reverse]` | | | `[data-clone]` | | **Edge Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `side` | `Side` | Yes | The side where the edge gradient should appear. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Edge Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-side]` | | | `[data-orientation]` | The orientation of the edge | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMarqueeReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-orientation]` | The orientation of the viewport | | `[data-side]` | | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFill` | `boolean` | No | Whether to automatically duplicate content to fill the container. | | `defaultPaused` | `boolean` | No | Whether the marquee is paused by default. | | `delay` | `number` | No | The delay before the animation starts (in seconds). | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: (index: number) => string }>` | No | The ids of the elements in the marquee. Useful for composition. | | `loopCount` | `number` | No | The number of times to loop the animation (0 = infinite). | | `paused` | `boolean` | No | Whether the marquee is paused. | | `pauseOnInteraction` | `boolean` | No | Whether to pause the marquee on user interaction (hover, focus). | | `reverse` | `boolean` | No | Whether to reverse the animation direction. | | `side` | `Side` | No | The side/direction the marquee scrolls towards. | | `spacing` | `string` | No | The spacing between marquee items. | | `speed` | `number` | No | The speed of the marquee animation in pixels per second. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | root | | `[data-state]` | "paused" | "idle" | | `[data-orientation]` | The orientation of the marquee | | `[data-paused]` | Present when paused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--marquee-duration` | The marquee duration value for the Root | | `--marquee-spacing` | The marquee spacing value for the Root | | `--marquee-delay` | The marquee delay value for the Root | | `--marquee-loop-count` | The marquee loop count value for the Root | | `--marquee-translate` | The marquee translate value for the Root | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-index]` | The index of the item | | `[data-orientation]` | The orientation of the content | | `[data-side]` | | | `[data-reverse]` | | | `[data-clone]` | | **Edge Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `side` | `Side` | Yes | The side where the edge gradient should appear. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Edge Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-side]` | | | `[data-orientation]` | The orientation of the edge | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `MarqueeApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-orientation]` | The orientation of the viewport | | `[data-side]` | | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFill` | `boolean` | No | Whether to automatically duplicate content to fill the container. | | `defaultPaused` | `boolean` | No | Whether the marquee is paused by default. | | `delay` | `number` | No | The delay before the animation starts (in seconds). | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: (index: number) => string }>` | No | The ids of the elements in the marquee. Useful for composition. | | `loopCount` | `number` | No | The number of times to loop the animation (0 = infinite). | | `onComplete` | `() => void` | No | Function called when the marquee completes all loops and stops. Only fires for finite loops (loopCount > 0). | | `onLoopComplete` | `() => void` | No | Function called when the marquee completes one loop iteration. | | `onPauseChange` | `(details: PauseStatusDetails) => void` | No | Function called when the pause status changes. | | `paused` | `boolean` | No | Whether the marquee is paused. | | `pauseOnInteraction` | `boolean` | No | Whether to pause the marquee on user interaction (hover, focus). | | `ref` | `Element` | No | | | `reverse` | `boolean` | No | Whether to reverse the animation direction. | | `side` | `Side` | No | The side/direction the marquee scrolls towards. | | `spacing` | `string` | No | The spacing between marquee items. | | `speed` | `number` | No | The speed of the marquee animation in pixels per second. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | root | | `[data-state]` | "paused" | "idle" | | `[data-orientation]` | The orientation of the marquee | | `[data-paused]` | Present when paused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--marquee-duration` | The marquee duration value for the Root | | `--marquee-spacing` | The marquee spacing value for the Root | | `--marquee-delay` | The marquee delay value for the Root | | `--marquee-loop-count` | The marquee loop count value for the Root | | `--marquee-translate` | The marquee translate value for the Root | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-index]` | The index of the item | | `[data-orientation]` | The orientation of the content | | `[data-side]` | | | `[data-reverse]` | | | `[data-clone]` | | **Edge Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `side` | `Side` | Yes | The side where the edge gradient should appear. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Edge Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-side]` | | | `[data-orientation]` | The orientation of the edge | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMarqueeReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-orientation]` | The orientation of the viewport | | `[data-side]` | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `paused` | `boolean` | Whether the marquee is currently paused. | | `orientation` | `"horizontal" | "vertical"` | The current orientation of the marquee. | | `side` | `Side` | The current side/direction of the marquee. | | `multiplier` | `number` | The multiplier for auto-fill. Indicates how many times to duplicate content. When autoFill is enabled and content is smaller than container, this returns the number of additional copies needed. Otherwise returns 1. | | `contentCount` | `number` | The total number of content elements to render (original + clones). Use this value when rendering your content in a loop. | | `pause` | `VoidFunction` | Pause the marquee animation. | | `resume` | `VoidFunction` | Resume the marquee animation. | | `togglePause` | `VoidFunction` | Toggle the pause state. | | `restart` | `VoidFunction` | Restart the marquee animation from the beginning. | --- # Marquee (SVELTE) ## Anatomy {/* */} ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Basic = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Basic = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Auto Fill Use the `autoFill` prop to automatically duplicate content to fill the viewport. The `spacing` prop controls the gap between duplicated content instances: **Example: auto-fill** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, ] export const AutoFill = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, ] export const AutoFill = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Reverse Set the `reverse` prop to reverse the scroll direction: **Example: reverse** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Reverse = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Reverse = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Vertical Set `side="bottom"` (or `side="top"`) to create a vertical marquee: **Example: vertical** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Vertical = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Vertical = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Speed Control the animation speed using the `speed` prop, which accepts values in pixels per second: **Example: speed** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Speed = () => (

                    Slow (25px/s)

                    {items.map((item, i) => ( {item.logo} {item.name} ))}

                    Normal (50px/s)

                    {items.map((item, i) => ( {item.logo} {item.name} ))}

                    Fast (100px/s)

                    {items.map((item, i) => ( {item.logo} {item.name} ))}
                    ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Speed = () => (

                    Slow (25px/s)

                    {(item) => ( {item.logo} {item.name} )}

                    Normal (50px/s)

                    {(item) => ( {item.logo} {item.name} )}

                    Fast (100px/s)

                    {(item) => ( {item.logo} {item.name} )}
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Slow (25px/s)

                    {#each items as item} {item.logo} {item.name} {/each}

                    Normal (50px/s)

                    {#each items as item} {item.logo} {item.name} {/each}

                    Fast (100px/s)

                    {#each items as item} {item.logo} {item.name} {/each}
                    ``` ### Pause on Interaction Enable `pauseOnInteraction` to pause the marquee when users hover or focus on it, improving accessibility: **Example: pause-on-interaction** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const PauseOnInteraction = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const PauseOnInteraction = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Programmatic Control Use the `useMarquee` hook with `Marquee.RootProvider` to access the marquee API and control playback programmatically: **Example: programmatic-control** #### React ```tsx import { Marquee, useMarquee } from '@ark-ui/react/marquee' import button from 'styles/button.module.css' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const ProgrammaticControl = () => { const marquee = useMarquee() return (
                    {items.map((item, i) => ( {item.logo} {item.name} ))}
                    ) } ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee, useMarquee } from '@ark-ui/solid/marquee' import button from 'styles/button.module.css' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const ProgrammaticControl = () => { const marquee = useMarquee() return (
                    {(item) => ( {item.logo} {item.name} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each items as item} {item.logo} {item.name} {/each}
                    ``` > 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: **Example: finite-loops** #### React ```tsx import { useState } from 'react' import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const FiniteLoops = () => { const [loopCount, setLoopCount] = useState(0) const [completedCount, setCompletedCount] = useState(0) return (
                    setLoopCount((prev) => prev + 1)} onComplete={() => setCompletedCount((prev) => prev + 1)} className={styles.Root} > {items.map((item, i) => ( {item.logo} {item.name} ))}

                    Loop completed: {loopCount} times

                    Animation completed: {completedCount} times

                    ) } ``` #### Solid ```tsx import { For, createSignal } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const FiniteLoops = () => { const [loopCount, setLoopCount] = createSignal(0) const [completedCount, setCompletedCount] = createSignal(0) return (
                    setLoopCount((prev) => prev + 1)} onComplete={() => setCompletedCount((prev) => prev + 1)} class={styles.Root} > {(item) => ( {item.logo} {item.name} )}

                    Loop completed: {loopCount()} times

                    Animation completed: {completedCount()} times

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    loopCount++} onComplete={() => completedCount++} class={styles.Root} > {#each items as item} {item.logo} {item.name} {/each}

                    Loop completed: {loopCount} times

                    Animation completed: {completedCount} times

                    ``` ### Edges Add `Marquee.Edge` components to create fade effects at the start and end of the scrolling area: **Example: with-edges** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const WithEdges = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const WithEdges = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ## Guides ### Content Animation The Marquee component requires CSS keyframe animations to function properly. You'll need to define animations for both horizontal and vertical scrolling: ```css @keyframes marqueeX { from { transform: translateX(0); } to { transform: translateX(var(--marquee-translate)); } } @keyframes marqueeY { from { transform: translateY(0); } to { transform: translateY(var(--marquee-translate)); } } ``` The component automatically applies the appropriate animation (`marqueeX` or `marqueeY`) based on the scroll direction and uses the `--marquee-translate` CSS variable for seamless looping. You can target specific parts of the marquee using `data-part` attributes for custom styling: - `[data-part="root"]` - The root container - `[data-part="viewport"]` - The scrolling viewport - `[data-part="content"]` - The content wrapper (receives animation) - `[data-part="item"]` - Individual marquee items - `[data-part="edge"]` - Edge gradient overlays ### Best Practices - **Enable pause-on-interaction**: Use `pauseOnInteraction` to allow users to pause animations on hover or focus, improving accessibility and readability - **Use descriptive labels**: Provide meaningful `aria-label` values that describe the marquee content (e.g., "Partner logos", "Latest announcements") - **Avoid for critical information**: Don't use marquees for essential content that users must read, as continuously moving text can be difficult to process. Consider static displays for important information ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFill` | `boolean` | No | Whether to automatically duplicate content to fill the container. | | `defaultPaused` | `boolean` | No | Whether the marquee is paused by default. | | `delay` | `number` | No | The delay before the animation starts (in seconds). | | `ids` | `Partial<{ root: string; viewport: string; content: (index: number) => string }>` | No | The ids of the elements in the marquee. Useful for composition. | | `loopCount` | `number` | No | The number of times to loop the animation (0 = infinite). | | `onComplete` | `() => void` | No | Function called when the marquee completes all loops and stops. Only fires for finite loops (loopCount > 0). | | `onLoopComplete` | `() => void` | No | Function called when the marquee completes one loop iteration. | | `onPauseChange` | `(details: PauseStatusDetails) => void` | No | Function called when the pause status changes. | | `paused` | `boolean` | No | Whether the marquee is paused. | | `pauseOnInteraction` | `boolean` | No | Whether to pause the marquee on user interaction (hover, focus). | | `reverse` | `boolean` | No | Whether to reverse the animation direction. | | `side` | `Side` | No | The side/direction the marquee scrolls towards. | | `spacing` | `string` | No | The spacing between marquee items. | | `speed` | `number` | No | The speed of the marquee animation in pixels per second. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | root | | `[data-state]` | "paused" | "idle" | | `[data-orientation]` | The orientation of the marquee | | `[data-paused]` | Present when paused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--marquee-duration` | The marquee duration value for the Root | | `--marquee-spacing` | The marquee spacing value for the Root | | `--marquee-delay` | The marquee delay value for the Root | | `--marquee-loop-count` | The marquee loop count value for the Root | | `--marquee-translate` | The marquee translate value for the Root | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-index]` | The index of the item | | `[data-orientation]` | The orientation of the content | | `[data-side]` | | | `[data-reverse]` | | | `[data-clone]` | | **Edge Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `side` | `Side` | Yes | The side where the edge gradient should appear. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Edge Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-side]` | | | `[data-orientation]` | The orientation of the edge | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMarqueeReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-orientation]` | The orientation of the viewport | | `[data-side]` | | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFill` | `boolean` | No | Whether to automatically duplicate content to fill the container. | | `defaultPaused` | `boolean` | No | Whether the marquee is paused by default. | | `delay` | `number` | No | The delay before the animation starts (in seconds). | | `ids` | `Partial<{ root: string; viewport: string; content: (index: number) => string }>` | No | The ids of the elements in the marquee. Useful for composition. | | `loopCount` | `number` | No | The number of times to loop the animation (0 = infinite). | | `onComplete` | `() => void` | No | Function called when the marquee completes all loops and stops. Only fires for finite loops (loopCount > 0). | | `onLoopComplete` | `() => void` | No | Function called when the marquee completes one loop iteration. | | `onPauseChange` | `(details: PauseStatusDetails) => void` | No | Function called when the pause status changes. | | `paused` | `boolean` | No | Whether the marquee is paused. | | `pauseOnInteraction` | `boolean` | No | Whether to pause the marquee on user interaction (hover, focus). | | `reverse` | `boolean` | No | Whether to reverse the animation direction. | | `side` | `Side` | No | The side/direction the marquee scrolls towards. | | `spacing` | `string` | No | The spacing between marquee items. | | `speed` | `number` | No | The speed of the marquee animation in pixels per second. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | root | | `[data-state]` | "paused" | "idle" | | `[data-orientation]` | The orientation of the marquee | | `[data-paused]` | Present when paused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--marquee-duration` | The marquee duration value for the Root | | `--marquee-spacing` | The marquee spacing value for the Root | | `--marquee-delay` | The marquee delay value for the Root | | `--marquee-loop-count` | The marquee loop count value for the Root | | `--marquee-translate` | The marquee translate value for the Root | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-index]` | The index of the item | | `[data-orientation]` | The orientation of the content | | `[data-side]` | | | `[data-reverse]` | | | `[data-clone]` | | **Edge Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `side` | `Side` | Yes | The side where the edge gradient should appear. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Edge Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-side]` | | | `[data-orientation]` | The orientation of the edge | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMarqueeReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-orientation]` | The orientation of the viewport | | `[data-side]` | | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFill` | `boolean` | No | Whether to automatically duplicate content to fill the container. | | `defaultPaused` | `boolean` | No | Whether the marquee is paused by default. | | `delay` | `number` | No | The delay before the animation starts (in seconds). | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: (index: number) => string }>` | No | The ids of the elements in the marquee. Useful for composition. | | `loopCount` | `number` | No | The number of times to loop the animation (0 = infinite). | | `paused` | `boolean` | No | Whether the marquee is paused. | | `pauseOnInteraction` | `boolean` | No | Whether to pause the marquee on user interaction (hover, focus). | | `reverse` | `boolean` | No | Whether to reverse the animation direction. | | `side` | `Side` | No | The side/direction the marquee scrolls towards. | | `spacing` | `string` | No | The spacing between marquee items. | | `speed` | `number` | No | The speed of the marquee animation in pixels per second. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | root | | `[data-state]` | "paused" | "idle" | | `[data-orientation]` | The orientation of the marquee | | `[data-paused]` | Present when paused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--marquee-duration` | The marquee duration value for the Root | | `--marquee-spacing` | The marquee spacing value for the Root | | `--marquee-delay` | The marquee delay value for the Root | | `--marquee-loop-count` | The marquee loop count value for the Root | | `--marquee-translate` | The marquee translate value for the Root | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-index]` | The index of the item | | `[data-orientation]` | The orientation of the content | | `[data-side]` | | | `[data-reverse]` | | | `[data-clone]` | | **Edge Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `side` | `Side` | Yes | The side where the edge gradient should appear. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Edge Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-side]` | | | `[data-orientation]` | The orientation of the edge | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `MarqueeApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-orientation]` | The orientation of the viewport | | `[data-side]` | | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFill` | `boolean` | No | Whether to automatically duplicate content to fill the container. | | `defaultPaused` | `boolean` | No | Whether the marquee is paused by default. | | `delay` | `number` | No | The delay before the animation starts (in seconds). | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: (index: number) => string }>` | No | The ids of the elements in the marquee. Useful for composition. | | `loopCount` | `number` | No | The number of times to loop the animation (0 = infinite). | | `onComplete` | `() => void` | No | Function called when the marquee completes all loops and stops. Only fires for finite loops (loopCount > 0). | | `onLoopComplete` | `() => void` | No | Function called when the marquee completes one loop iteration. | | `onPauseChange` | `(details: PauseStatusDetails) => void` | No | Function called when the pause status changes. | | `paused` | `boolean` | No | Whether the marquee is paused. | | `pauseOnInteraction` | `boolean` | No | Whether to pause the marquee on user interaction (hover, focus). | | `ref` | `Element` | No | | | `reverse` | `boolean` | No | Whether to reverse the animation direction. | | `side` | `Side` | No | The side/direction the marquee scrolls towards. | | `spacing` | `string` | No | The spacing between marquee items. | | `speed` | `number` | No | The speed of the marquee animation in pixels per second. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | root | | `[data-state]` | "paused" | "idle" | | `[data-orientation]` | The orientation of the marquee | | `[data-paused]` | Present when paused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--marquee-duration` | The marquee duration value for the Root | | `--marquee-spacing` | The marquee spacing value for the Root | | `--marquee-delay` | The marquee delay value for the Root | | `--marquee-loop-count` | The marquee loop count value for the Root | | `--marquee-translate` | The marquee translate value for the Root | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-index]` | The index of the item | | `[data-orientation]` | The orientation of the content | | `[data-side]` | | | `[data-reverse]` | | | `[data-clone]` | | **Edge Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `side` | `Side` | Yes | The side where the edge gradient should appear. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Edge Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-side]` | | | `[data-orientation]` | The orientation of the edge | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMarqueeReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-orientation]` | The orientation of the viewport | | `[data-side]` | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `paused` | `boolean` | Whether the marquee is currently paused. | | `orientation` | `"horizontal" | "vertical"` | The current orientation of the marquee. | | `side` | `Side` | The current side/direction of the marquee. | | `multiplier` | `number` | The multiplier for auto-fill. Indicates how many times to duplicate content. When autoFill is enabled and content is smaller than container, this returns the number of additional copies needed. Otherwise returns 1. | | `contentCount` | `number` | The total number of content elements to render (original + clones). Use this value when rendering your content in a loop. | | `pause` | `VoidFunction` | Pause the marquee animation. | | `resume` | `VoidFunction` | Resume the marquee animation. | | `togglePause` | `VoidFunction` | Toggle the pause state. | | `restart` | `VoidFunction` | Restart the marquee animation from the beginning. | --- # Marquee (SOLID) ## Anatomy {/* */} ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Basic = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Basic = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Auto Fill Use the `autoFill` prop to automatically duplicate content to fill the viewport. The `spacing` prop controls the gap between duplicated content instances: **Example: auto-fill** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, ] export const AutoFill = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, ] export const AutoFill = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Reverse Set the `reverse` prop to reverse the scroll direction: **Example: reverse** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Reverse = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Reverse = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Vertical Set `side="bottom"` (or `side="top"`) to create a vertical marquee: **Example: vertical** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Vertical = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Vertical = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Speed Control the animation speed using the `speed` prop, which accepts values in pixels per second: **Example: speed** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Speed = () => (

                    Slow (25px/s)

                    {items.map((item, i) => ( {item.logo} {item.name} ))}

                    Normal (50px/s)

                    {items.map((item, i) => ( {item.logo} {item.name} ))}

                    Fast (100px/s)

                    {items.map((item, i) => ( {item.logo} {item.name} ))}
                    ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const Speed = () => (

                    Slow (25px/s)

                    {(item) => ( {item.logo} {item.name} )}

                    Normal (50px/s)

                    {(item) => ( {item.logo} {item.name} )}

                    Fast (100px/s)

                    {(item) => ( {item.logo} {item.name} )}
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Slow (25px/s)

                    {#each items as item} {item.logo} {item.name} {/each}

                    Normal (50px/s)

                    {#each items as item} {item.logo} {item.name} {/each}

                    Fast (100px/s)

                    {#each items as item} {item.logo} {item.name} {/each}
                    ``` ### Pause on Interaction Enable `pauseOnInteraction` to pause the marquee when users hover or focus on it, improving accessibility: **Example: pause-on-interaction** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const PauseOnInteraction = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const PauseOnInteraction = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ### Programmatic Control Use the `useMarquee` hook with `Marquee.RootProvider` to access the marquee API and control playback programmatically: **Example: programmatic-control** #### React ```tsx import { Marquee, useMarquee } from '@ark-ui/react/marquee' import button from 'styles/button.module.css' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const ProgrammaticControl = () => { const marquee = useMarquee() return (
                    {items.map((item, i) => ( {item.logo} {item.name} ))}
                    ) } ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee, useMarquee } from '@ark-ui/solid/marquee' import button from 'styles/button.module.css' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const ProgrammaticControl = () => { const marquee = useMarquee() return (
                    {(item) => ( {item.logo} {item.name} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each items as item} {item.logo} {item.name} {/each}
                    ``` > 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: **Example: finite-loops** #### React ```tsx import { useState } from 'react' import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const FiniteLoops = () => { const [loopCount, setLoopCount] = useState(0) const [completedCount, setCompletedCount] = useState(0) return (
                    setLoopCount((prev) => prev + 1)} onComplete={() => setCompletedCount((prev) => prev + 1)} className={styles.Root} > {items.map((item, i) => ( {item.logo} {item.name} ))}

                    Loop completed: {loopCount} times

                    Animation completed: {completedCount} times

                    ) } ``` #### Solid ```tsx import { For, createSignal } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const FiniteLoops = () => { const [loopCount, setLoopCount] = createSignal(0) const [completedCount, setCompletedCount] = createSignal(0) return (
                    setLoopCount((prev) => prev + 1)} onComplete={() => setCompletedCount((prev) => prev + 1)} class={styles.Root} > {(item) => ( {item.logo} {item.name} )}

                    Loop completed: {loopCount()} times

                    Animation completed: {completedCount()} times

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    loopCount++} onComplete={() => completedCount++} class={styles.Root} > {#each items as item} {item.logo} {item.name} {/each}

                    Loop completed: {loopCount} times

                    Animation completed: {completedCount} times

                    ``` ### Edges Add `Marquee.Edge` components to create fade effects at the start and end of the scrolling area: **Example: with-edges** #### React ```tsx import { Marquee } from '@ark-ui/react/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const WithEdges = () => ( {items.map((item, i) => ( {item.logo} {item.name} ))} ) ``` #### Solid ```tsx import { For } from 'solid-js' import { Marquee } from '@ark-ui/solid/marquee' import styles from 'styles/marquee.module.css' const items = [ { name: 'Apple', logo: '🍎' }, { name: 'Banana', logo: '🍌' }, { name: 'Cherry', logo: '🍒' }, { name: 'Grape', logo: '🍇' }, { name: 'Watermelon', logo: '🍉' }, { name: 'Strawberry', logo: '🍓' }, ] export const WithEdges = () => ( {(item) => ( {item.logo} {item.name} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item} {item.logo} {item.name} {/each} ``` ## Guides ### Content Animation The Marquee component requires CSS keyframe animations to function properly. You'll need to define animations for both horizontal and vertical scrolling: ```css @keyframes marqueeX { from { transform: translateX(0); } to { transform: translateX(var(--marquee-translate)); } } @keyframes marqueeY { from { transform: translateY(0); } to { transform: translateY(var(--marquee-translate)); } } ``` The component automatically applies the appropriate animation (`marqueeX` or `marqueeY`) based on the scroll direction and uses the `--marquee-translate` CSS variable for seamless looping. You can target specific parts of the marquee using `data-part` attributes for custom styling: - `[data-part="root"]` - The root container - `[data-part="viewport"]` - The scrolling viewport - `[data-part="content"]` - The content wrapper (receives animation) - `[data-part="item"]` - Individual marquee items - `[data-part="edge"]` - Edge gradient overlays ### Best Practices - **Enable pause-on-interaction**: Use `pauseOnInteraction` to allow users to pause animations on hover or focus, improving accessibility and readability - **Use descriptive labels**: Provide meaningful `aria-label` values that describe the marquee content (e.g., "Partner logos", "Latest announcements") - **Avoid for critical information**: Don't use marquees for essential content that users must read, as continuously moving text can be difficult to process. Consider static displays for important information ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFill` | `boolean` | No | Whether to automatically duplicate content to fill the container. | | `defaultPaused` | `boolean` | No | Whether the marquee is paused by default. | | `delay` | `number` | No | The delay before the animation starts (in seconds). | | `ids` | `Partial<{ root: string; viewport: string; content: (index: number) => string }>` | No | The ids of the elements in the marquee. Useful for composition. | | `loopCount` | `number` | No | The number of times to loop the animation (0 = infinite). | | `onComplete` | `() => void` | No | Function called when the marquee completes all loops and stops. Only fires for finite loops (loopCount > 0). | | `onLoopComplete` | `() => void` | No | Function called when the marquee completes one loop iteration. | | `onPauseChange` | `(details: PauseStatusDetails) => void` | No | Function called when the pause status changes. | | `paused` | `boolean` | No | Whether the marquee is paused. | | `pauseOnInteraction` | `boolean` | No | Whether to pause the marquee on user interaction (hover, focus). | | `reverse` | `boolean` | No | Whether to reverse the animation direction. | | `side` | `Side` | No | The side/direction the marquee scrolls towards. | | `spacing` | `string` | No | The spacing between marquee items. | | `speed` | `number` | No | The speed of the marquee animation in pixels per second. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | root | | `[data-state]` | "paused" | "idle" | | `[data-orientation]` | The orientation of the marquee | | `[data-paused]` | Present when paused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--marquee-duration` | The marquee duration value for the Root | | `--marquee-spacing` | The marquee spacing value for the Root | | `--marquee-delay` | The marquee delay value for the Root | | `--marquee-loop-count` | The marquee loop count value for the Root | | `--marquee-translate` | The marquee translate value for the Root | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-index]` | The index of the item | | `[data-orientation]` | The orientation of the content | | `[data-side]` | | | `[data-reverse]` | | | `[data-clone]` | | **Edge Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `side` | `Side` | Yes | The side where the edge gradient should appear. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Edge Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-side]` | | | `[data-orientation]` | The orientation of the edge | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMarqueeReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-orientation]` | The orientation of the viewport | | `[data-side]` | | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFill` | `boolean` | No | Whether to automatically duplicate content to fill the container. | | `defaultPaused` | `boolean` | No | Whether the marquee is paused by default. | | `delay` | `number` | No | The delay before the animation starts (in seconds). | | `ids` | `Partial<{ root: string; viewport: string; content: (index: number) => string }>` | No | The ids of the elements in the marquee. Useful for composition. | | `loopCount` | `number` | No | The number of times to loop the animation (0 = infinite). | | `onComplete` | `() => void` | No | Function called when the marquee completes all loops and stops. Only fires for finite loops (loopCount > 0). | | `onLoopComplete` | `() => void` | No | Function called when the marquee completes one loop iteration. | | `onPauseChange` | `(details: PauseStatusDetails) => void` | No | Function called when the pause status changes. | | `paused` | `boolean` | No | Whether the marquee is paused. | | `pauseOnInteraction` | `boolean` | No | Whether to pause the marquee on user interaction (hover, focus). | | `reverse` | `boolean` | No | Whether to reverse the animation direction. | | `side` | `Side` | No | The side/direction the marquee scrolls towards. | | `spacing` | `string` | No | The spacing between marquee items. | | `speed` | `number` | No | The speed of the marquee animation in pixels per second. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | root | | `[data-state]` | "paused" | "idle" | | `[data-orientation]` | The orientation of the marquee | | `[data-paused]` | Present when paused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--marquee-duration` | The marquee duration value for the Root | | `--marquee-spacing` | The marquee spacing value for the Root | | `--marquee-delay` | The marquee delay value for the Root | | `--marquee-loop-count` | The marquee loop count value for the Root | | `--marquee-translate` | The marquee translate value for the Root | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-index]` | The index of the item | | `[data-orientation]` | The orientation of the content | | `[data-side]` | | | `[data-reverse]` | | | `[data-clone]` | | **Edge Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `side` | `Side` | Yes | The side where the edge gradient should appear. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Edge Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-side]` | | | `[data-orientation]` | The orientation of the edge | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMarqueeReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-orientation]` | The orientation of the viewport | | `[data-side]` | | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFill` | `boolean` | No | Whether to automatically duplicate content to fill the container. | | `defaultPaused` | `boolean` | No | Whether the marquee is paused by default. | | `delay` | `number` | No | The delay before the animation starts (in seconds). | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: (index: number) => string }>` | No | The ids of the elements in the marquee. Useful for composition. | | `loopCount` | `number` | No | The number of times to loop the animation (0 = infinite). | | `paused` | `boolean` | No | Whether the marquee is paused. | | `pauseOnInteraction` | `boolean` | No | Whether to pause the marquee on user interaction (hover, focus). | | `reverse` | `boolean` | No | Whether to reverse the animation direction. | | `side` | `Side` | No | The side/direction the marquee scrolls towards. | | `spacing` | `string` | No | The spacing between marquee items. | | `speed` | `number` | No | The speed of the marquee animation in pixels per second. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | root | | `[data-state]` | "paused" | "idle" | | `[data-orientation]` | The orientation of the marquee | | `[data-paused]` | Present when paused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--marquee-duration` | The marquee duration value for the Root | | `--marquee-spacing` | The marquee spacing value for the Root | | `--marquee-delay` | The marquee delay value for the Root | | `--marquee-loop-count` | The marquee loop count value for the Root | | `--marquee-translate` | The marquee translate value for the Root | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-index]` | The index of the item | | `[data-orientation]` | The orientation of the content | | `[data-side]` | | | `[data-reverse]` | | | `[data-clone]` | | **Edge Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `side` | `Side` | Yes | The side where the edge gradient should appear. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Edge Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-side]` | | | `[data-orientation]` | The orientation of the edge | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `MarqueeApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-orientation]` | The orientation of the viewport | | `[data-side]` | | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFill` | `boolean` | No | Whether to automatically duplicate content to fill the container. | | `defaultPaused` | `boolean` | No | Whether the marquee is paused by default. | | `delay` | `number` | No | The delay before the animation starts (in seconds). | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: (index: number) => string }>` | No | The ids of the elements in the marquee. Useful for composition. | | `loopCount` | `number` | No | The number of times to loop the animation (0 = infinite). | | `onComplete` | `() => void` | No | Function called when the marquee completes all loops and stops. Only fires for finite loops (loopCount > 0). | | `onLoopComplete` | `() => void` | No | Function called when the marquee completes one loop iteration. | | `onPauseChange` | `(details: PauseStatusDetails) => void` | No | Function called when the pause status changes. | | `paused` | `boolean` | No | Whether the marquee is paused. | | `pauseOnInteraction` | `boolean` | No | Whether to pause the marquee on user interaction (hover, focus). | | `ref` | `Element` | No | | | `reverse` | `boolean` | No | Whether to reverse the animation direction. | | `side` | `Side` | No | The side/direction the marquee scrolls towards. | | `spacing` | `string` | No | The spacing between marquee items. | | `speed` | `number` | No | The speed of the marquee animation in pixels per second. | | `translations` | `IntlTranslations` | No | The localized messages to use. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | root | | `[data-state]` | "paused" | "idle" | | `[data-orientation]` | The orientation of the marquee | | `[data-paused]` | Present when paused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--marquee-duration` | The marquee duration value for the Root | | `--marquee-spacing` | The marquee spacing value for the Root | | `--marquee-delay` | The marquee delay value for the Root | | `--marquee-loop-count` | The marquee loop count value for the Root | | `--marquee-translate` | The marquee translate value for the Root | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-index]` | The index of the item | | `[data-orientation]` | The orientation of the content | | `[data-side]` | | | `[data-reverse]` | | | `[data-clone]` | | **Edge Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `side` | `Side` | Yes | The side where the edge gradient should appear. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Edge Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-side]` | | | `[data-orientation]` | The orientation of the edge | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMarqueeReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | marquee | | `[data-part]` | | | `[data-orientation]` | The orientation of the viewport | | `[data-side]` | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `paused` | `boolean` | Whether the marquee is currently paused. | | `orientation` | `"horizontal" | "vertical"` | The current orientation of the marquee. | | `side` | `Side` | The current side/direction of the marquee. | | `multiplier` | `number` | The multiplier for auto-fill. Indicates how many times to duplicate content. When autoFill is enabled and content is smaller than container, this returns the number of additional copies needed. Otherwise returns 1. | | `contentCount` | `number` | The total number of content elements to render (original + clones). Use this value when rendering your content in a loop. | | `pause` | `VoidFunction` | Pause the marquee animation. | | `resume` | `VoidFunction` | Resume the marquee animation. | | `togglePause` | `VoidFunction` | Toggle the pause state. | | `restart` | `VoidFunction` | Restart the marquee animation from the beginning. | --- # Menu (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/menu.module.css' export const Basic = () => ( File New File Open... Save Save As... ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import styles from 'styles/menu.module.css' export const Basic = () => ( File New File Open... Save Save As... ) ``` #### Vue ```vue ``` #### Svelte ```svelte File New File Open... Save Save As... ``` ### Item Selection Use `onSelect` to handle item selection. The callback receives the item's `id`. **Example: controlled** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/menu.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return (
                    setOpen(e.open)}> Actions Edit Duplicate Archive Delete
                    ) } ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/menu.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return (
                    setOpen(e.open)}> Actions Edit Duplicate Archive Delete
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Actions Edit Duplicate Archive Delete
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Menu, useMenu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/menu.module.css' export const RootProvider = () => { const menu = useMenu() return (
                    Edit Cut Copy Paste Delete
                    ) } ``` #### Solid ```tsx import { Menu, useMenu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/menu.module.css' export const RootProvider = () => { const menu = useMenu() return (
                    Edit Cut Copy Paste Delete
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Edit Cut Copy Paste Delete
                    ``` ### Grouping Use `Menu.ItemGroup` and `Menu.ItemGroupLabel` to organize related menu items. **Example: group** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/menu.module.css' export const Group = () => ( Edit Clipboard Cut Copy Paste Selection Select All Deselect ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import styles from 'styles/menu.module.css' export const Group = () => ( Edit Clipboard Cut Copy Paste Selection Select All Deselect ) ``` #### Vue ```vue ``` #### Svelte ```svelte Edit Clipboard Cut Copy Paste Selection Select All Deselect ``` ### Links To render menu items as links, use the `asChild` prop to replace the default element with an anchor tag. **Example: links** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/menu.module.css' export const Links = () => ( Help Documentation GitHub Changelog ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import styles from 'styles/menu.module.css' export const Links = () => ( Help }> Documentation } > GitHub } > Changelog ) ``` #### Vue ```vue ``` #### Svelte ```svelte Help {#snippet asChild(itemProps)} Documentation {/snippet} {#snippet asChild(itemProps)} GitHub {/snippet} {#snippet asChild(itemProps)} Changelog {/snippet} ``` ### Checkbox To add a checkbox to a menu item, use the `Menu.Checkbox` component. **Example: checkbox-items** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { CheckIcon, ChevronDownIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/menu.module.css' export const CheckboxItems = () => { const [showToolbar, setShowToolbar] = useState(true) const [showStatusBar, setShowStatusBar] = useState(false) return ( View Show Toolbar Show Status Bar ) } ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { CheckIcon, ChevronDownIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/menu.module.css' export const CheckboxItems = () => { const [showToolbar, setShowToolbar] = createSignal(true) const [showStatusBar, setShowStatusBar] = createSignal(false) return ( View Show Toolbar Show Status Bar ) } ``` #### Vue ```vue ``` #### Svelte ```svelte View Show Toolbar Show Status Bar ``` ### Radio Group To group radio option items, use the `Menu.RadioGroup` component. **Example: radio-items** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { CheckIcon, ChevronDownIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/menu.module.css' export const RadioItems = () => { const [sortBy, setSortBy] = useState('date') return ( Sort setSortBy(e.value)}> Sort By Name Date Modified Size Type ) } ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { CheckIcon, ChevronDownIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/menu.module.css' export const RadioItems = () => { const [sortBy, setSortBy] = createSignal('date') return ( Sort setSortBy(e.value)}> Sort By Name Date Modified Size Type ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Sort Sort By Name Date Modified Size Type ``` ### 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. **Example: context** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import styles from 'styles/menu.module.css' export const Context = () => ( Right click here Cut Copy Paste Delete ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import styles from 'styles/menu.module.css' export const Context = () => ( Right click here Cut Copy Paste Delete ) ``` #### Vue ```vue ``` #### Svelte ```svelte Right click here Cut Copy Paste Delete ``` ### Nested To show a nested menu, render another `Menu` component and use the `Menu.TriggerItem` component to open the submenu. **Example: nested** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/menu.module.css' export const Nested = () => ( File New File Open... Share Email Message AirDrop Export PDF PNG SVG Print... ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/menu.module.css' export const Nested = () => ( File New File Open... Share Email Message AirDrop Export PDF PNG SVG Print... ) ``` #### Vue ```vue ``` #### Svelte ```svelte File New File Open... Share Email Message AirDrop Export PDF PNG SVG Print... ``` ### Menu in Dialog When rendering a menu inside a dialog, use `lazyMount` and `unmountOnExit` to ensure proper cleanup when the dialog closes. **Example: menu-in-dialog** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Menu } from '@ark-ui/react/menu' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/menu.module.css' export const MenuInDialog = () => ( Open Dialog Settings Configure your preferences below.
                    Select theme Light Dark System
                    ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/menu.module.css' export const MenuInDialog = () => ( Open Dialog Settings Configure your preferences below.
                    Select theme Light Dark System
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Settings Configure your preferences below.
                    Select theme Light Dark System
                    ``` ### Menu Item Dialog Open a confirmation dialog from a menu item. This pattern is useful for destructive actions like delete that require user confirmation. **Example: menu-item-dialog** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Menu } from '@ark-ui/react/menu' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/menu.module.css' export const MenuItemDialog = () => { const [dialogOpen, setDialogOpen] = useState(false) return ( <> Actions Edit Duplicate setDialogOpen(true)}> Delete... setDialogOpen(e.open)} role="alertdialog"> Confirm Delete Are you sure you want to delete this item? This action cannot be undone.
                    ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/menu.module.css' export const MenuItemDialog = () => { const [dialogOpen, setDialogOpen] = createSignal(false) return ( <> Actions Edit Duplicate setDialogOpen(true)}> Delete... setDialogOpen(e.open)} role="alertdialog"> Confirm Delete Are you sure you want to delete this item? This action cannot be undone.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Actions Edit Duplicate (dialogOpen = true)}>Delete... Confirm Delete Are you sure you want to delete this item? This action cannot be undone.
                    ``` ## Guides ### Custom IDs Ark UI autogenerates ids for menu items internally. Passing a custom `id` prop breaks the internal `getElementById` functionality used by the component. ```tsx // ❌ Don't do this Custom Item // ✅ Do this Custom Item ``` ### Links To render a menu item as a link, render the link as the menu item itself using the `asChild` prop, not as a child of the menu item. > This pattern ensures the link element receives the correct ARIA attributes and keyboard interactions from the menu > item. Here's an example of a reusable `MenuItemLink` component: ```tsx interface MenuItemLinkProps extends Menu.ItemProps { href?: string target?: string } export const MenuItemLink = (props: MenuItemLinkProps) => { const { href, target, children, ...rest } = props return ( {children} ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. | | `aria-label` | `string` | No | The accessibility label for the menu | | `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected | | `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item. | | `defaultOpen` | `boolean` | No | The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu. | | `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string contextTrigger: string content: string groupLabel: (id: string) => string group: (id: string) => string positioner: string arrow: string }>` | No | The ids of the elements in the menu. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when the highlighted menu item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the menu opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when a menu item is selected. | | `open` | `boolean` | No | The controlled open state of the menu | | `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CheckboxItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `checked` | `boolean` | Yes | Whether the option is checked | | `value` | `string` | Yes | The value of the option | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onCheckedChange` | `(checked: boolean) => void` | No | Function called when the option state is changed | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | menu | | `[data-has-nested]` | menu | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested menus | **ContextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ContextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | context-trigger | | `[data-state]` | "open" | "closed" | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The unique value of the menu item option. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onSelect` | `VoidFunction` | No | The function to call when the item is selected | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-value]` | The value of the item | | `[data-valuetext]` | The human-readable value | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RadioItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `onValueChange` | `(e: ValueChangeDetails) => void` | No | | | `value` | `string` | No | | **RadioItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the option | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMenuReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TriggerItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. | | `aria-label` | `string` | No | The accessibility label for the menu | | `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected | | `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item. | | `defaultOpen` | `boolean` | No | The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu. | | `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string contextTrigger: string content: string groupLabel: (id: string) => string group: (id: string) => string positioner: string arrow: string }>` | No | The ids of the elements in the menu. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when the highlighted menu item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the menu opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when a menu item is selected. | | `open` | `boolean` | No | The controlled open state of the menu | | `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CheckboxItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `checked` | `boolean` | Yes | Whether the option is checked | | `value` | `string` | Yes | The value of the option | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onCheckedChange` | `(checked: boolean) => void` | No | Function called when the option state is changed | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | menu | | `[data-has-nested]` | menu | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested menus | **ContextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ContextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | context-trigger | | `[data-state]` | "open" | "closed" | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The unique value of the menu item option. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onSelect` | `VoidFunction` | No | The function to call when the item is selected | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-value]` | The value of the item | | `[data-valuetext]` | The human-readable value | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RadioItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `onValueChange` | `(e: ValueChangeDetails) => void` | No | | | `value` | `string` | No | | **RadioItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the option | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMenuReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'hr'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TriggerItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. | | `aria-label` | `string` | No | The accessibility label for the menu | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected | | `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item. | | `defaultOpen` | `boolean` | No | The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu. | | `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string contextTrigger: string content: string groupLabel(id: string): string group(id: string): string positioner: string arrow: string }>` | No | The ids of the elements in the menu. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element | | `open` | `boolean` | No | The controlled open state of the menu | | `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu | | `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CheckboxItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `checked` | `boolean` | Yes | Whether the option is checked | | `value` | `string` | Yes | The value of the option | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | menu | | `[data-has-nested]` | menu | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested menus | **ContextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ContextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | context-trigger | | `[data-state]` | "open" | "closed" | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The `id` of the element that provides accessibility label to the option group | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The unique value of the menu item option. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-value]` | The value of the item | | `[data-valuetext]` | The human-readable value | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RadioItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | | `modelValue` | `string` | No | | **RadioItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the option | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMenuReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TriggerItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. | | `aria-label` | `string` | No | The accessibility label for the menu | | `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected | | `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item. | | `defaultOpen` | `boolean` | No | The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu. | | `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string contextTrigger: string content: string groupLabel: (id: string) => string group: (id: string) => string positioner: string arrow: string }>` | No | The ids of the elements in the menu. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when the highlighted menu item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the menu opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when a menu item is selected. | | `open` | `boolean` | No | The controlled open state of the menu | | `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **CheckboxItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `checked` | `boolean` | Yes | Whether the option is checked | | `value` | `string` | Yes | The value of the option | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onCheckedChange` | `(checked: boolean) => void` | No | Function called when the option state is changed | | `ref` | `Element` | No | | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | menu | | `[data-has-nested]` | menu | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested menus | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseMenuContext]>` | Yes | | **ContextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ContextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | context-trigger | | `[data-state]` | "open" | "closed" | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseMenuItemContext]>` | Yes | | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The `id` of the element that provides accessibility label to the option group | | `ref` | `Element` | No | | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The unique value of the menu item option. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onSelect` | `VoidFunction` | No | The function to call when the item is selected | | `ref` | `Element` | No | | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-value]` | The value of the item | | `[data-valuetext]` | The human-readable value | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RadioItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | | `onValueChange` | `(e: ValueChangeDetails) => void` | No | | | `ref` | `Element` | No | | | `value` | `string` | No | | **RadioItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the option | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `ref` | `Element` | No | | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMenuReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TriggerItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the menu is open | | `setOpen` | `(open: boolean) => void` | Function to open or close the menu | | `highlightedValue` | `string` | The id of the currently highlighted menuitem | | `setHighlightedValue` | `(value: string) => void` | Function to set the highlighted menuitem | | `setParent` | `(parent: ParentMenuService) => void` | Function to register a parent menu. This is used for submenus | | `setChild` | `(child: ChildMenuService) => void` | Function to register a child menu. This is used for submenus | | `reposition` | `(options?: Partial) => void` | Function to reposition the popover | | `getOptionItemState` | `(props: OptionItemProps) => OptionItemState` | Returns the state of the option item | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of the menu item | | `addItemListener` | `(props: ItemListenerProps) => VoidFunction` | Setup the custom event listener for item selection event | ## Accessibility Complies with the [Menu WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/). ### Keyboard Support **`Space`** Description: Activates/Selects the highlighted item **`Enter`** Description: Activates/Selects the highlighted item **`ArrowDown`** Description: Highlights the next item in the menu **`ArrowUp`** Description: Highlights the previous item in the menu **`ArrowRight + ArrowLeft`** Description: When focus is on trigger, opens or closes the submenu depending on reading direction. **`Esc`** Description: Closes the menu and moves focus to the trigger --- # Menu (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/menu.module.css' export const Basic = () => ( File New File Open... Save Save As... ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import styles from 'styles/menu.module.css' export const Basic = () => ( File New File Open... Save Save As... ) ``` #### Vue ```vue ``` #### Svelte ```svelte File New File Open... Save Save As... ``` ### Item Selection Use `onSelect` to handle item selection. The callback receives the item's `id`. **Example: controlled** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/menu.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return (
                    setOpen(e.open)}> Actions Edit Duplicate Archive Delete
                    ) } ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/menu.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return (
                    setOpen(e.open)}> Actions Edit Duplicate Archive Delete
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Actions Edit Duplicate Archive Delete
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Menu, useMenu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/menu.module.css' export const RootProvider = () => { const menu = useMenu() return (
                    Edit Cut Copy Paste Delete
                    ) } ``` #### Solid ```tsx import { Menu, useMenu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/menu.module.css' export const RootProvider = () => { const menu = useMenu() return (
                    Edit Cut Copy Paste Delete
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Edit Cut Copy Paste Delete
                    ``` ### Grouping Use `Menu.ItemGroup` and `Menu.ItemGroupLabel` to organize related menu items. **Example: group** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/menu.module.css' export const Group = () => ( Edit Clipboard Cut Copy Paste Selection Select All Deselect ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import styles from 'styles/menu.module.css' export const Group = () => ( Edit Clipboard Cut Copy Paste Selection Select All Deselect ) ``` #### Vue ```vue ``` #### Svelte ```svelte Edit Clipboard Cut Copy Paste Selection Select All Deselect ``` ### Links To render menu items as links, use the `asChild` prop to replace the default element with an anchor tag. **Example: links** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/menu.module.css' export const Links = () => ( Help Documentation GitHub Changelog ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import styles from 'styles/menu.module.css' export const Links = () => ( Help }> Documentation } > GitHub } > Changelog ) ``` #### Vue ```vue ``` #### Svelte ```svelte Help {#snippet asChild(itemProps)} Documentation {/snippet} {#snippet asChild(itemProps)} GitHub {/snippet} {#snippet asChild(itemProps)} Changelog {/snippet} ``` ### Checkbox To add a checkbox to a menu item, use the `Menu.Checkbox` component. **Example: checkbox-items** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { CheckIcon, ChevronDownIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/menu.module.css' export const CheckboxItems = () => { const [showToolbar, setShowToolbar] = useState(true) const [showStatusBar, setShowStatusBar] = useState(false) return ( View Show Toolbar Show Status Bar ) } ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { CheckIcon, ChevronDownIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/menu.module.css' export const CheckboxItems = () => { const [showToolbar, setShowToolbar] = createSignal(true) const [showStatusBar, setShowStatusBar] = createSignal(false) return ( View Show Toolbar Show Status Bar ) } ``` #### Vue ```vue ``` #### Svelte ```svelte View Show Toolbar Show Status Bar ``` ### Radio Group To group radio option items, use the `Menu.RadioGroup` component. **Example: radio-items** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { CheckIcon, ChevronDownIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/menu.module.css' export const RadioItems = () => { const [sortBy, setSortBy] = useState('date') return ( Sort setSortBy(e.value)}> Sort By Name Date Modified Size Type ) } ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { CheckIcon, ChevronDownIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/menu.module.css' export const RadioItems = () => { const [sortBy, setSortBy] = createSignal('date') return ( Sort setSortBy(e.value)}> Sort By Name Date Modified Size Type ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Sort Sort By Name Date Modified Size Type ``` ### 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. **Example: context** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import styles from 'styles/menu.module.css' export const Context = () => ( Right click here Cut Copy Paste Delete ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import styles from 'styles/menu.module.css' export const Context = () => ( Right click here Cut Copy Paste Delete ) ``` #### Vue ```vue ``` #### Svelte ```svelte Right click here Cut Copy Paste Delete ``` ### Nested To show a nested menu, render another `Menu` component and use the `Menu.TriggerItem` component to open the submenu. **Example: nested** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/menu.module.css' export const Nested = () => ( File New File Open... Share Email Message AirDrop Export PDF PNG SVG Print... ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/menu.module.css' export const Nested = () => ( File New File Open... Share Email Message AirDrop Export PDF PNG SVG Print... ) ``` #### Vue ```vue ``` #### Svelte ```svelte File New File Open... Share Email Message AirDrop Export PDF PNG SVG Print... ``` ### Menu in Dialog When rendering a menu inside a dialog, use `lazyMount` and `unmountOnExit` to ensure proper cleanup when the dialog closes. **Example: menu-in-dialog** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Menu } from '@ark-ui/react/menu' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/menu.module.css' export const MenuInDialog = () => ( Open Dialog Settings Configure your preferences below.
                    Select theme Light Dark System
                    ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/menu.module.css' export const MenuInDialog = () => ( Open Dialog Settings Configure your preferences below.
                    Select theme Light Dark System
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Settings Configure your preferences below.
                    Select theme Light Dark System
                    ``` ### Menu Item Dialog Open a confirmation dialog from a menu item. This pattern is useful for destructive actions like delete that require user confirmation. **Example: menu-item-dialog** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Menu } from '@ark-ui/react/menu' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/menu.module.css' export const MenuItemDialog = () => { const [dialogOpen, setDialogOpen] = useState(false) return ( <> Actions Edit Duplicate setDialogOpen(true)}> Delete... setDialogOpen(e.open)} role="alertdialog"> Confirm Delete Are you sure you want to delete this item? This action cannot be undone.
                    ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/menu.module.css' export const MenuItemDialog = () => { const [dialogOpen, setDialogOpen] = createSignal(false) return ( <> Actions Edit Duplicate setDialogOpen(true)}> Delete... setDialogOpen(e.open)} role="alertdialog"> Confirm Delete Are you sure you want to delete this item? This action cannot be undone.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Actions Edit Duplicate (dialogOpen = true)}>Delete... Confirm Delete Are you sure you want to delete this item? This action cannot be undone.
                    ``` ## Guides ### Custom IDs Ark UI autogenerates ids for menu items internally. Passing a custom `id` prop breaks the internal `getElementById` functionality used by the component. ```tsx // ❌ Don't do this Custom Item // ✅ Do this Custom Item ``` ### Links To render a menu item as a link, render the link as the menu item itself using the `asChild` prop, not as a child of the menu item. > This pattern ensures the link element receives the correct ARIA attributes and keyboard interactions from the menu > item. Here's an example of a reusable `MenuItemLink` component: ```tsx interface MenuItemLinkProps extends Menu.ItemProps { href?: string target?: string } export const MenuItemLink = (props: MenuItemLinkProps) => { const { href, target, children, ...rest } = props return ( {children} ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. | | `aria-label` | `string` | No | The accessibility label for the menu | | `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected | | `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item. | | `defaultOpen` | `boolean` | No | The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu. | | `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string contextTrigger: string content: string groupLabel: (id: string) => string group: (id: string) => string positioner: string arrow: string }>` | No | The ids of the elements in the menu. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when the highlighted menu item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the menu opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when a menu item is selected. | | `open` | `boolean` | No | The controlled open state of the menu | | `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CheckboxItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `checked` | `boolean` | Yes | Whether the option is checked | | `value` | `string` | Yes | The value of the option | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onCheckedChange` | `(checked: boolean) => void` | No | Function called when the option state is changed | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | menu | | `[data-has-nested]` | menu | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested menus | **ContextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ContextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | context-trigger | | `[data-state]` | "open" | "closed" | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The unique value of the menu item option. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onSelect` | `VoidFunction` | No | The function to call when the item is selected | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-value]` | The value of the item | | `[data-valuetext]` | The human-readable value | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RadioItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `onValueChange` | `(e: ValueChangeDetails) => void` | No | | | `value` | `string` | No | | **RadioItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the option | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMenuReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TriggerItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. | | `aria-label` | `string` | No | The accessibility label for the menu | | `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected | | `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item. | | `defaultOpen` | `boolean` | No | The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu. | | `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string contextTrigger: string content: string groupLabel: (id: string) => string group: (id: string) => string positioner: string arrow: string }>` | No | The ids of the elements in the menu. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when the highlighted menu item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the menu opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when a menu item is selected. | | `open` | `boolean` | No | The controlled open state of the menu | | `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CheckboxItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `checked` | `boolean` | Yes | Whether the option is checked | | `value` | `string` | Yes | The value of the option | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onCheckedChange` | `(checked: boolean) => void` | No | Function called when the option state is changed | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | menu | | `[data-has-nested]` | menu | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested menus | **ContextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ContextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | context-trigger | | `[data-state]` | "open" | "closed" | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The unique value of the menu item option. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onSelect` | `VoidFunction` | No | The function to call when the item is selected | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-value]` | The value of the item | | `[data-valuetext]` | The human-readable value | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RadioItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `onValueChange` | `(e: ValueChangeDetails) => void` | No | | | `value` | `string` | No | | **RadioItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the option | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMenuReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'hr'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TriggerItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. | | `aria-label` | `string` | No | The accessibility label for the menu | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected | | `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item. | | `defaultOpen` | `boolean` | No | The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu. | | `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string contextTrigger: string content: string groupLabel(id: string): string group(id: string): string positioner: string arrow: string }>` | No | The ids of the elements in the menu. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element | | `open` | `boolean` | No | The controlled open state of the menu | | `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu | | `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CheckboxItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `checked` | `boolean` | Yes | Whether the option is checked | | `value` | `string` | Yes | The value of the option | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | menu | | `[data-has-nested]` | menu | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested menus | **ContextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ContextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | context-trigger | | `[data-state]` | "open" | "closed" | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The `id` of the element that provides accessibility label to the option group | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The unique value of the menu item option. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-value]` | The value of the item | | `[data-valuetext]` | The human-readable value | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RadioItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | | `modelValue` | `string` | No | | **RadioItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the option | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMenuReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TriggerItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. | | `aria-label` | `string` | No | The accessibility label for the menu | | `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected | | `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item. | | `defaultOpen` | `boolean` | No | The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu. | | `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string contextTrigger: string content: string groupLabel: (id: string) => string group: (id: string) => string positioner: string arrow: string }>` | No | The ids of the elements in the menu. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when the highlighted menu item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the menu opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when a menu item is selected. | | `open` | `boolean` | No | The controlled open state of the menu | | `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **CheckboxItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `checked` | `boolean` | Yes | Whether the option is checked | | `value` | `string` | Yes | The value of the option | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onCheckedChange` | `(checked: boolean) => void` | No | Function called when the option state is changed | | `ref` | `Element` | No | | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | menu | | `[data-has-nested]` | menu | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested menus | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseMenuContext]>` | Yes | | **ContextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ContextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | context-trigger | | `[data-state]` | "open" | "closed" | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseMenuItemContext]>` | Yes | | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The `id` of the element that provides accessibility label to the option group | | `ref` | `Element` | No | | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The unique value of the menu item option. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onSelect` | `VoidFunction` | No | The function to call when the item is selected | | `ref` | `Element` | No | | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-value]` | The value of the item | | `[data-valuetext]` | The human-readable value | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RadioItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | | `onValueChange` | `(e: ValueChangeDetails) => void` | No | | | `ref` | `Element` | No | | | `value` | `string` | No | | **RadioItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the option | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `ref` | `Element` | No | | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMenuReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TriggerItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the menu is open | | `setOpen` | `(open: boolean) => void` | Function to open or close the menu | | `highlightedValue` | `string` | The id of the currently highlighted menuitem | | `setHighlightedValue` | `(value: string) => void` | Function to set the highlighted menuitem | | `setParent` | `(parent: ParentMenuService) => void` | Function to register a parent menu. This is used for submenus | | `setChild` | `(child: ChildMenuService) => void` | Function to register a child menu. This is used for submenus | | `reposition` | `(options?: Partial) => void` | Function to reposition the popover | | `getOptionItemState` | `(props: OptionItemProps) => OptionItemState` | Returns the state of the option item | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of the menu item | | `addItemListener` | `(props: ItemListenerProps) => VoidFunction` | Setup the custom event listener for item selection event | ## Accessibility Complies with the [Menu WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/). ### Keyboard Support **`Space`** Description: Activates/Selects the highlighted item **`Enter`** Description: Activates/Selects the highlighted item **`ArrowDown`** Description: Highlights the next item in the menu **`ArrowUp`** Description: Highlights the previous item in the menu **`ArrowRight + ArrowLeft`** Description: When focus is on trigger, opens or closes the submenu depending on reading direction. **`Esc`** Description: Closes the menu and moves focus to the trigger --- # Menu (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/menu.module.css' export const Basic = () => ( File New File Open... Save Save As... ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import styles from 'styles/menu.module.css' export const Basic = () => ( File New File Open... Save Save As... ) ``` #### Vue ```vue ``` #### Svelte ```svelte File New File Open... Save Save As... ``` ### Item Selection Use `onSelect` to handle item selection. The callback receives the item's `id`. **Example: controlled** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/menu.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return (
                    setOpen(e.open)}> Actions Edit Duplicate Archive Delete
                    ) } ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/menu.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return (
                    setOpen(e.open)}> Actions Edit Duplicate Archive Delete
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Actions Edit Duplicate Archive Delete
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Menu, useMenu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/menu.module.css' export const RootProvider = () => { const menu = useMenu() return (
                    Edit Cut Copy Paste Delete
                    ) } ``` #### Solid ```tsx import { Menu, useMenu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/menu.module.css' export const RootProvider = () => { const menu = useMenu() return (
                    Edit Cut Copy Paste Delete
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Edit Cut Copy Paste Delete
                    ``` ### Grouping Use `Menu.ItemGroup` and `Menu.ItemGroupLabel` to organize related menu items. **Example: group** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/menu.module.css' export const Group = () => ( Edit Clipboard Cut Copy Paste Selection Select All Deselect ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import styles from 'styles/menu.module.css' export const Group = () => ( Edit Clipboard Cut Copy Paste Selection Select All Deselect ) ``` #### Vue ```vue ``` #### Svelte ```svelte Edit Clipboard Cut Copy Paste Selection Select All Deselect ``` ### Links To render menu items as links, use the `asChild` prop to replace the default element with an anchor tag. **Example: links** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/menu.module.css' export const Links = () => ( Help Documentation GitHub Changelog ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import styles from 'styles/menu.module.css' export const Links = () => ( Help }> Documentation } > GitHub } > Changelog ) ``` #### Vue ```vue ``` #### Svelte ```svelte Help {#snippet asChild(itemProps)} Documentation {/snippet} {#snippet asChild(itemProps)} GitHub {/snippet} {#snippet asChild(itemProps)} Changelog {/snippet} ``` ### Checkbox To add a checkbox to a menu item, use the `Menu.Checkbox` component. **Example: checkbox-items** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { CheckIcon, ChevronDownIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/menu.module.css' export const CheckboxItems = () => { const [showToolbar, setShowToolbar] = useState(true) const [showStatusBar, setShowStatusBar] = useState(false) return ( View Show Toolbar Show Status Bar ) } ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { CheckIcon, ChevronDownIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/menu.module.css' export const CheckboxItems = () => { const [showToolbar, setShowToolbar] = createSignal(true) const [showStatusBar, setShowStatusBar] = createSignal(false) return ( View Show Toolbar Show Status Bar ) } ``` #### Vue ```vue ``` #### Svelte ```svelte View Show Toolbar Show Status Bar ``` ### Radio Group To group radio option items, use the `Menu.RadioGroup` component. **Example: radio-items** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { CheckIcon, ChevronDownIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/menu.module.css' export const RadioItems = () => { const [sortBy, setSortBy] = useState('date') return ( Sort setSortBy(e.value)}> Sort By Name Date Modified Size Type ) } ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { CheckIcon, ChevronDownIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/menu.module.css' export const RadioItems = () => { const [sortBy, setSortBy] = createSignal('date') return ( Sort setSortBy(e.value)}> Sort By Name Date Modified Size Type ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Sort Sort By Name Date Modified Size Type ``` ### 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. **Example: context** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import styles from 'styles/menu.module.css' export const Context = () => ( Right click here Cut Copy Paste Delete ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import styles from 'styles/menu.module.css' export const Context = () => ( Right click here Cut Copy Paste Delete ) ``` #### Vue ```vue ``` #### Svelte ```svelte Right click here Cut Copy Paste Delete ``` ### Nested To show a nested menu, render another `Menu` component and use the `Menu.TriggerItem` component to open the submenu. **Example: nested** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/menu.module.css' export const Nested = () => ( File New File Open... Share Email Message AirDrop Export PDF PNG SVG Print... ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/menu.module.css' export const Nested = () => ( File New File Open... Share Email Message AirDrop Export PDF PNG SVG Print... ) ``` #### Vue ```vue ``` #### Svelte ```svelte File New File Open... Share Email Message AirDrop Export PDF PNG SVG Print... ``` ### Menu in Dialog When rendering a menu inside a dialog, use `lazyMount` and `unmountOnExit` to ensure proper cleanup when the dialog closes. **Example: menu-in-dialog** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Menu } from '@ark-ui/react/menu' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/menu.module.css' export const MenuInDialog = () => ( Open Dialog Settings Configure your preferences below.
                    Select theme Light Dark System
                    ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/menu.module.css' export const MenuInDialog = () => ( Open Dialog Settings Configure your preferences below.
                    Select theme Light Dark System
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Settings Configure your preferences below.
                    Select theme Light Dark System
                    ``` ### Menu Item Dialog Open a confirmation dialog from a menu item. This pattern is useful for destructive actions like delete that require user confirmation. **Example: menu-item-dialog** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Menu } from '@ark-ui/react/menu' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/menu.module.css' export const MenuItemDialog = () => { const [dialogOpen, setDialogOpen] = useState(false) return ( <> Actions Edit Duplicate setDialogOpen(true)}> Delete... setDialogOpen(e.open)} role="alertdialog"> Confirm Delete Are you sure you want to delete this item? This action cannot be undone.
                    ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/menu.module.css' export const MenuItemDialog = () => { const [dialogOpen, setDialogOpen] = createSignal(false) return ( <> Actions Edit Duplicate setDialogOpen(true)}> Delete... setDialogOpen(e.open)} role="alertdialog"> Confirm Delete Are you sure you want to delete this item? This action cannot be undone.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Actions Edit Duplicate (dialogOpen = true)}>Delete... Confirm Delete Are you sure you want to delete this item? This action cannot be undone.
                    ``` ## Guides ### Custom IDs Ark UI autogenerates ids for menu items internally. Passing a custom `id` prop breaks the internal `getElementById` functionality used by the component. ```tsx // ❌ Don't do this Custom Item // ✅ Do this Custom Item ``` ### Links To render a menu item as a link, render the link as the menu item itself using the `asChild` prop, not as a child of the menu item. > This pattern ensures the link element receives the correct ARIA attributes and keyboard interactions from the menu > item. Here's an example of a reusable `MenuItemLink` component: ```tsx interface MenuItemLinkProps extends Menu.ItemProps { href?: string target?: string } export const MenuItemLink = (props: MenuItemLinkProps) => { const { href, target, children, ...rest } = props return ( {children} ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. | | `aria-label` | `string` | No | The accessibility label for the menu | | `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected | | `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item. | | `defaultOpen` | `boolean` | No | The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu. | | `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string contextTrigger: string content: string groupLabel: (id: string) => string group: (id: string) => string positioner: string arrow: string }>` | No | The ids of the elements in the menu. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when the highlighted menu item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the menu opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when a menu item is selected. | | `open` | `boolean` | No | The controlled open state of the menu | | `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CheckboxItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `checked` | `boolean` | Yes | Whether the option is checked | | `value` | `string` | Yes | The value of the option | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onCheckedChange` | `(checked: boolean) => void` | No | Function called when the option state is changed | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | menu | | `[data-has-nested]` | menu | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested menus | **ContextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ContextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | context-trigger | | `[data-state]` | "open" | "closed" | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The unique value of the menu item option. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onSelect` | `VoidFunction` | No | The function to call when the item is selected | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-value]` | The value of the item | | `[data-valuetext]` | The human-readable value | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RadioItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `onValueChange` | `(e: ValueChangeDetails) => void` | No | | | `value` | `string` | No | | **RadioItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the option | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMenuReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TriggerItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. | | `aria-label` | `string` | No | The accessibility label for the menu | | `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected | | `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item. | | `defaultOpen` | `boolean` | No | The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu. | | `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string contextTrigger: string content: string groupLabel: (id: string) => string group: (id: string) => string positioner: string arrow: string }>` | No | The ids of the elements in the menu. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when the highlighted menu item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the menu opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when a menu item is selected. | | `open` | `boolean` | No | The controlled open state of the menu | | `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CheckboxItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `checked` | `boolean` | Yes | Whether the option is checked | | `value` | `string` | Yes | The value of the option | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onCheckedChange` | `(checked: boolean) => void` | No | Function called when the option state is changed | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | menu | | `[data-has-nested]` | menu | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested menus | **ContextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ContextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | context-trigger | | `[data-state]` | "open" | "closed" | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The unique value of the menu item option. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onSelect` | `VoidFunction` | No | The function to call when the item is selected | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-value]` | The value of the item | | `[data-valuetext]` | The human-readable value | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RadioItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `onValueChange` | `(e: ValueChangeDetails) => void` | No | | | `value` | `string` | No | | **RadioItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the option | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMenuReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'hr'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TriggerItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. | | `aria-label` | `string` | No | The accessibility label for the menu | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected | | `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item. | | `defaultOpen` | `boolean` | No | The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu. | | `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string contextTrigger: string content: string groupLabel(id: string): string group(id: string): string positioner: string arrow: string }>` | No | The ids of the elements in the menu. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element | | `open` | `boolean` | No | The controlled open state of the menu | | `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu | | `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CheckboxItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `checked` | `boolean` | Yes | Whether the option is checked | | `value` | `string` | Yes | The value of the option | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | menu | | `[data-has-nested]` | menu | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested menus | **ContextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ContextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | context-trigger | | `[data-state]` | "open" | "closed" | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The `id` of the element that provides accessibility label to the option group | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The unique value of the menu item option. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-value]` | The value of the item | | `[data-valuetext]` | The human-readable value | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RadioItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | | `modelValue` | `string` | No | | **RadioItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the option | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMenuReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TriggerItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. | | `aria-label` | `string` | No | The accessibility label for the menu | | `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected | | `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item. | | `defaultOpen` | `boolean` | No | The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu. | | `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string contextTrigger: string content: string groupLabel: (id: string) => string group: (id: string) => string positioner: string arrow: string }>` | No | The ids of the elements in the menu. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when the highlighted menu item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the menu opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when a menu item is selected. | | `open` | `boolean` | No | The controlled open state of the menu | | `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **CheckboxItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `checked` | `boolean` | Yes | Whether the option is checked | | `value` | `string` | Yes | The value of the option | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onCheckedChange` | `(checked: boolean) => void` | No | Function called when the option state is changed | | `ref` | `Element` | No | | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | menu | | `[data-has-nested]` | menu | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested menus | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseMenuContext]>` | Yes | | **ContextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ContextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | context-trigger | | `[data-state]` | "open" | "closed" | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseMenuItemContext]>` | Yes | | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The `id` of the element that provides accessibility label to the option group | | `ref` | `Element` | No | | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The unique value of the menu item option. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onSelect` | `VoidFunction` | No | The function to call when the item is selected | | `ref` | `Element` | No | | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-value]` | The value of the item | | `[data-valuetext]` | The human-readable value | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RadioItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | | `onValueChange` | `(e: ValueChangeDetails) => void` | No | | | `ref` | `Element` | No | | | `value` | `string` | No | | **RadioItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the option | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `ref` | `Element` | No | | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMenuReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TriggerItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the menu is open | | `setOpen` | `(open: boolean) => void` | Function to open or close the menu | | `highlightedValue` | `string` | The id of the currently highlighted menuitem | | `setHighlightedValue` | `(value: string) => void` | Function to set the highlighted menuitem | | `setParent` | `(parent: ParentMenuService) => void` | Function to register a parent menu. This is used for submenus | | `setChild` | `(child: ChildMenuService) => void` | Function to register a child menu. This is used for submenus | | `reposition` | `(options?: Partial) => void` | Function to reposition the popover | | `getOptionItemState` | `(props: OptionItemProps) => OptionItemState` | Returns the state of the option item | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of the menu item | | `addItemListener` | `(props: ItemListenerProps) => VoidFunction` | Setup the custom event listener for item selection event | ## Accessibility Complies with the [Menu WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/). ### Keyboard Support **`Space`** Description: Activates/Selects the highlighted item **`Enter`** Description: Activates/Selects the highlighted item **`ArrowDown`** Description: Highlights the next item in the menu **`ArrowUp`** Description: Highlights the previous item in the menu **`ArrowRight + ArrowLeft`** Description: When focus is on trigger, opens or closes the submenu depending on reading direction. **`Esc`** Description: Closes the menu and moves focus to the trigger --- # Menu (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/menu.module.css' export const Basic = () => ( File New File Open... Save Save As... ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import styles from 'styles/menu.module.css' export const Basic = () => ( File New File Open... Save Save As... ) ``` #### Vue ```vue ``` #### Svelte ```svelte File New File Open... Save Save As... ``` ### Item Selection Use `onSelect` to handle item selection. The callback receives the item's `id`. **Example: controlled** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/menu.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return (
                    setOpen(e.open)}> Actions Edit Duplicate Archive Delete
                    ) } ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/menu.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return (
                    setOpen(e.open)}> Actions Edit Duplicate Archive Delete
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Actions Edit Duplicate Archive Delete
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Menu, useMenu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/menu.module.css' export const RootProvider = () => { const menu = useMenu() return (
                    Edit Cut Copy Paste Delete
                    ) } ``` #### Solid ```tsx import { Menu, useMenu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/menu.module.css' export const RootProvider = () => { const menu = useMenu() return (
                    Edit Cut Copy Paste Delete
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Edit Cut Copy Paste Delete
                    ``` ### Grouping Use `Menu.ItemGroup` and `Menu.ItemGroupLabel` to organize related menu items. **Example: group** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/menu.module.css' export const Group = () => ( Edit Clipboard Cut Copy Paste Selection Select All Deselect ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import styles from 'styles/menu.module.css' export const Group = () => ( Edit Clipboard Cut Copy Paste Selection Select All Deselect ) ``` #### Vue ```vue ``` #### Svelte ```svelte Edit Clipboard Cut Copy Paste Selection Select All Deselect ``` ### Links To render menu items as links, use the `asChild` prop to replace the default element with an anchor tag. **Example: links** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/menu.module.css' export const Links = () => ( Help Documentation GitHub Changelog ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import styles from 'styles/menu.module.css' export const Links = () => ( Help }> Documentation } > GitHub } > Changelog ) ``` #### Vue ```vue ``` #### Svelte ```svelte Help {#snippet asChild(itemProps)} Documentation {/snippet} {#snippet asChild(itemProps)} GitHub {/snippet} {#snippet asChild(itemProps)} Changelog {/snippet} ``` ### Checkbox To add a checkbox to a menu item, use the `Menu.Checkbox` component. **Example: checkbox-items** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { CheckIcon, ChevronDownIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/menu.module.css' export const CheckboxItems = () => { const [showToolbar, setShowToolbar] = useState(true) const [showStatusBar, setShowStatusBar] = useState(false) return ( View Show Toolbar Show Status Bar ) } ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { CheckIcon, ChevronDownIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/menu.module.css' export const CheckboxItems = () => { const [showToolbar, setShowToolbar] = createSignal(true) const [showStatusBar, setShowStatusBar] = createSignal(false) return ( View Show Toolbar Show Status Bar ) } ``` #### Vue ```vue ``` #### Svelte ```svelte View Show Toolbar Show Status Bar ``` ### Radio Group To group radio option items, use the `Menu.RadioGroup` component. **Example: radio-items** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { CheckIcon, ChevronDownIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/menu.module.css' export const RadioItems = () => { const [sortBy, setSortBy] = useState('date') return ( Sort setSortBy(e.value)}> Sort By Name Date Modified Size Type ) } ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { CheckIcon, ChevronDownIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/menu.module.css' export const RadioItems = () => { const [sortBy, setSortBy] = createSignal('date') return ( Sort setSortBy(e.value)}> Sort By Name Date Modified Size Type ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Sort Sort By Name Date Modified Size Type ``` ### 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. **Example: context** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import styles from 'styles/menu.module.css' export const Context = () => ( Right click here Cut Copy Paste Delete ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import styles from 'styles/menu.module.css' export const Context = () => ( Right click here Cut Copy Paste Delete ) ``` #### Vue ```vue ``` #### Svelte ```svelte Right click here Cut Copy Paste Delete ``` ### Nested To show a nested menu, render another `Menu` component and use the `Menu.TriggerItem` component to open the submenu. **Example: nested** #### React ```tsx import { Menu } from '@ark-ui/react/menu' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon } from 'lucide-react' import styles from 'styles/menu.module.css' export const Nested = () => ( File New File Open... Share Email Message AirDrop Export PDF PNG SVG Print... ) ``` #### Solid ```tsx import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import styles from 'styles/menu.module.css' export const Nested = () => ( File New File Open... Share Email Message AirDrop Export PDF PNG SVG Print... ) ``` #### Vue ```vue ``` #### Svelte ```svelte File New File Open... Share Email Message AirDrop Export PDF PNG SVG Print... ``` ### Menu in Dialog When rendering a menu inside a dialog, use `lazyMount` and `unmountOnExit` to ensure proper cleanup when the dialog closes. **Example: menu-in-dialog** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Menu } from '@ark-ui/react/menu' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/menu.module.css' export const MenuInDialog = () => ( Open Dialog Settings Configure your preferences below.
                    Select theme Light Dark System
                    ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon, XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/menu.module.css' export const MenuInDialog = () => ( Open Dialog Settings Configure your preferences below.
                    Select theme Light Dark System
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Settings Configure your preferences below.
                    Select theme Light Dark System
                    ``` ### Menu Item Dialog Open a confirmation dialog from a menu item. This pattern is useful for destructive actions like delete that require user confirmation. **Example: menu-item-dialog** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Menu } from '@ark-ui/react/menu' import { Portal } from '@ark-ui/react/portal' import { ChevronDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/menu.module.css' export const MenuItemDialog = () => { const [dialogOpen, setDialogOpen] = useState(false) return ( <> Actions Edit Duplicate setDialogOpen(true)}> Delete... setDialogOpen(e.open)} role="alertdialog"> Confirm Delete Are you sure you want to delete this item? This action cannot be undone.
                    ) } ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { Menu } from '@ark-ui/solid/menu' import { ChevronDownIcon, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/menu.module.css' export const MenuItemDialog = () => { const [dialogOpen, setDialogOpen] = createSignal(false) return ( <> Actions Edit Duplicate setDialogOpen(true)}> Delete... setDialogOpen(e.open)} role="alertdialog"> Confirm Delete Are you sure you want to delete this item? This action cannot be undone.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Actions Edit Duplicate (dialogOpen = true)}>Delete... Confirm Delete Are you sure you want to delete this item? This action cannot be undone.
                    ``` ## Guides ### Custom IDs Ark UI autogenerates ids for menu items internally. Passing a custom `id` prop breaks the internal `getElementById` functionality used by the component. ```tsx // ❌ Don't do this Custom Item // ✅ Do this Custom Item ``` ### Links To render a menu item as a link, render the link as the menu item itself using the `asChild` prop, not as a child of the menu item. > This pattern ensures the link element receives the correct ARIA attributes and keyboard interactions from the menu > item. Here's an example of a reusable `MenuItemLink` component: ```tsx interface MenuItemLinkProps extends Menu.ItemProps { href?: string target?: string } export const MenuItemLink = (props: MenuItemLinkProps) => { const { href, target, children, ...rest } = props return ( {children} ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. | | `aria-label` | `string` | No | The accessibility label for the menu | | `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected | | `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item. | | `defaultOpen` | `boolean` | No | The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu. | | `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string contextTrigger: string content: string groupLabel: (id: string) => string group: (id: string) => string positioner: string arrow: string }>` | No | The ids of the elements in the menu. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when the highlighted menu item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the menu opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when a menu item is selected. | | `open` | `boolean` | No | The controlled open state of the menu | | `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CheckboxItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `checked` | `boolean` | Yes | Whether the option is checked | | `value` | `string` | Yes | The value of the option | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onCheckedChange` | `(checked: boolean) => void` | No | Function called when the option state is changed | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | menu | | `[data-has-nested]` | menu | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested menus | **ContextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ContextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | context-trigger | | `[data-state]` | "open" | "closed" | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The unique value of the menu item option. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onSelect` | `VoidFunction` | No | The function to call when the item is selected | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-value]` | The value of the item | | `[data-valuetext]` | The human-readable value | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RadioItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `onValueChange` | `(e: ValueChangeDetails) => void` | No | | | `value` | `string` | No | | **RadioItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the option | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMenuReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TriggerItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. | | `aria-label` | `string` | No | The accessibility label for the menu | | `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected | | `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item. | | `defaultOpen` | `boolean` | No | The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu. | | `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string contextTrigger: string content: string groupLabel: (id: string) => string group: (id: string) => string positioner: string arrow: string }>` | No | The ids of the elements in the menu. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when the highlighted menu item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the menu opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when a menu item is selected. | | `open` | `boolean` | No | The controlled open state of the menu | | `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CheckboxItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `checked` | `boolean` | Yes | Whether the option is checked | | `value` | `string` | Yes | The value of the option | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onCheckedChange` | `(checked: boolean) => void` | No | Function called when the option state is changed | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | menu | | `[data-has-nested]` | menu | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested menus | **ContextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ContextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | context-trigger | | `[data-state]` | "open" | "closed" | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The unique value of the menu item option. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onSelect` | `VoidFunction` | No | The function to call when the item is selected | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-value]` | The value of the item | | `[data-valuetext]` | The human-readable value | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RadioItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `onValueChange` | `(e: ValueChangeDetails) => void` | No | | | `value` | `string` | No | | **RadioItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the option | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMenuReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'hr'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TriggerItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. | | `aria-label` | `string` | No | The accessibility label for the menu | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected | | `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item. | | `defaultOpen` | `boolean` | No | The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu. | | `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string contextTrigger: string content: string groupLabel(id: string): string group(id: string): string positioner: string arrow: string }>` | No | The ids of the elements in the menu. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element | | `open` | `boolean` | No | The controlled open state of the menu | | `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu | | `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CheckboxItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `checked` | `boolean` | Yes | Whether the option is checked | | `value` | `string` | Yes | The value of the option | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | menu | | `[data-has-nested]` | menu | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested menus | **ContextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ContextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | context-trigger | | `[data-state]` | "open" | "closed" | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The `id` of the element that provides accessibility label to the option group | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The unique value of the menu item option. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-value]` | The value of the item | | `[data-valuetext]` | The human-readable value | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RadioItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | | `modelValue` | `string` | No | | **RadioItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the option | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMenuReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TriggerItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `anchorPoint` | `Point` | No | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. | | `aria-label` | `string` | No | The accessibility label for the menu | | `closeOnSelect` | `boolean` | No | Whether to close the menu when an option is selected | | `composite` | `boolean` | No | Whether the menu is a composed with other composite widgets like a combobox or tabs | | `defaultHighlightedValue` | `string` | No | The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item. | | `defaultOpen` | `boolean` | No | The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu. | | `highlightedValue` | `string` | No | The controlled highlighted value of the menu item. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string contextTrigger: string content: string groupLabel: (id: string) => string group: (id: string) => string positioner: string arrow: string }>` | No | The ids of the elements in the menu. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected item if it's an anchor element | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Function called when the highlighted menu item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the menu opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when a menu item is selected. | | `open` | `boolean` | No | The controlled open state of the menu | | `positioning` | `PositioningOptions` | No | The options used to dynamically position the menu | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `typeahead` | `boolean` | No | Whether the pressing printable characters should trigger typeahead navigation | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **CheckboxItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `checked` | `boolean` | Yes | Whether the option is checked | | `value` | `string` | Yes | The value of the option | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onCheckedChange` | `(checked: boolean) => void` | No | Function called when the option state is changed | | `ref` | `Element` | No | | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | menu | | `[data-has-nested]` | menu | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested menus | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseMenuContext]>` | Yes | | **ContextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ContextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | context-trigger | | `[data-state]` | "open" | "closed" | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseMenuItemContext]>` | Yes | | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The `id` of the element that provides accessibility label to the option group | | `ref` | `Element` | No | | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The unique value of the menu item option. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `onSelect` | `VoidFunction` | No | The function to call when the item is selected | | `ref` | `Element` | No | | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-value]` | The value of the item | | `[data-valuetext]` | The human-readable value | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | | `[data-state]` | "checked" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RadioItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | | `onValueChange` | `(e: ValueChangeDetails) => void` | No | | | `ref` | `Element` | No | | | `value` | `string` | No | | **RadioItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the option | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the menu should be closed when the option is selected. | | `disabled` | `boolean` | No | Whether the menu item is disabled | | `ref` | `Element` | No | | | `valueText` | `string` | No | The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseMenuReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **TriggerItem Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | menu | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the menu is open | | `setOpen` | `(open: boolean) => void` | Function to open or close the menu | | `highlightedValue` | `string` | The id of the currently highlighted menuitem | | `setHighlightedValue` | `(value: string) => void` | Function to set the highlighted menuitem | | `setParent` | `(parent: ParentMenuService) => void` | Function to register a parent menu. This is used for submenus | | `setChild` | `(child: ChildMenuService) => void` | Function to register a child menu. This is used for submenus | | `reposition` | `(options?: Partial) => void` | Function to reposition the popover | | `getOptionItemState` | `(props: OptionItemProps) => OptionItemState` | Returns the state of the option item | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of the menu item | | `addItemListener` | `(props: ItemListenerProps) => VoidFunction` | Setup the custom event listener for item selection event | ## Accessibility Complies with the [Menu WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/menubar/). ### Keyboard Support **`Space`** Description: Activates/Selects the highlighted item **`Enter`** Description: Activates/Selects the highlighted item **`ArrowDown`** Description: Highlights the next item in the menu **`ArrowUp`** Description: Highlights the previous item in the menu **`ArrowRight + ArrowLeft`** Description: When focus is on trigger, opens or closes the submenu depending on reading direction. **`Esc`** Description: Closes the menu and moves focus to the trigger --- # Number Input (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const Basic = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const Basic = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### 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. **Example: min-max** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const MinMax = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const MinMax = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` > To allow values outside the min/max range, set `clampValueOnBlur` to `false`. ### 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`. **Example: fraction-digits** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const FractionDigits = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const FractionDigits = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### 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. **Example: scrubber** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon, ArrowLeftRightIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const Scrubber = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ArrowLeftRightIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const Scrubber = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### 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`. **Example: mouse-wheel** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const MouseWheel = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const MouseWheel = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### Formatting To apply custom formatting to the input's value, set the `formatOptions` and provide `Intl.NumberFormatOptions` such as `style` and `currency`. **Example: formatting** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const Formatting = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const Formatting = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/number-input.module.css' export const WithField = () => ( Label
                    Additional Info Error Info
                    ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import field from 'styles/field.module.css' import styles from 'styles/number-input.module.css' export const WithField = () => ( Label
                    Additional Info Error Info
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    Additional Info Error Info
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { NumberInput, useNumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const RootProvider = () => { const numberInput = useNumberInput() return (
                    valueAsNumber: {numberInput.valueAsNumber} Label
                    ) } ``` #### Solid ```tsx import { NumberInput, useNumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const RootProvider = () => { const numberInput = useNumberInput() return (
                    valueAsNumber: {numberInput().valueAsNumber} Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    valueAsNumber: {numberInput().valueAsNumber} Label
                    ``` ## Guides ### Scrubber The `NumberInput.Scrubber` component provides an interactive scrub area that allows users to drag to change the input value. It renders as a `
                    ` element and displays a custom cursor element during scrubbing interactions. This component utilizes the [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API) for smooth dragging interactions. > **Note:** Browsers may show a notification when the Pointer Lock API is activated. The scrubber is automatically > disabled in Safari to prevent layout shifts. ### Controlled When controlling the NumberInput component, it's recommended to use string values instead of converting to numbers. This is especially important when using `formatOptions` for currency or locale-specific formatting. ```tsx const [value, setValue] = useState('0') setValue(details.value)}> {/* ... */} ``` Converting values to numbers can cause issues with locale-specific formatting, particularly for currencies that use different decimal and thousands separators (e.g., `1.523,30` vs `1,523.30`). By keeping values as strings, you preserve the correct formatting and avoid parsing issues. If you need to submit a numeric value in your form, use a hidden input that reads `valueAsNumber` from `NumberInput.Context`: ```tsx setValue(details.value)}> {(context) => } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowMouseWheel` | `boolean` | No | Whether to allow mouse wheel to change the value | | `allowOverflow` | `boolean` | No | Whether to allow the value overflow the min/max range | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `clampValueOnBlur` | `boolean` | No | Whether to clamp the value when the input loses focus (blur) | | `defaultValue` | `string` | No | The initial value of the input when rendered. Use when you don't need to control the value of the input. | | `disabled` | `boolean` | No | Whether the number input is disabled. | | `focusInputOnChange` | `boolean` | No | Whether to focus input when the value changes | | `form` | `string` | No | The associate form of the input element. | | `formatOptions` | `NumberFormatOptions` | No | The options to pass to the `Intl.NumberFormat` constructor | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string input: string incrementTrigger: string decrementTrigger: string scrubber: string }>` | No | The ids of the elements in the number input. Useful for composition. | | `inputMode` | `InputMode` | No | Hints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices | | `invalid` | `boolean` | No | Whether the number input value is invalid. | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `max` | `number` | No | The maximum value of the number input | | `min` | `number` | No | The minimum value of the number input | | `name` | `string` | No | The name attribute of the number input. Useful for form submission. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the number input is focused | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value changes | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function invoked when the value overflows or underflows the min/max range | | `pattern` | `string` | No | The pattern used to check the element's value against | | `readOnly` | `boolean` | No | Whether the number input is readonly | | `required` | `boolean` | No | Whether the number input is required | | `spinOnPress` | `boolean` | No | Whether to spin the value when the increment/decrement button is pressed | | `step` | `number` | No | The amount to increment or decrement the value by | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `string` | No | The controlled value of the input | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | control | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **DecrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DecrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | decrement-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **IncrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IncrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | increment-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-scrubbing]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseNumberInputReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | scrubber | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | | `[data-scrubbing]` | | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowMouseWheel` | `boolean` | No | Whether to allow mouse wheel to change the value | | `allowOverflow` | `boolean` | No | Whether to allow the value overflow the min/max range | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `clampValueOnBlur` | `boolean` | No | Whether to clamp the value when the input loses focus (blur) | | `defaultValue` | `string` | No | The initial value of the input when rendered. Use when you don't need to control the value of the input. | | `disabled` | `boolean` | No | Whether the number input is disabled. | | `focusInputOnChange` | `boolean` | No | Whether to focus input when the value changes | | `form` | `string` | No | The associate form of the input element. | | `formatOptions` | `NumberFormatOptions` | No | The options to pass to the `Intl.NumberFormat` constructor | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string input: string incrementTrigger: string decrementTrigger: string scrubber: string }>` | No | The ids of the elements in the number input. Useful for composition. | | `inputMode` | `InputMode` | No | Hints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices | | `invalid` | `boolean` | No | Whether the number input value is invalid. | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `max` | `number` | No | The maximum value of the number input | | `min` | `number` | No | The minimum value of the number input | | `name` | `string` | No | The name attribute of the number input. Useful for form submission. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the number input is focused | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value changes | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function invoked when the value overflows or underflows the min/max range | | `pattern` | `string` | No | The pattern used to check the element's value against | | `readOnly` | `boolean` | No | Whether the number input is readonly | | `required` | `boolean` | No | Whether the number input is required | | `spinOnPress` | `boolean` | No | Whether to spin the value when the increment/decrement button is pressed | | `step` | `number` | No | The amount to increment or decrement the value by | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `string` | No | The controlled value of the input | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | control | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **DecrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DecrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | decrement-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **IncrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IncrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | increment-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-scrubbing]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseNumberInputReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | scrubber | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | | `[data-scrubbing]` | | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowMouseWheel` | `boolean` | No | Whether to allow mouse wheel to change the value | | `allowOverflow` | `boolean` | No | Whether to allow the value overflow the min/max range | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `clampValueOnBlur` | `boolean` | No | Whether to clamp the value when the input loses focus (blur) | | `defaultValue` | `string` | No | The initial value of the input when rendered. Use when you don't need to control the value of the input. | | `disabled` | `boolean` | No | Whether the number input is disabled. | | `focusInputOnChange` | `boolean` | No | Whether to focus input when the value changes | | `form` | `string` | No | The associate form of the input element. | | `formatOptions` | `NumberFormatOptions` | No | The options to pass to the `Intl.NumberFormat` constructor | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string input: string incrementTrigger: string decrementTrigger: string scrubber: string }>` | No | The ids of the elements in the number input. Useful for composition. | | `inputMode` | `'text' | 'tel' | 'numeric' | 'decimal'` | No | Hints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices | | `invalid` | `boolean` | No | Whether the number input value is invalid. | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `max` | `number` | No | The maximum value of the number input | | `min` | `number` | No | The minimum value of the number input | | `modelValue` | `string` | No | The v-model value of the number input | | `name` | `string` | No | The name attribute of the number input. Useful for form submission. | | `pattern` | `string` | No | The pattern used to check the element's value against | | `readOnly` | `boolean` | No | Whether the number input is readonly | | `required` | `boolean` | No | Whether the number input is required | | `spinOnPress` | `boolean` | No | Whether to spin the value when the increment/decrement button is pressed | | `step` | `number` | No | The amount to increment or decrement the value by | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | control | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **DecrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DecrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | decrement-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **IncrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IncrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | increment-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-scrubbing]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `NumberInputApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | scrubber | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | | `[data-scrubbing]` | | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowMouseWheel` | `boolean` | No | Whether to allow mouse wheel to change the value | | `allowOverflow` | `boolean` | No | Whether to allow the value overflow the min/max range | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `clampValueOnBlur` | `boolean` | No | Whether to clamp the value when the input loses focus (blur) | | `defaultValue` | `string` | No | The initial value of the input when rendered. Use when you don't need to control the value of the input. | | `disabled` | `boolean` | No | Whether the number input is disabled. | | `focusInputOnChange` | `boolean` | No | Whether to focus input when the value changes | | `form` | `string` | No | The associate form of the input element. | | `formatOptions` | `NumberFormatOptions` | No | The options to pass to the `Intl.NumberFormat` constructor | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string input: string incrementTrigger: string decrementTrigger: string scrubber: string }>` | No | The ids of the elements in the number input. Useful for composition. | | `inputMode` | `InputMode` | No | Hints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices | | `invalid` | `boolean` | No | Whether the number input value is invalid. | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `max` | `number` | No | The maximum value of the number input | | `min` | `number` | No | The minimum value of the number input | | `name` | `string` | No | The name attribute of the number input. Useful for form submission. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the number input is focused | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value changes | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function invoked when the value overflows or underflows the min/max range | | `pattern` | `string` | No | The pattern used to check the element's value against | | `readOnly` | `boolean` | No | Whether the number input is readonly | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the number input is required | | `spinOnPress` | `boolean` | No | Whether to spin the value when the increment/decrement button is pressed | | `step` | `number` | No | The amount to increment or decrement the value by | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `string` | No | The controlled value of the input | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseNumberInputContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | control | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **DecrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **DecrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | decrement-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **IncrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **IncrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | increment-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-scrubbing]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseNumberInputReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Scrubber Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Scrubber Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | scrubber | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | | `[data-scrubbing]` | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focused` | `boolean` | Whether the input is focused. | | `invalid` | `boolean` | Whether the input is invalid. | | `empty` | `boolean` | Whether the input value is empty. | | `value` | `string` | The formatted value of the input. | | `valueAsNumber` | `number` | The value of the input as a number. | | `setValue` | `(value: number) => void` | Function to set the value of the input. | | `clearValue` | `VoidFunction` | Function to clear the value of the input. | | `increment` | `VoidFunction` | Function to increment the value of the input by the step. | | `decrement` | `VoidFunction` | Function to decrement the value of the input by the step. | | `setToMax` | `VoidFunction` | Function to set the value of the input to the max. | | `setToMin` | `VoidFunction` | Function to set the value of the input to the min. | | `focus` | `VoidFunction` | Function to focus the input. | ## Accessibility Complies with the [Spinbutton WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/). ### Keyboard Support **`ArrowUp`** Description: Increments the value of the number input by a predefined step. **`ArrowDown`** Description: Decrements the value of the number input by a predefined step. **`PageUp`** Description: Increments the value of the number input by a larger predefined step. **`PageDown`** Description: Decrements the value of the number input by a larger predefined step. **`Home`** Description: Sets the value of the number input to its minimum allowed value. **`End`** Description: Sets the value of the number input to its maximum allowed value. **`Enter`** Description: Submits the value entered in the number input. --- # Number Input (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const Basic = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const Basic = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### 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. **Example: min-max** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const MinMax = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const MinMax = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` > To allow values outside the min/max range, set `clampValueOnBlur` to `false`. ### 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`. **Example: fraction-digits** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const FractionDigits = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const FractionDigits = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### 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. **Example: scrubber** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon, ArrowLeftRightIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const Scrubber = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ArrowLeftRightIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const Scrubber = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### 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`. **Example: mouse-wheel** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const MouseWheel = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const MouseWheel = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### Formatting To apply custom formatting to the input's value, set the `formatOptions` and provide `Intl.NumberFormatOptions` such as `style` and `currency`. **Example: formatting** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const Formatting = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const Formatting = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/number-input.module.css' export const WithField = () => ( Label
                    Additional Info Error Info
                    ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import field from 'styles/field.module.css' import styles from 'styles/number-input.module.css' export const WithField = () => ( Label
                    Additional Info Error Info
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    Additional Info Error Info
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { NumberInput, useNumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const RootProvider = () => { const numberInput = useNumberInput() return (
                    valueAsNumber: {numberInput.valueAsNumber} Label
                    ) } ``` #### Solid ```tsx import { NumberInput, useNumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const RootProvider = () => { const numberInput = useNumberInput() return (
                    valueAsNumber: {numberInput().valueAsNumber} Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    valueAsNumber: {numberInput().valueAsNumber} Label
                    ``` ## Guides ### Scrubber The `NumberInput.Scrubber` component provides an interactive scrub area that allows users to drag to change the input value. It renders as a `
                    ` element and displays a custom cursor element during scrubbing interactions. This component utilizes the [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API) for smooth dragging interactions. > **Note:** Browsers may show a notification when the Pointer Lock API is activated. The scrubber is automatically > disabled in Safari to prevent layout shifts. ### Controlled When controlling the NumberInput component, it's recommended to use string values instead of converting to numbers. This is especially important when using `formatOptions` for currency or locale-specific formatting. ```tsx const [value, setValue] = useState('0') setValue(details.value)}> {/* ... */} ``` Converting values to numbers can cause issues with locale-specific formatting, particularly for currencies that use different decimal and thousands separators (e.g., `1.523,30` vs `1,523.30`). By keeping values as strings, you preserve the correct formatting and avoid parsing issues. If you need to submit a numeric value in your form, use a hidden input that reads `valueAsNumber` from `NumberInput.Context`: ```tsx setValue(details.value)}> {(context) => } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowMouseWheel` | `boolean` | No | Whether to allow mouse wheel to change the value | | `allowOverflow` | `boolean` | No | Whether to allow the value overflow the min/max range | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `clampValueOnBlur` | `boolean` | No | Whether to clamp the value when the input loses focus (blur) | | `defaultValue` | `string` | No | The initial value of the input when rendered. Use when you don't need to control the value of the input. | | `disabled` | `boolean` | No | Whether the number input is disabled. | | `focusInputOnChange` | `boolean` | No | Whether to focus input when the value changes | | `form` | `string` | No | The associate form of the input element. | | `formatOptions` | `NumberFormatOptions` | No | The options to pass to the `Intl.NumberFormat` constructor | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string input: string incrementTrigger: string decrementTrigger: string scrubber: string }>` | No | The ids of the elements in the number input. Useful for composition. | | `inputMode` | `InputMode` | No | Hints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices | | `invalid` | `boolean` | No | Whether the number input value is invalid. | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `max` | `number` | No | The maximum value of the number input | | `min` | `number` | No | The minimum value of the number input | | `name` | `string` | No | The name attribute of the number input. Useful for form submission. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the number input is focused | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value changes | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function invoked when the value overflows or underflows the min/max range | | `pattern` | `string` | No | The pattern used to check the element's value against | | `readOnly` | `boolean` | No | Whether the number input is readonly | | `required` | `boolean` | No | Whether the number input is required | | `spinOnPress` | `boolean` | No | Whether to spin the value when the increment/decrement button is pressed | | `step` | `number` | No | The amount to increment or decrement the value by | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `string` | No | The controlled value of the input | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | control | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **DecrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DecrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | decrement-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **IncrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IncrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | increment-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-scrubbing]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseNumberInputReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | scrubber | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | | `[data-scrubbing]` | | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowMouseWheel` | `boolean` | No | Whether to allow mouse wheel to change the value | | `allowOverflow` | `boolean` | No | Whether to allow the value overflow the min/max range | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `clampValueOnBlur` | `boolean` | No | Whether to clamp the value when the input loses focus (blur) | | `defaultValue` | `string` | No | The initial value of the input when rendered. Use when you don't need to control the value of the input. | | `disabled` | `boolean` | No | Whether the number input is disabled. | | `focusInputOnChange` | `boolean` | No | Whether to focus input when the value changes | | `form` | `string` | No | The associate form of the input element. | | `formatOptions` | `NumberFormatOptions` | No | The options to pass to the `Intl.NumberFormat` constructor | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string input: string incrementTrigger: string decrementTrigger: string scrubber: string }>` | No | The ids of the elements in the number input. Useful for composition. | | `inputMode` | `InputMode` | No | Hints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices | | `invalid` | `boolean` | No | Whether the number input value is invalid. | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `max` | `number` | No | The maximum value of the number input | | `min` | `number` | No | The minimum value of the number input | | `name` | `string` | No | The name attribute of the number input. Useful for form submission. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the number input is focused | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value changes | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function invoked when the value overflows or underflows the min/max range | | `pattern` | `string` | No | The pattern used to check the element's value against | | `readOnly` | `boolean` | No | Whether the number input is readonly | | `required` | `boolean` | No | Whether the number input is required | | `spinOnPress` | `boolean` | No | Whether to spin the value when the increment/decrement button is pressed | | `step` | `number` | No | The amount to increment or decrement the value by | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `string` | No | The controlled value of the input | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | control | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **DecrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DecrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | decrement-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **IncrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IncrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | increment-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-scrubbing]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseNumberInputReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | scrubber | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | | `[data-scrubbing]` | | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowMouseWheel` | `boolean` | No | Whether to allow mouse wheel to change the value | | `allowOverflow` | `boolean` | No | Whether to allow the value overflow the min/max range | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `clampValueOnBlur` | `boolean` | No | Whether to clamp the value when the input loses focus (blur) | | `defaultValue` | `string` | No | The initial value of the input when rendered. Use when you don't need to control the value of the input. | | `disabled` | `boolean` | No | Whether the number input is disabled. | | `focusInputOnChange` | `boolean` | No | Whether to focus input when the value changes | | `form` | `string` | No | The associate form of the input element. | | `formatOptions` | `NumberFormatOptions` | No | The options to pass to the `Intl.NumberFormat` constructor | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string input: string incrementTrigger: string decrementTrigger: string scrubber: string }>` | No | The ids of the elements in the number input. Useful for composition. | | `inputMode` | `'text' | 'tel' | 'numeric' | 'decimal'` | No | Hints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices | | `invalid` | `boolean` | No | Whether the number input value is invalid. | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `max` | `number` | No | The maximum value of the number input | | `min` | `number` | No | The minimum value of the number input | | `modelValue` | `string` | No | The v-model value of the number input | | `name` | `string` | No | The name attribute of the number input. Useful for form submission. | | `pattern` | `string` | No | The pattern used to check the element's value against | | `readOnly` | `boolean` | No | Whether the number input is readonly | | `required` | `boolean` | No | Whether the number input is required | | `spinOnPress` | `boolean` | No | Whether to spin the value when the increment/decrement button is pressed | | `step` | `number` | No | The amount to increment or decrement the value by | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | control | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **DecrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DecrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | decrement-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **IncrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IncrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | increment-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-scrubbing]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `NumberInputApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | scrubber | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | | `[data-scrubbing]` | | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowMouseWheel` | `boolean` | No | Whether to allow mouse wheel to change the value | | `allowOverflow` | `boolean` | No | Whether to allow the value overflow the min/max range | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `clampValueOnBlur` | `boolean` | No | Whether to clamp the value when the input loses focus (blur) | | `defaultValue` | `string` | No | The initial value of the input when rendered. Use when you don't need to control the value of the input. | | `disabled` | `boolean` | No | Whether the number input is disabled. | | `focusInputOnChange` | `boolean` | No | Whether to focus input when the value changes | | `form` | `string` | No | The associate form of the input element. | | `formatOptions` | `NumberFormatOptions` | No | The options to pass to the `Intl.NumberFormat` constructor | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string input: string incrementTrigger: string decrementTrigger: string scrubber: string }>` | No | The ids of the elements in the number input. Useful for composition. | | `inputMode` | `InputMode` | No | Hints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices | | `invalid` | `boolean` | No | Whether the number input value is invalid. | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `max` | `number` | No | The maximum value of the number input | | `min` | `number` | No | The minimum value of the number input | | `name` | `string` | No | The name attribute of the number input. Useful for form submission. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the number input is focused | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value changes | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function invoked when the value overflows or underflows the min/max range | | `pattern` | `string` | No | The pattern used to check the element's value against | | `readOnly` | `boolean` | No | Whether the number input is readonly | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the number input is required | | `spinOnPress` | `boolean` | No | Whether to spin the value when the increment/decrement button is pressed | | `step` | `number` | No | The amount to increment or decrement the value by | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `string` | No | The controlled value of the input | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseNumberInputContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | control | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **DecrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **DecrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | decrement-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **IncrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **IncrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | increment-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-scrubbing]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseNumberInputReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Scrubber Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Scrubber Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | scrubber | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | | `[data-scrubbing]` | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focused` | `boolean` | Whether the input is focused. | | `invalid` | `boolean` | Whether the input is invalid. | | `empty` | `boolean` | Whether the input value is empty. | | `value` | `string` | The formatted value of the input. | | `valueAsNumber` | `number` | The value of the input as a number. | | `setValue` | `(value: number) => void` | Function to set the value of the input. | | `clearValue` | `VoidFunction` | Function to clear the value of the input. | | `increment` | `VoidFunction` | Function to increment the value of the input by the step. | | `decrement` | `VoidFunction` | Function to decrement the value of the input by the step. | | `setToMax` | `VoidFunction` | Function to set the value of the input to the max. | | `setToMin` | `VoidFunction` | Function to set the value of the input to the min. | | `focus` | `VoidFunction` | Function to focus the input. | ## Accessibility Complies with the [Spinbutton WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/). ### Keyboard Support **`ArrowUp`** Description: Increments the value of the number input by a predefined step. **`ArrowDown`** Description: Decrements the value of the number input by a predefined step. **`PageUp`** Description: Increments the value of the number input by a larger predefined step. **`PageDown`** Description: Decrements the value of the number input by a larger predefined step. **`Home`** Description: Sets the value of the number input to its minimum allowed value. **`End`** Description: Sets the value of the number input to its maximum allowed value. **`Enter`** Description: Submits the value entered in the number input. --- # Number Input (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const Basic = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const Basic = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### 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. **Example: min-max** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const MinMax = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const MinMax = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` > To allow values outside the min/max range, set `clampValueOnBlur` to `false`. ### 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`. **Example: fraction-digits** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const FractionDigits = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const FractionDigits = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### 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. **Example: scrubber** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon, ArrowLeftRightIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const Scrubber = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ArrowLeftRightIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const Scrubber = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### 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`. **Example: mouse-wheel** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const MouseWheel = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const MouseWheel = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### Formatting To apply custom formatting to the input's value, set the `formatOptions` and provide `Intl.NumberFormatOptions` such as `style` and `currency`. **Example: formatting** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const Formatting = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const Formatting = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/number-input.module.css' export const WithField = () => ( Label
                    Additional Info Error Info
                    ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import field from 'styles/field.module.css' import styles from 'styles/number-input.module.css' export const WithField = () => ( Label
                    Additional Info Error Info
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    Additional Info Error Info
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { NumberInput, useNumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const RootProvider = () => { const numberInput = useNumberInput() return (
                    valueAsNumber: {numberInput.valueAsNumber} Label
                    ) } ``` #### Solid ```tsx import { NumberInput, useNumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const RootProvider = () => { const numberInput = useNumberInput() return (
                    valueAsNumber: {numberInput().valueAsNumber} Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    valueAsNumber: {numberInput().valueAsNumber} Label
                    ``` ## Guides ### Scrubber The `NumberInput.Scrubber` component provides an interactive scrub area that allows users to drag to change the input value. It renders as a `
                    ` element and displays a custom cursor element during scrubbing interactions. This component utilizes the [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API) for smooth dragging interactions. > **Note:** Browsers may show a notification when the Pointer Lock API is activated. The scrubber is automatically > disabled in Safari to prevent layout shifts. ### Controlled When controlling the NumberInput component, it's recommended to use string values instead of converting to numbers. This is especially important when using `formatOptions` for currency or locale-specific formatting. ```tsx const [value, setValue] = useState('0') setValue(details.value)}> {/* ... */} ``` Converting values to numbers can cause issues with locale-specific formatting, particularly for currencies that use different decimal and thousands separators (e.g., `1.523,30` vs `1,523.30`). By keeping values as strings, you preserve the correct formatting and avoid parsing issues. If you need to submit a numeric value in your form, use a hidden input that reads `valueAsNumber` from `NumberInput.Context`: ```tsx setValue(details.value)}> {(context) => } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowMouseWheel` | `boolean` | No | Whether to allow mouse wheel to change the value | | `allowOverflow` | `boolean` | No | Whether to allow the value overflow the min/max range | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `clampValueOnBlur` | `boolean` | No | Whether to clamp the value when the input loses focus (blur) | | `defaultValue` | `string` | No | The initial value of the input when rendered. Use when you don't need to control the value of the input. | | `disabled` | `boolean` | No | Whether the number input is disabled. | | `focusInputOnChange` | `boolean` | No | Whether to focus input when the value changes | | `form` | `string` | No | The associate form of the input element. | | `formatOptions` | `NumberFormatOptions` | No | The options to pass to the `Intl.NumberFormat` constructor | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string input: string incrementTrigger: string decrementTrigger: string scrubber: string }>` | No | The ids of the elements in the number input. Useful for composition. | | `inputMode` | `InputMode` | No | Hints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices | | `invalid` | `boolean` | No | Whether the number input value is invalid. | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `max` | `number` | No | The maximum value of the number input | | `min` | `number` | No | The minimum value of the number input | | `name` | `string` | No | The name attribute of the number input. Useful for form submission. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the number input is focused | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value changes | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function invoked when the value overflows or underflows the min/max range | | `pattern` | `string` | No | The pattern used to check the element's value against | | `readOnly` | `boolean` | No | Whether the number input is readonly | | `required` | `boolean` | No | Whether the number input is required | | `spinOnPress` | `boolean` | No | Whether to spin the value when the increment/decrement button is pressed | | `step` | `number` | No | The amount to increment or decrement the value by | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `string` | No | The controlled value of the input | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | control | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **DecrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DecrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | decrement-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **IncrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IncrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | increment-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-scrubbing]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseNumberInputReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | scrubber | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | | `[data-scrubbing]` | | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowMouseWheel` | `boolean` | No | Whether to allow mouse wheel to change the value | | `allowOverflow` | `boolean` | No | Whether to allow the value overflow the min/max range | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `clampValueOnBlur` | `boolean` | No | Whether to clamp the value when the input loses focus (blur) | | `defaultValue` | `string` | No | The initial value of the input when rendered. Use when you don't need to control the value of the input. | | `disabled` | `boolean` | No | Whether the number input is disabled. | | `focusInputOnChange` | `boolean` | No | Whether to focus input when the value changes | | `form` | `string` | No | The associate form of the input element. | | `formatOptions` | `NumberFormatOptions` | No | The options to pass to the `Intl.NumberFormat` constructor | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string input: string incrementTrigger: string decrementTrigger: string scrubber: string }>` | No | The ids of the elements in the number input. Useful for composition. | | `inputMode` | `InputMode` | No | Hints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices | | `invalid` | `boolean` | No | Whether the number input value is invalid. | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `max` | `number` | No | The maximum value of the number input | | `min` | `number` | No | The minimum value of the number input | | `name` | `string` | No | The name attribute of the number input. Useful for form submission. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the number input is focused | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value changes | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function invoked when the value overflows or underflows the min/max range | | `pattern` | `string` | No | The pattern used to check the element's value against | | `readOnly` | `boolean` | No | Whether the number input is readonly | | `required` | `boolean` | No | Whether the number input is required | | `spinOnPress` | `boolean` | No | Whether to spin the value when the increment/decrement button is pressed | | `step` | `number` | No | The amount to increment or decrement the value by | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `string` | No | The controlled value of the input | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | control | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **DecrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DecrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | decrement-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **IncrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IncrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | increment-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-scrubbing]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseNumberInputReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | scrubber | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | | `[data-scrubbing]` | | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowMouseWheel` | `boolean` | No | Whether to allow mouse wheel to change the value | | `allowOverflow` | `boolean` | No | Whether to allow the value overflow the min/max range | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `clampValueOnBlur` | `boolean` | No | Whether to clamp the value when the input loses focus (blur) | | `defaultValue` | `string` | No | The initial value of the input when rendered. Use when you don't need to control the value of the input. | | `disabled` | `boolean` | No | Whether the number input is disabled. | | `focusInputOnChange` | `boolean` | No | Whether to focus input when the value changes | | `form` | `string` | No | The associate form of the input element. | | `formatOptions` | `NumberFormatOptions` | No | The options to pass to the `Intl.NumberFormat` constructor | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string input: string incrementTrigger: string decrementTrigger: string scrubber: string }>` | No | The ids of the elements in the number input. Useful for composition. | | `inputMode` | `'text' | 'tel' | 'numeric' | 'decimal'` | No | Hints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices | | `invalid` | `boolean` | No | Whether the number input value is invalid. | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `max` | `number` | No | The maximum value of the number input | | `min` | `number` | No | The minimum value of the number input | | `modelValue` | `string` | No | The v-model value of the number input | | `name` | `string` | No | The name attribute of the number input. Useful for form submission. | | `pattern` | `string` | No | The pattern used to check the element's value against | | `readOnly` | `boolean` | No | Whether the number input is readonly | | `required` | `boolean` | No | Whether the number input is required | | `spinOnPress` | `boolean` | No | Whether to spin the value when the increment/decrement button is pressed | | `step` | `number` | No | The amount to increment or decrement the value by | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | control | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **DecrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DecrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | decrement-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **IncrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IncrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | increment-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-scrubbing]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `NumberInputApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | scrubber | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | | `[data-scrubbing]` | | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowMouseWheel` | `boolean` | No | Whether to allow mouse wheel to change the value | | `allowOverflow` | `boolean` | No | Whether to allow the value overflow the min/max range | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `clampValueOnBlur` | `boolean` | No | Whether to clamp the value when the input loses focus (blur) | | `defaultValue` | `string` | No | The initial value of the input when rendered. Use when you don't need to control the value of the input. | | `disabled` | `boolean` | No | Whether the number input is disabled. | | `focusInputOnChange` | `boolean` | No | Whether to focus input when the value changes | | `form` | `string` | No | The associate form of the input element. | | `formatOptions` | `NumberFormatOptions` | No | The options to pass to the `Intl.NumberFormat` constructor | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string input: string incrementTrigger: string decrementTrigger: string scrubber: string }>` | No | The ids of the elements in the number input. Useful for composition. | | `inputMode` | `InputMode` | No | Hints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices | | `invalid` | `boolean` | No | Whether the number input value is invalid. | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `max` | `number` | No | The maximum value of the number input | | `min` | `number` | No | The minimum value of the number input | | `name` | `string` | No | The name attribute of the number input. Useful for form submission. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the number input is focused | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value changes | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function invoked when the value overflows or underflows the min/max range | | `pattern` | `string` | No | The pattern used to check the element's value against | | `readOnly` | `boolean` | No | Whether the number input is readonly | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the number input is required | | `spinOnPress` | `boolean` | No | Whether to spin the value when the increment/decrement button is pressed | | `step` | `number` | No | The amount to increment or decrement the value by | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `string` | No | The controlled value of the input | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseNumberInputContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | control | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **DecrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **DecrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | decrement-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **IncrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **IncrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | increment-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-scrubbing]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseNumberInputReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Scrubber Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Scrubber Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | scrubber | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | | `[data-scrubbing]` | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focused` | `boolean` | Whether the input is focused. | | `invalid` | `boolean` | Whether the input is invalid. | | `empty` | `boolean` | Whether the input value is empty. | | `value` | `string` | The formatted value of the input. | | `valueAsNumber` | `number` | The value of the input as a number. | | `setValue` | `(value: number) => void` | Function to set the value of the input. | | `clearValue` | `VoidFunction` | Function to clear the value of the input. | | `increment` | `VoidFunction` | Function to increment the value of the input by the step. | | `decrement` | `VoidFunction` | Function to decrement the value of the input by the step. | | `setToMax` | `VoidFunction` | Function to set the value of the input to the max. | | `setToMin` | `VoidFunction` | Function to set the value of the input to the min. | | `focus` | `VoidFunction` | Function to focus the input. | ## Accessibility Complies with the [Spinbutton WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/). ### Keyboard Support **`ArrowUp`** Description: Increments the value of the number input by a predefined step. **`ArrowDown`** Description: Decrements the value of the number input by a predefined step. **`PageUp`** Description: Increments the value of the number input by a larger predefined step. **`PageDown`** Description: Decrements the value of the number input by a larger predefined step. **`Home`** Description: Sets the value of the number input to its minimum allowed value. **`End`** Description: Sets the value of the number input to its maximum allowed value. **`Enter`** Description: Submits the value entered in the number input. --- # Number Input (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const Basic = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const Basic = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### 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. **Example: min-max** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const MinMax = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const MinMax = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` > To allow values outside the min/max range, set `clampValueOnBlur` to `false`. ### 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`. **Example: fraction-digits** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const FractionDigits = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const FractionDigits = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### 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. **Example: scrubber** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon, ArrowLeftRightIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const Scrubber = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ArrowLeftRightIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const Scrubber = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### 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`. **Example: mouse-wheel** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const MouseWheel = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const MouseWheel = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### Formatting To apply custom formatting to the input's value, set the `formatOptions` and provide `Intl.NumberFormatOptions` such as `style` and `currency`. **Example: formatting** #### React ```tsx import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const Formatting = () => ( Label
                    ) ``` #### Solid ```tsx import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const Formatting = () => ( Label
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { NumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/number-input.module.css' export const WithField = () => ( Label
                    Additional Info Error Info
                    ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { NumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import field from 'styles/field.module.css' import styles from 'styles/number-input.module.css' export const WithField = () => ( Label
                    Additional Info Error Info
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label
                    Additional Info Error Info
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { NumberInput, useNumberInput } from '@ark-ui/react/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react' import styles from 'styles/number-input.module.css' export const RootProvider = () => { const numberInput = useNumberInput() return (
                    valueAsNumber: {numberInput.valueAsNumber} Label
                    ) } ``` #### Solid ```tsx import { NumberInput, useNumberInput } from '@ark-ui/solid/number-input' import { ChevronDownIcon, ChevronUpIcon } from 'lucide-solid' import styles from 'styles/number-input.module.css' export const RootProvider = () => { const numberInput = useNumberInput() return (
                    valueAsNumber: {numberInput().valueAsNumber} Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    valueAsNumber: {numberInput().valueAsNumber} Label
                    ``` ## Guides ### Scrubber The `NumberInput.Scrubber` component provides an interactive scrub area that allows users to drag to change the input value. It renders as a `
                    ` element and displays a custom cursor element during scrubbing interactions. This component utilizes the [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API) for smooth dragging interactions. > **Note:** Browsers may show a notification when the Pointer Lock API is activated. The scrubber is automatically > disabled in Safari to prevent layout shifts. ### Controlled When controlling the NumberInput component, it's recommended to use string values instead of converting to numbers. This is especially important when using `formatOptions` for currency or locale-specific formatting. ```tsx const [value, setValue] = useState('0') setValue(details.value)}> {/* ... */} ``` Converting values to numbers can cause issues with locale-specific formatting, particularly for currencies that use different decimal and thousands separators (e.g., `1.523,30` vs `1,523.30`). By keeping values as strings, you preserve the correct formatting and avoid parsing issues. If you need to submit a numeric value in your form, use a hidden input that reads `valueAsNumber` from `NumberInput.Context`: ```tsx setValue(details.value)}> {(context) => } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowMouseWheel` | `boolean` | No | Whether to allow mouse wheel to change the value | | `allowOverflow` | `boolean` | No | Whether to allow the value overflow the min/max range | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `clampValueOnBlur` | `boolean` | No | Whether to clamp the value when the input loses focus (blur) | | `defaultValue` | `string` | No | The initial value of the input when rendered. Use when you don't need to control the value of the input. | | `disabled` | `boolean` | No | Whether the number input is disabled. | | `focusInputOnChange` | `boolean` | No | Whether to focus input when the value changes | | `form` | `string` | No | The associate form of the input element. | | `formatOptions` | `NumberFormatOptions` | No | The options to pass to the `Intl.NumberFormat` constructor | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string input: string incrementTrigger: string decrementTrigger: string scrubber: string }>` | No | The ids of the elements in the number input. Useful for composition. | | `inputMode` | `InputMode` | No | Hints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices | | `invalid` | `boolean` | No | Whether the number input value is invalid. | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `max` | `number` | No | The maximum value of the number input | | `min` | `number` | No | The minimum value of the number input | | `name` | `string` | No | The name attribute of the number input. Useful for form submission. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the number input is focused | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value changes | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function invoked when the value overflows or underflows the min/max range | | `pattern` | `string` | No | The pattern used to check the element's value against | | `readOnly` | `boolean` | No | Whether the number input is readonly | | `required` | `boolean` | No | Whether the number input is required | | `spinOnPress` | `boolean` | No | Whether to spin the value when the increment/decrement button is pressed | | `step` | `number` | No | The amount to increment or decrement the value by | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `string` | No | The controlled value of the input | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | control | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **DecrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DecrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | decrement-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **IncrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IncrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | increment-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-scrubbing]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseNumberInputReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | scrubber | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | | `[data-scrubbing]` | | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowMouseWheel` | `boolean` | No | Whether to allow mouse wheel to change the value | | `allowOverflow` | `boolean` | No | Whether to allow the value overflow the min/max range | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `clampValueOnBlur` | `boolean` | No | Whether to clamp the value when the input loses focus (blur) | | `defaultValue` | `string` | No | The initial value of the input when rendered. Use when you don't need to control the value of the input. | | `disabled` | `boolean` | No | Whether the number input is disabled. | | `focusInputOnChange` | `boolean` | No | Whether to focus input when the value changes | | `form` | `string` | No | The associate form of the input element. | | `formatOptions` | `NumberFormatOptions` | No | The options to pass to the `Intl.NumberFormat` constructor | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string input: string incrementTrigger: string decrementTrigger: string scrubber: string }>` | No | The ids of the elements in the number input. Useful for composition. | | `inputMode` | `InputMode` | No | Hints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices | | `invalid` | `boolean` | No | Whether the number input value is invalid. | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `max` | `number` | No | The maximum value of the number input | | `min` | `number` | No | The minimum value of the number input | | `name` | `string` | No | The name attribute of the number input. Useful for form submission. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the number input is focused | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value changes | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function invoked when the value overflows or underflows the min/max range | | `pattern` | `string` | No | The pattern used to check the element's value against | | `readOnly` | `boolean` | No | Whether the number input is readonly | | `required` | `boolean` | No | Whether the number input is required | | `spinOnPress` | `boolean` | No | Whether to spin the value when the increment/decrement button is pressed | | `step` | `number` | No | The amount to increment or decrement the value by | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `string` | No | The controlled value of the input | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | control | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **DecrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DecrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | decrement-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **IncrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IncrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | increment-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-scrubbing]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseNumberInputReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | scrubber | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | | `[data-scrubbing]` | | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowMouseWheel` | `boolean` | No | Whether to allow mouse wheel to change the value | | `allowOverflow` | `boolean` | No | Whether to allow the value overflow the min/max range | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `clampValueOnBlur` | `boolean` | No | Whether to clamp the value when the input loses focus (blur) | | `defaultValue` | `string` | No | The initial value of the input when rendered. Use when you don't need to control the value of the input. | | `disabled` | `boolean` | No | Whether the number input is disabled. | | `focusInputOnChange` | `boolean` | No | Whether to focus input when the value changes | | `form` | `string` | No | The associate form of the input element. | | `formatOptions` | `NumberFormatOptions` | No | The options to pass to the `Intl.NumberFormat` constructor | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string input: string incrementTrigger: string decrementTrigger: string scrubber: string }>` | No | The ids of the elements in the number input. Useful for composition. | | `inputMode` | `'text' | 'tel' | 'numeric' | 'decimal'` | No | Hints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices | | `invalid` | `boolean` | No | Whether the number input value is invalid. | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `max` | `number` | No | The maximum value of the number input | | `min` | `number` | No | The minimum value of the number input | | `modelValue` | `string` | No | The v-model value of the number input | | `name` | `string` | No | The name attribute of the number input. Useful for form submission. | | `pattern` | `string` | No | The pattern used to check the element's value against | | `readOnly` | `boolean` | No | Whether the number input is readonly | | `required` | `boolean` | No | Whether the number input is required | | `spinOnPress` | `boolean` | No | Whether to spin the value when the increment/decrement button is pressed | | `step` | `number` | No | The amount to increment or decrement the value by | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | control | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **DecrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DecrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | decrement-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **IncrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **IncrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | increment-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-scrubbing]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `NumberInputApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrubber Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | scrubber | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | | `[data-scrubbing]` | | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowMouseWheel` | `boolean` | No | Whether to allow mouse wheel to change the value | | `allowOverflow` | `boolean` | No | Whether to allow the value overflow the min/max range | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `clampValueOnBlur` | `boolean` | No | Whether to clamp the value when the input loses focus (blur) | | `defaultValue` | `string` | No | The initial value of the input when rendered. Use when you don't need to control the value of the input. | | `disabled` | `boolean` | No | Whether the number input is disabled. | | `focusInputOnChange` | `boolean` | No | Whether to focus input when the value changes | | `form` | `string` | No | The associate form of the input element. | | `formatOptions` | `NumberFormatOptions` | No | The options to pass to the `Intl.NumberFormat` constructor | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string input: string incrementTrigger: string decrementTrigger: string scrubber: string }>` | No | The ids of the elements in the number input. Useful for composition. | | `inputMode` | `InputMode` | No | Hints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices | | `invalid` | `boolean` | No | Whether the number input value is invalid. | | `locale` | `string` | No | The current locale. Based on the BCP 47 definition. | | `max` | `number` | No | The maximum value of the number input | | `min` | `number` | No | The minimum value of the number input | | `name` | `string` | No | The name attribute of the number input. Useful for form submission. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the number input is focused | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value changes | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function invoked when the value overflows or underflows the min/max range | | `pattern` | `string` | No | The pattern used to check the element's value against | | `readOnly` | `boolean` | No | Whether the number input is readonly | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the number input is required | | `spinOnPress` | `boolean` | No | Whether to spin the value when the increment/decrement button is pressed | | `step` | `number` | No | The amount to increment or decrement the value by | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `string` | No | The controlled value of the input | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseNumberInputContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | control | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-scrubbing]` | | **DecrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **DecrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | decrement-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **IncrementTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **IncrementTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | increment-trigger | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | | `[data-scrubbing]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseNumberInputReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Scrubber Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Scrubber Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | scrubber | | `[data-disabled]` | Present when disabled | | `[data-scrubbing]` | | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | number-input | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | | `[data-scrubbing]` | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focused` | `boolean` | Whether the input is focused. | | `invalid` | `boolean` | Whether the input is invalid. | | `empty` | `boolean` | Whether the input value is empty. | | `value` | `string` | The formatted value of the input. | | `valueAsNumber` | `number` | The value of the input as a number. | | `setValue` | `(value: number) => void` | Function to set the value of the input. | | `clearValue` | `VoidFunction` | Function to clear the value of the input. | | `increment` | `VoidFunction` | Function to increment the value of the input by the step. | | `decrement` | `VoidFunction` | Function to decrement the value of the input by the step. | | `setToMax` | `VoidFunction` | Function to set the value of the input to the max. | | `setToMin` | `VoidFunction` | Function to set the value of the input to the min. | | `focus` | `VoidFunction` | Function to focus the input. | ## Accessibility Complies with the [Spinbutton WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/). ### Keyboard Support **`ArrowUp`** Description: Increments the value of the number input by a predefined step. **`ArrowDown`** Description: Decrements the value of the number input by a predefined step. **`PageUp`** Description: Increments the value of the number input by a larger predefined step. **`PageDown`** Description: Decrements the value of the number input by a larger predefined step. **`Home`** Description: Sets the value of the number input to its minimum allowed value. **`End`** Description: Sets the value of the number input to its maximum allowed value. **`Enter`** Description: Submits the value entered in the number input. --- # Pagination (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Basic = () => (
                    {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) }
                    ) ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const Basic = () => (
                    {(pagination) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )}
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet render(pagination)} {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} {/snippet}
                    ``` ### 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: **Example: controlled** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { useState } from 'react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Controlled = () => { const [currentPage, setCurrentPage] = useState(1) return ( setCurrentPage(details.page)} className={styles.Root} >
                    {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) }
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For, createSignal } from 'solid-js' import styles from 'styles/pagination.module.css' export const Controlled = () => { const [currentPage, setCurrentPage] = createSignal(1) return ( setCurrentPage(details.page)} class={styles.Root} >
                    {(pagination) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet render(pagination)} {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} {/snippet}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination, usePagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const RootProvider = () => { const pagination = usePagination({ count: 5000, pageSize: 10, siblingCount: 2 }) return (
                    {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) }
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination, usePagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const RootProvider = () => { const pagination = usePagination({ count: 5000, pageSize: 10, siblingCount: 2 }) return (
                    {(pagination) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}
                    ``` ### 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: **Example: customized** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Customized = () => ( `Page ${details.page}`, }} className={styles.Root} >
                    {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) }
                    ) ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const Customized = () => { return ( `Page ${details.page}`, }} class={styles.Root} >
                    {(pagination) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte `Page ${details.page}`, }} class={styles.Root} >
                    {#snippet render(pagination)} {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} {/snippet}
                    ``` ### Context The `Context` component provides access to the pagination state and methods through a render prop pattern. This allows you to access methods like `setPage`, `setPageSize`, `goToNextPage`, `goToPrevPage`, `goToFirstPage`, `goToLastPage`, as well as properties like `totalPages` and `pageRange`. **Example: context** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon, ChevronsLeftIcon, ChevronsRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Context = () => { return ( {(pagination) => (

                    Page {pagination.page} of {pagination.totalPages}

                    )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon, ChevronsLeftIcon, ChevronsRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import styles from 'styles/pagination.module.css' export const Context = () => { return ( {(pagination) => (

                    Page {pagination().page} of {pagination().totalPages}

                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}

                    Page {pagination().page} of {pagination().totalPages}

                    {/snippet}
                    ``` ### 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. **Example: data-slicing** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' const users = [ { id: 1, name: 'Emma Wilson', email: 'emma@example.com' }, { id: 2, name: 'Liam Johnson', email: 'liam@example.com' }, { id: 3, name: 'Olivia Brown', email: 'olivia@example.com' }, { id: 4, name: 'Noah Davis', email: 'noah@example.com' }, { id: 5, name: 'Ava Martinez', email: 'ava@example.com' }, { id: 6, name: 'Ethan Garcia', email: 'ethan@example.com' }, { id: 7, name: 'Sophia Rodriguez', email: 'sophia@example.com' }, { id: 8, name: 'Mason Lee', email: 'mason@example.com' }, { id: 9, name: 'Isabella Walker', email: 'isabella@example.com' }, { id: 10, name: 'James Hall', email: 'james@example.com' }, { id: 11, name: 'Mia Allen', email: 'mia@example.com' }, { id: 12, name: 'Benjamin Young', email: 'benjamin@example.com' }, { id: 13, name: 'Charlotte King', email: 'charlotte@example.com' }, { id: 14, name: 'William Wright', email: 'william@example.com' }, { id: 15, name: 'Amelia Scott', email: 'amelia@example.com' }, { id: 16, name: 'Henry Green', email: 'henry@example.com' }, { id: 17, name: 'Harper Adams', email: 'harper@example.com' }, { id: 18, name: 'Sebastian Baker', email: 'sebastian@example.com' }, { id: 19, name: 'Evelyn Nelson', email: 'evelyn@example.com' }, { id: 20, name: 'Jack Carter', email: 'jack@example.com' }, ] export const DataSlicing = () => { return ( {(pagination) => ( <>
                    {pagination.slice(users).map((user) => (
                    {user.name} {user.email}
                    ))}
                    {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )}
                    )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' const users = [ { id: 1, name: 'Emma Wilson', email: 'emma@example.com' }, { id: 2, name: 'Liam Johnson', email: 'liam@example.com' }, { id: 3, name: 'Olivia Brown', email: 'olivia@example.com' }, { id: 4, name: 'Noah Davis', email: 'noah@example.com' }, { id: 5, name: 'Ava Martinez', email: 'ava@example.com' }, { id: 6, name: 'Ethan Garcia', email: 'ethan@example.com' }, { id: 7, name: 'Sophia Rodriguez', email: 'sophia@example.com' }, { id: 8, name: 'Mason Lee', email: 'mason@example.com' }, { id: 9, name: 'Isabella Walker', email: 'isabella@example.com' }, { id: 10, name: 'James Hall', email: 'james@example.com' }, { id: 11, name: 'Mia Allen', email: 'mia@example.com' }, { id: 12, name: 'Benjamin Young', email: 'benjamin@example.com' }, { id: 13, name: 'Charlotte King', email: 'charlotte@example.com' }, { id: 14, name: 'William Wright', email: 'william@example.com' }, { id: 15, name: 'Amelia Scott', email: 'amelia@example.com' }, { id: 16, name: 'Henry Green', email: 'henry@example.com' }, { id: 17, name: 'Harper Adams', email: 'harper@example.com' }, { id: 18, name: 'Sebastian Baker', email: 'sebastian@example.com' }, { id: 19, name: 'Evelyn Nelson', email: 'evelyn@example.com' }, { id: 20, name: 'Jack Carter', email: 'jack@example.com' }, ] export const DataSlicing = () => { return ( {(pagination) => ( <>
                    {(user) => (
                    {user.name} {user.email}
                    )}
                    {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) }
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}
                    {#each pagination().slice(users) as user (user.id)}
                    {user.name} {user.email}
                    {/each}
                    {#each pagination().pages as page, index} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}
                    {/snippet}
                    ``` ### 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"). **Example: page-range** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const PageRange = () => { return ( {(pagination) => ( <>
                    {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )}

                    Showing {pagination.pageRange.start + 1}-{pagination.pageRange.end} of {pagination.count} results

                    Page {pagination.page} of {pagination.totalPages}

                    )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const PageRange = () => { return ( {(pagination) => ( <>
                    {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) }

                    Showing {pagination().pageRange.start + 1}-{pagination().pageRange.end} of {pagination().count} results

                    Page {pagination().page} of {pagination().totalPages}

                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}
                    {#each pagination().pages as page, index} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}

                    Showing {pagination().pageRange.start + 1}-{pagination().pageRange.end} of {pagination().count} results

                    Page {pagination().page} of {pagination().totalPages}

                    {/snippet}
                    ``` ### 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. **Example: page-size-control** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const PageSizeControl = () => { return ( {(pagination) => ( <>
                    {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )}

                    Page {pagination.page} of {pagination.totalPages}

                    )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const PageSizeControl = () => { return ( {(pagination) => ( <>
                    {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) }

                    Page {pagination().page} of {pagination().totalPages}

                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}
                    {#each pagination().pages as page, index} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}

                    Page {pagination().page} of {pagination().totalPages}

                    {/snippet}
                    ``` ### 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. **Example: link** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination, usePagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Link = () => { const pagination = usePagination({ type: 'link', count: 100, pageSize: 10, siblingCount: 2, getPageUrl: ({ page }) => `/page=${page}`, }) return (
                    {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination, usePagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const Link = () => { const pagination = usePagination({ type: 'link', count: 100, pageSize: 10, siblingCount: 2, getPageUrl: ({ page }) => `/page=${page}`, }) return (
                    {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | Total number of data items | | `defaultPage` | `number` | No | The initial active page when rendered. Use when you don't need to control the active page of the pagination. | | `defaultPageSize` | `number` | No | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. | | `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links. Only used when `type` is set to "link". | | `ids` | `Partial<{ root: string ellipsis: (index: number) => string prevTrigger: string nextTrigger: string item: (page: number) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Called when the page number is changed | | `onPageSizeChange` | `(details: PageSizeChangeDetails) => void` | No | Called when the page size is changed | | `page` | `number` | No | The controlled active page | | `pageSize` | `number` | No | The controlled number of data items per page | | `siblingCount` | `number` | No | Number of pages to show beside active page | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'button' | 'link'` | No | The type of the trigger element | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePaginationReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'nav'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | Total number of data items | | `defaultPage` | `number` | No | The initial active page when rendered. Use when you don't need to control the active page of the pagination. | | `defaultPageSize` | `number` | No | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. | | `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links. Only used when `type` is set to "link". | | `ids` | `Partial<{ root: string ellipsis: (index: number) => string prevTrigger: string nextTrigger: string item: (page: number) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Called when the page number is changed | | `onPageSizeChange` | `(details: PageSizeChangeDetails) => void` | No | Called when the page size is changed | | `page` | `number` | No | The controlled active page | | `pageSize` | `number` | No | The controlled number of data items per page | | `siblingCount` | `number` | No | Number of pages to show beside active page | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'link' | 'button'` | No | The type of the trigger element | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePaginationReturn` | Yes | | | `asChild` | `(props: ParentProps<'nav'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | Total number of data items | | `defaultPage` | `number` | No | The initial active page when rendered. Use when you don't need to control the active page of the pagination. | | `defaultPageSize` | `number` | No | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. | | `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links. Only used when `type` is set to "link". | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string ellipsis(index: number): string prevTrigger: string nextTrigger: string item(page: number): string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `page` | `number` | No | The controlled active page | | `pageSize` | `number` | No | The controlled number of data items per page | | `siblingCount` | `number` | No | Number of pages to show beside active page | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'button' | 'link'` | No | The type of the trigger element | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PaginationApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'nav'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | Total number of data items | | `defaultPage` | `number` | No | The initial active page when rendered. Use when you don't need to control the active page of the pagination. | | `defaultPageSize` | `number` | No | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. | | `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links. Only used when `type` is set to "link". | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string ellipsis: (index: number) => string prevTrigger: string nextTrigger: string item: (page: number) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Called when the page number is changed | | `onPageSizeChange` | `(details: PageSizeChangeDetails) => void` | No | Called when the page size is changed | | `page` | `number` | No | The controlled active page | | `pageSize` | `number` | No | The controlled number of data items per page | | `ref` | `Element` | No | | | `siblingCount` | `number` | No | Number of pages to show beside active page | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'button' | 'link'` | No | The type of the trigger element | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePaginationContext]>` | Yes | | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePaginationReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'nav'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `page` | `number` | The current page. | | `count` | `number` | The total number of data items. | | `pageSize` | `number` | The number of data items per page. | | `totalPages` | `number` | The total number of pages. | | `pages` | `Pages` | The page range. Represented as an array of page numbers (including ellipsis) | | `previousPage` | `number` | The previous page. | | `nextPage` | `number` | The next page. | | `pageRange` | `PageRange` | The page range. Represented as an object with `start` and `end` properties. | | `slice` | `(data: V[]) => V[]` | Function to slice an array of data based on the current page. | | `setPageSize` | `(size: number) => void` | Function to set the page size. | | `setPage` | `(page: number) => void` | Function to set the current page. | | `goToNextPage` | `VoidFunction` | Function to go to the next page. | | `goToPrevPage` | `VoidFunction` | Function to go to the previous page. | | `goToFirstPage` | `VoidFunction` | Function to go to the first page. | | `goToLastPage` | `VoidFunction` | Function to go to the last page. | --- # Pagination (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Basic = () => (
                    {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) }
                    ) ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const Basic = () => (
                    {(pagination) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )}
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet render(pagination)} {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} {/snippet}
                    ``` ### 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: **Example: controlled** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { useState } from 'react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Controlled = () => { const [currentPage, setCurrentPage] = useState(1) return ( setCurrentPage(details.page)} className={styles.Root} >
                    {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) }
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For, createSignal } from 'solid-js' import styles from 'styles/pagination.module.css' export const Controlled = () => { const [currentPage, setCurrentPage] = createSignal(1) return ( setCurrentPage(details.page)} class={styles.Root} >
                    {(pagination) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet render(pagination)} {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} {/snippet}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination, usePagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const RootProvider = () => { const pagination = usePagination({ count: 5000, pageSize: 10, siblingCount: 2 }) return (
                    {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) }
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination, usePagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const RootProvider = () => { const pagination = usePagination({ count: 5000, pageSize: 10, siblingCount: 2 }) return (
                    {(pagination) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}
                    ``` ### 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: **Example: customized** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Customized = () => ( `Page ${details.page}`, }} className={styles.Root} >
                    {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) }
                    ) ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const Customized = () => { return ( `Page ${details.page}`, }} class={styles.Root} >
                    {(pagination) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte `Page ${details.page}`, }} class={styles.Root} >
                    {#snippet render(pagination)} {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} {/snippet}
                    ``` ### Context The `Context` component provides access to the pagination state and methods through a render prop pattern. This allows you to access methods like `setPage`, `setPageSize`, `goToNextPage`, `goToPrevPage`, `goToFirstPage`, `goToLastPage`, as well as properties like `totalPages` and `pageRange`. **Example: context** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon, ChevronsLeftIcon, ChevronsRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Context = () => { return ( {(pagination) => (

                    Page {pagination.page} of {pagination.totalPages}

                    )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon, ChevronsLeftIcon, ChevronsRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import styles from 'styles/pagination.module.css' export const Context = () => { return ( {(pagination) => (

                    Page {pagination().page} of {pagination().totalPages}

                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}

                    Page {pagination().page} of {pagination().totalPages}

                    {/snippet}
                    ``` ### 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. **Example: data-slicing** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' const users = [ { id: 1, name: 'Emma Wilson', email: 'emma@example.com' }, { id: 2, name: 'Liam Johnson', email: 'liam@example.com' }, { id: 3, name: 'Olivia Brown', email: 'olivia@example.com' }, { id: 4, name: 'Noah Davis', email: 'noah@example.com' }, { id: 5, name: 'Ava Martinez', email: 'ava@example.com' }, { id: 6, name: 'Ethan Garcia', email: 'ethan@example.com' }, { id: 7, name: 'Sophia Rodriguez', email: 'sophia@example.com' }, { id: 8, name: 'Mason Lee', email: 'mason@example.com' }, { id: 9, name: 'Isabella Walker', email: 'isabella@example.com' }, { id: 10, name: 'James Hall', email: 'james@example.com' }, { id: 11, name: 'Mia Allen', email: 'mia@example.com' }, { id: 12, name: 'Benjamin Young', email: 'benjamin@example.com' }, { id: 13, name: 'Charlotte King', email: 'charlotte@example.com' }, { id: 14, name: 'William Wright', email: 'william@example.com' }, { id: 15, name: 'Amelia Scott', email: 'amelia@example.com' }, { id: 16, name: 'Henry Green', email: 'henry@example.com' }, { id: 17, name: 'Harper Adams', email: 'harper@example.com' }, { id: 18, name: 'Sebastian Baker', email: 'sebastian@example.com' }, { id: 19, name: 'Evelyn Nelson', email: 'evelyn@example.com' }, { id: 20, name: 'Jack Carter', email: 'jack@example.com' }, ] export const DataSlicing = () => { return ( {(pagination) => ( <>
                    {pagination.slice(users).map((user) => (
                    {user.name} {user.email}
                    ))}
                    {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )}
                    )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' const users = [ { id: 1, name: 'Emma Wilson', email: 'emma@example.com' }, { id: 2, name: 'Liam Johnson', email: 'liam@example.com' }, { id: 3, name: 'Olivia Brown', email: 'olivia@example.com' }, { id: 4, name: 'Noah Davis', email: 'noah@example.com' }, { id: 5, name: 'Ava Martinez', email: 'ava@example.com' }, { id: 6, name: 'Ethan Garcia', email: 'ethan@example.com' }, { id: 7, name: 'Sophia Rodriguez', email: 'sophia@example.com' }, { id: 8, name: 'Mason Lee', email: 'mason@example.com' }, { id: 9, name: 'Isabella Walker', email: 'isabella@example.com' }, { id: 10, name: 'James Hall', email: 'james@example.com' }, { id: 11, name: 'Mia Allen', email: 'mia@example.com' }, { id: 12, name: 'Benjamin Young', email: 'benjamin@example.com' }, { id: 13, name: 'Charlotte King', email: 'charlotte@example.com' }, { id: 14, name: 'William Wright', email: 'william@example.com' }, { id: 15, name: 'Amelia Scott', email: 'amelia@example.com' }, { id: 16, name: 'Henry Green', email: 'henry@example.com' }, { id: 17, name: 'Harper Adams', email: 'harper@example.com' }, { id: 18, name: 'Sebastian Baker', email: 'sebastian@example.com' }, { id: 19, name: 'Evelyn Nelson', email: 'evelyn@example.com' }, { id: 20, name: 'Jack Carter', email: 'jack@example.com' }, ] export const DataSlicing = () => { return ( {(pagination) => ( <>
                    {(user) => (
                    {user.name} {user.email}
                    )}
                    {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) }
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}
                    {#each pagination().slice(users) as user (user.id)}
                    {user.name} {user.email}
                    {/each}
                    {#each pagination().pages as page, index} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}
                    {/snippet}
                    ``` ### 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"). **Example: page-range** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const PageRange = () => { return ( {(pagination) => ( <>
                    {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )}

                    Showing {pagination.pageRange.start + 1}-{pagination.pageRange.end} of {pagination.count} results

                    Page {pagination.page} of {pagination.totalPages}

                    )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const PageRange = () => { return ( {(pagination) => ( <>
                    {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) }

                    Showing {pagination().pageRange.start + 1}-{pagination().pageRange.end} of {pagination().count} results

                    Page {pagination().page} of {pagination().totalPages}

                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}
                    {#each pagination().pages as page, index} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}

                    Showing {pagination().pageRange.start + 1}-{pagination().pageRange.end} of {pagination().count} results

                    Page {pagination().page} of {pagination().totalPages}

                    {/snippet}
                    ``` ### 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. **Example: page-size-control** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const PageSizeControl = () => { return ( {(pagination) => ( <>
                    {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )}

                    Page {pagination.page} of {pagination.totalPages}

                    )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const PageSizeControl = () => { return ( {(pagination) => ( <>
                    {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) }

                    Page {pagination().page} of {pagination().totalPages}

                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}
                    {#each pagination().pages as page, index} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}

                    Page {pagination().page} of {pagination().totalPages}

                    {/snippet}
                    ``` ### 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. **Example: link** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination, usePagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Link = () => { const pagination = usePagination({ type: 'link', count: 100, pageSize: 10, siblingCount: 2, getPageUrl: ({ page }) => `/page=${page}`, }) return (
                    {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination, usePagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const Link = () => { const pagination = usePagination({ type: 'link', count: 100, pageSize: 10, siblingCount: 2, getPageUrl: ({ page }) => `/page=${page}`, }) return (
                    {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | Total number of data items | | `defaultPage` | `number` | No | The initial active page when rendered. Use when you don't need to control the active page of the pagination. | | `defaultPageSize` | `number` | No | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. | | `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links. Only used when `type` is set to "link". | | `ids` | `Partial<{ root: string ellipsis: (index: number) => string prevTrigger: string nextTrigger: string item: (page: number) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Called when the page number is changed | | `onPageSizeChange` | `(details: PageSizeChangeDetails) => void` | No | Called when the page size is changed | | `page` | `number` | No | The controlled active page | | `pageSize` | `number` | No | The controlled number of data items per page | | `siblingCount` | `number` | No | Number of pages to show beside active page | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'button' | 'link'` | No | The type of the trigger element | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePaginationReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'nav'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | Total number of data items | | `defaultPage` | `number` | No | The initial active page when rendered. Use when you don't need to control the active page of the pagination. | | `defaultPageSize` | `number` | No | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. | | `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links. Only used when `type` is set to "link". | | `ids` | `Partial<{ root: string ellipsis: (index: number) => string prevTrigger: string nextTrigger: string item: (page: number) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Called when the page number is changed | | `onPageSizeChange` | `(details: PageSizeChangeDetails) => void` | No | Called when the page size is changed | | `page` | `number` | No | The controlled active page | | `pageSize` | `number` | No | The controlled number of data items per page | | `siblingCount` | `number` | No | Number of pages to show beside active page | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'link' | 'button'` | No | The type of the trigger element | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePaginationReturn` | Yes | | | `asChild` | `(props: ParentProps<'nav'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | Total number of data items | | `defaultPage` | `number` | No | The initial active page when rendered. Use when you don't need to control the active page of the pagination. | | `defaultPageSize` | `number` | No | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. | | `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links. Only used when `type` is set to "link". | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string ellipsis(index: number): string prevTrigger: string nextTrigger: string item(page: number): string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `page` | `number` | No | The controlled active page | | `pageSize` | `number` | No | The controlled number of data items per page | | `siblingCount` | `number` | No | Number of pages to show beside active page | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'button' | 'link'` | No | The type of the trigger element | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PaginationApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'nav'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | Total number of data items | | `defaultPage` | `number` | No | The initial active page when rendered. Use when you don't need to control the active page of the pagination. | | `defaultPageSize` | `number` | No | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. | | `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links. Only used when `type` is set to "link". | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string ellipsis: (index: number) => string prevTrigger: string nextTrigger: string item: (page: number) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Called when the page number is changed | | `onPageSizeChange` | `(details: PageSizeChangeDetails) => void` | No | Called when the page size is changed | | `page` | `number` | No | The controlled active page | | `pageSize` | `number` | No | The controlled number of data items per page | | `ref` | `Element` | No | | | `siblingCount` | `number` | No | Number of pages to show beside active page | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'button' | 'link'` | No | The type of the trigger element | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePaginationContext]>` | Yes | | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePaginationReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'nav'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `page` | `number` | The current page. | | `count` | `number` | The total number of data items. | | `pageSize` | `number` | The number of data items per page. | | `totalPages` | `number` | The total number of pages. | | `pages` | `Pages` | The page range. Represented as an array of page numbers (including ellipsis) | | `previousPage` | `number` | The previous page. | | `nextPage` | `number` | The next page. | | `pageRange` | `PageRange` | The page range. Represented as an object with `start` and `end` properties. | | `slice` | `(data: V[]) => V[]` | Function to slice an array of data based on the current page. | | `setPageSize` | `(size: number) => void` | Function to set the page size. | | `setPage` | `(page: number) => void` | Function to set the current page. | | `goToNextPage` | `VoidFunction` | Function to go to the next page. | | `goToPrevPage` | `VoidFunction` | Function to go to the previous page. | | `goToFirstPage` | `VoidFunction` | Function to go to the first page. | | `goToLastPage` | `VoidFunction` | Function to go to the last page. | --- # Pagination (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Basic = () => (
                    {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) }
                    ) ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const Basic = () => (
                    {(pagination) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )}
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet render(pagination)} {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} {/snippet}
                    ``` ### 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: **Example: controlled** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { useState } from 'react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Controlled = () => { const [currentPage, setCurrentPage] = useState(1) return ( setCurrentPage(details.page)} className={styles.Root} >
                    {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) }
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For, createSignal } from 'solid-js' import styles from 'styles/pagination.module.css' export const Controlled = () => { const [currentPage, setCurrentPage] = createSignal(1) return ( setCurrentPage(details.page)} class={styles.Root} >
                    {(pagination) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet render(pagination)} {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} {/snippet}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination, usePagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const RootProvider = () => { const pagination = usePagination({ count: 5000, pageSize: 10, siblingCount: 2 }) return (
                    {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) }
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination, usePagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const RootProvider = () => { const pagination = usePagination({ count: 5000, pageSize: 10, siblingCount: 2 }) return (
                    {(pagination) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}
                    ``` ### 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: **Example: customized** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Customized = () => ( `Page ${details.page}`, }} className={styles.Root} >
                    {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) }
                    ) ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const Customized = () => { return ( `Page ${details.page}`, }} class={styles.Root} >
                    {(pagination) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte `Page ${details.page}`, }} class={styles.Root} >
                    {#snippet render(pagination)} {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} {/snippet}
                    ``` ### Context The `Context` component provides access to the pagination state and methods through a render prop pattern. This allows you to access methods like `setPage`, `setPageSize`, `goToNextPage`, `goToPrevPage`, `goToFirstPage`, `goToLastPage`, as well as properties like `totalPages` and `pageRange`. **Example: context** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon, ChevronsLeftIcon, ChevronsRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Context = () => { return ( {(pagination) => (

                    Page {pagination.page} of {pagination.totalPages}

                    )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon, ChevronsLeftIcon, ChevronsRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import styles from 'styles/pagination.module.css' export const Context = () => { return ( {(pagination) => (

                    Page {pagination().page} of {pagination().totalPages}

                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}

                    Page {pagination().page} of {pagination().totalPages}

                    {/snippet}
                    ``` ### 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. **Example: data-slicing** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' const users = [ { id: 1, name: 'Emma Wilson', email: 'emma@example.com' }, { id: 2, name: 'Liam Johnson', email: 'liam@example.com' }, { id: 3, name: 'Olivia Brown', email: 'olivia@example.com' }, { id: 4, name: 'Noah Davis', email: 'noah@example.com' }, { id: 5, name: 'Ava Martinez', email: 'ava@example.com' }, { id: 6, name: 'Ethan Garcia', email: 'ethan@example.com' }, { id: 7, name: 'Sophia Rodriguez', email: 'sophia@example.com' }, { id: 8, name: 'Mason Lee', email: 'mason@example.com' }, { id: 9, name: 'Isabella Walker', email: 'isabella@example.com' }, { id: 10, name: 'James Hall', email: 'james@example.com' }, { id: 11, name: 'Mia Allen', email: 'mia@example.com' }, { id: 12, name: 'Benjamin Young', email: 'benjamin@example.com' }, { id: 13, name: 'Charlotte King', email: 'charlotte@example.com' }, { id: 14, name: 'William Wright', email: 'william@example.com' }, { id: 15, name: 'Amelia Scott', email: 'amelia@example.com' }, { id: 16, name: 'Henry Green', email: 'henry@example.com' }, { id: 17, name: 'Harper Adams', email: 'harper@example.com' }, { id: 18, name: 'Sebastian Baker', email: 'sebastian@example.com' }, { id: 19, name: 'Evelyn Nelson', email: 'evelyn@example.com' }, { id: 20, name: 'Jack Carter', email: 'jack@example.com' }, ] export const DataSlicing = () => { return ( {(pagination) => ( <>
                    {pagination.slice(users).map((user) => (
                    {user.name} {user.email}
                    ))}
                    {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )}
                    )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' const users = [ { id: 1, name: 'Emma Wilson', email: 'emma@example.com' }, { id: 2, name: 'Liam Johnson', email: 'liam@example.com' }, { id: 3, name: 'Olivia Brown', email: 'olivia@example.com' }, { id: 4, name: 'Noah Davis', email: 'noah@example.com' }, { id: 5, name: 'Ava Martinez', email: 'ava@example.com' }, { id: 6, name: 'Ethan Garcia', email: 'ethan@example.com' }, { id: 7, name: 'Sophia Rodriguez', email: 'sophia@example.com' }, { id: 8, name: 'Mason Lee', email: 'mason@example.com' }, { id: 9, name: 'Isabella Walker', email: 'isabella@example.com' }, { id: 10, name: 'James Hall', email: 'james@example.com' }, { id: 11, name: 'Mia Allen', email: 'mia@example.com' }, { id: 12, name: 'Benjamin Young', email: 'benjamin@example.com' }, { id: 13, name: 'Charlotte King', email: 'charlotte@example.com' }, { id: 14, name: 'William Wright', email: 'william@example.com' }, { id: 15, name: 'Amelia Scott', email: 'amelia@example.com' }, { id: 16, name: 'Henry Green', email: 'henry@example.com' }, { id: 17, name: 'Harper Adams', email: 'harper@example.com' }, { id: 18, name: 'Sebastian Baker', email: 'sebastian@example.com' }, { id: 19, name: 'Evelyn Nelson', email: 'evelyn@example.com' }, { id: 20, name: 'Jack Carter', email: 'jack@example.com' }, ] export const DataSlicing = () => { return ( {(pagination) => ( <>
                    {(user) => (
                    {user.name} {user.email}
                    )}
                    {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) }
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}
                    {#each pagination().slice(users) as user (user.id)}
                    {user.name} {user.email}
                    {/each}
                    {#each pagination().pages as page, index} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}
                    {/snippet}
                    ``` ### 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"). **Example: page-range** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const PageRange = () => { return ( {(pagination) => ( <>
                    {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )}

                    Showing {pagination.pageRange.start + 1}-{pagination.pageRange.end} of {pagination.count} results

                    Page {pagination.page} of {pagination.totalPages}

                    )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const PageRange = () => { return ( {(pagination) => ( <>
                    {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) }

                    Showing {pagination().pageRange.start + 1}-{pagination().pageRange.end} of {pagination().count} results

                    Page {pagination().page} of {pagination().totalPages}

                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}
                    {#each pagination().pages as page, index} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}

                    Showing {pagination().pageRange.start + 1}-{pagination().pageRange.end} of {pagination().count} results

                    Page {pagination().page} of {pagination().totalPages}

                    {/snippet}
                    ``` ### 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. **Example: page-size-control** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const PageSizeControl = () => { return ( {(pagination) => ( <>
                    {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )}

                    Page {pagination.page} of {pagination.totalPages}

                    )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const PageSizeControl = () => { return ( {(pagination) => ( <>
                    {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) }

                    Page {pagination().page} of {pagination().totalPages}

                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}
                    {#each pagination().pages as page, index} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}

                    Page {pagination().page} of {pagination().totalPages}

                    {/snippet}
                    ``` ### 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. **Example: link** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination, usePagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Link = () => { const pagination = usePagination({ type: 'link', count: 100, pageSize: 10, siblingCount: 2, getPageUrl: ({ page }) => `/page=${page}`, }) return (
                    {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination, usePagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const Link = () => { const pagination = usePagination({ type: 'link', count: 100, pageSize: 10, siblingCount: 2, getPageUrl: ({ page }) => `/page=${page}`, }) return (
                    {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | Total number of data items | | `defaultPage` | `number` | No | The initial active page when rendered. Use when you don't need to control the active page of the pagination. | | `defaultPageSize` | `number` | No | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. | | `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links. Only used when `type` is set to "link". | | `ids` | `Partial<{ root: string ellipsis: (index: number) => string prevTrigger: string nextTrigger: string item: (page: number) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Called when the page number is changed | | `onPageSizeChange` | `(details: PageSizeChangeDetails) => void` | No | Called when the page size is changed | | `page` | `number` | No | The controlled active page | | `pageSize` | `number` | No | The controlled number of data items per page | | `siblingCount` | `number` | No | Number of pages to show beside active page | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'button' | 'link'` | No | The type of the trigger element | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePaginationReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'nav'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | Total number of data items | | `defaultPage` | `number` | No | The initial active page when rendered. Use when you don't need to control the active page of the pagination. | | `defaultPageSize` | `number` | No | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. | | `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links. Only used when `type` is set to "link". | | `ids` | `Partial<{ root: string ellipsis: (index: number) => string prevTrigger: string nextTrigger: string item: (page: number) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Called when the page number is changed | | `onPageSizeChange` | `(details: PageSizeChangeDetails) => void` | No | Called when the page size is changed | | `page` | `number` | No | The controlled active page | | `pageSize` | `number` | No | The controlled number of data items per page | | `siblingCount` | `number` | No | Number of pages to show beside active page | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'link' | 'button'` | No | The type of the trigger element | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePaginationReturn` | Yes | | | `asChild` | `(props: ParentProps<'nav'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | Total number of data items | | `defaultPage` | `number` | No | The initial active page when rendered. Use when you don't need to control the active page of the pagination. | | `defaultPageSize` | `number` | No | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. | | `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links. Only used when `type` is set to "link". | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string ellipsis(index: number): string prevTrigger: string nextTrigger: string item(page: number): string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `page` | `number` | No | The controlled active page | | `pageSize` | `number` | No | The controlled number of data items per page | | `siblingCount` | `number` | No | Number of pages to show beside active page | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'button' | 'link'` | No | The type of the trigger element | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PaginationApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'nav'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | Total number of data items | | `defaultPage` | `number` | No | The initial active page when rendered. Use when you don't need to control the active page of the pagination. | | `defaultPageSize` | `number` | No | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. | | `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links. Only used when `type` is set to "link". | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string ellipsis: (index: number) => string prevTrigger: string nextTrigger: string item: (page: number) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Called when the page number is changed | | `onPageSizeChange` | `(details: PageSizeChangeDetails) => void` | No | Called when the page size is changed | | `page` | `number` | No | The controlled active page | | `pageSize` | `number` | No | The controlled number of data items per page | | `ref` | `Element` | No | | | `siblingCount` | `number` | No | Number of pages to show beside active page | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'button' | 'link'` | No | The type of the trigger element | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePaginationContext]>` | Yes | | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePaginationReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'nav'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `page` | `number` | The current page. | | `count` | `number` | The total number of data items. | | `pageSize` | `number` | The number of data items per page. | | `totalPages` | `number` | The total number of pages. | | `pages` | `Pages` | The page range. Represented as an array of page numbers (including ellipsis) | | `previousPage` | `number` | The previous page. | | `nextPage` | `number` | The next page. | | `pageRange` | `PageRange` | The page range. Represented as an object with `start` and `end` properties. | | `slice` | `(data: V[]) => V[]` | Function to slice an array of data based on the current page. | | `setPageSize` | `(size: number) => void` | Function to set the page size. | | `setPage` | `(page: number) => void` | Function to set the current page. | | `goToNextPage` | `VoidFunction` | Function to go to the next page. | | `goToPrevPage` | `VoidFunction` | Function to go to the previous page. | | `goToFirstPage` | `VoidFunction` | Function to go to the first page. | | `goToLastPage` | `VoidFunction` | Function to go to the last page. | --- # Pagination (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Basic = () => (
                    {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) }
                    ) ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const Basic = () => (
                    {(pagination) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )}
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet render(pagination)} {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} {/snippet}
                    ``` ### 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: **Example: controlled** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { useState } from 'react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Controlled = () => { const [currentPage, setCurrentPage] = useState(1) return ( setCurrentPage(details.page)} className={styles.Root} >
                    {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) }
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For, createSignal } from 'solid-js' import styles from 'styles/pagination.module.css' export const Controlled = () => { const [currentPage, setCurrentPage] = createSignal(1) return ( setCurrentPage(details.page)} class={styles.Root} >
                    {(pagination) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet render(pagination)} {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} {/snippet}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination, usePagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const RootProvider = () => { const pagination = usePagination({ count: 5000, pageSize: 10, siblingCount: 2 }) return (
                    {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) }
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination, usePagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const RootProvider = () => { const pagination = usePagination({ count: 5000, pageSize: 10, siblingCount: 2 }) return (
                    {(pagination) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}
                    ``` ### 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: **Example: customized** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Customized = () => ( `Page ${details.page}`, }} className={styles.Root} >
                    {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) }
                    ) ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const Customized = () => { return ( `Page ${details.page}`, }} class={styles.Root} >
                    {(pagination) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte `Page ${details.page}`, }} class={styles.Root} >
                    {#snippet render(pagination)} {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} {/snippet}
                    ``` ### Context The `Context` component provides access to the pagination state and methods through a render prop pattern. This allows you to access methods like `setPage`, `setPageSize`, `goToNextPage`, `goToPrevPage`, `goToFirstPage`, `goToLastPage`, as well as properties like `totalPages` and `pageRange`. **Example: context** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon, ChevronsLeftIcon, ChevronsRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Context = () => { return ( {(pagination) => (

                    Page {pagination.page} of {pagination.totalPages}

                    )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon, ChevronsLeftIcon, ChevronsRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import styles from 'styles/pagination.module.css' export const Context = () => { return ( {(pagination) => (

                    Page {pagination().page} of {pagination().totalPages}

                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}

                    Page {pagination().page} of {pagination().totalPages}

                    {/snippet}
                    ``` ### 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. **Example: data-slicing** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' const users = [ { id: 1, name: 'Emma Wilson', email: 'emma@example.com' }, { id: 2, name: 'Liam Johnson', email: 'liam@example.com' }, { id: 3, name: 'Olivia Brown', email: 'olivia@example.com' }, { id: 4, name: 'Noah Davis', email: 'noah@example.com' }, { id: 5, name: 'Ava Martinez', email: 'ava@example.com' }, { id: 6, name: 'Ethan Garcia', email: 'ethan@example.com' }, { id: 7, name: 'Sophia Rodriguez', email: 'sophia@example.com' }, { id: 8, name: 'Mason Lee', email: 'mason@example.com' }, { id: 9, name: 'Isabella Walker', email: 'isabella@example.com' }, { id: 10, name: 'James Hall', email: 'james@example.com' }, { id: 11, name: 'Mia Allen', email: 'mia@example.com' }, { id: 12, name: 'Benjamin Young', email: 'benjamin@example.com' }, { id: 13, name: 'Charlotte King', email: 'charlotte@example.com' }, { id: 14, name: 'William Wright', email: 'william@example.com' }, { id: 15, name: 'Amelia Scott', email: 'amelia@example.com' }, { id: 16, name: 'Henry Green', email: 'henry@example.com' }, { id: 17, name: 'Harper Adams', email: 'harper@example.com' }, { id: 18, name: 'Sebastian Baker', email: 'sebastian@example.com' }, { id: 19, name: 'Evelyn Nelson', email: 'evelyn@example.com' }, { id: 20, name: 'Jack Carter', email: 'jack@example.com' }, ] export const DataSlicing = () => { return ( {(pagination) => ( <>
                    {pagination.slice(users).map((user) => (
                    {user.name} {user.email}
                    ))}
                    {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )}
                    )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' const users = [ { id: 1, name: 'Emma Wilson', email: 'emma@example.com' }, { id: 2, name: 'Liam Johnson', email: 'liam@example.com' }, { id: 3, name: 'Olivia Brown', email: 'olivia@example.com' }, { id: 4, name: 'Noah Davis', email: 'noah@example.com' }, { id: 5, name: 'Ava Martinez', email: 'ava@example.com' }, { id: 6, name: 'Ethan Garcia', email: 'ethan@example.com' }, { id: 7, name: 'Sophia Rodriguez', email: 'sophia@example.com' }, { id: 8, name: 'Mason Lee', email: 'mason@example.com' }, { id: 9, name: 'Isabella Walker', email: 'isabella@example.com' }, { id: 10, name: 'James Hall', email: 'james@example.com' }, { id: 11, name: 'Mia Allen', email: 'mia@example.com' }, { id: 12, name: 'Benjamin Young', email: 'benjamin@example.com' }, { id: 13, name: 'Charlotte King', email: 'charlotte@example.com' }, { id: 14, name: 'William Wright', email: 'william@example.com' }, { id: 15, name: 'Amelia Scott', email: 'amelia@example.com' }, { id: 16, name: 'Henry Green', email: 'henry@example.com' }, { id: 17, name: 'Harper Adams', email: 'harper@example.com' }, { id: 18, name: 'Sebastian Baker', email: 'sebastian@example.com' }, { id: 19, name: 'Evelyn Nelson', email: 'evelyn@example.com' }, { id: 20, name: 'Jack Carter', email: 'jack@example.com' }, ] export const DataSlicing = () => { return ( {(pagination) => ( <>
                    {(user) => (
                    {user.name} {user.email}
                    )}
                    {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) }
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}
                    {#each pagination().slice(users) as user (user.id)}
                    {user.name} {user.email}
                    {/each}
                    {#each pagination().pages as page, index} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}
                    {/snippet}
                    ``` ### 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"). **Example: page-range** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const PageRange = () => { return ( {(pagination) => ( <>
                    {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )}

                    Showing {pagination.pageRange.start + 1}-{pagination.pageRange.end} of {pagination.count} results

                    Page {pagination.page} of {pagination.totalPages}

                    )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const PageRange = () => { return ( {(pagination) => ( <>
                    {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) }

                    Showing {pagination().pageRange.start + 1}-{pagination().pageRange.end} of {pagination().count} results

                    Page {pagination().page} of {pagination().totalPages}

                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}
                    {#each pagination().pages as page, index} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}

                    Showing {pagination().pageRange.start + 1}-{pagination().pageRange.end} of {pagination().count} results

                    Page {pagination().page} of {pagination().totalPages}

                    {/snippet}
                    ``` ### 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. **Example: page-size-control** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const PageSizeControl = () => { return ( {(pagination) => ( <>
                    {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )}

                    Page {pagination.page} of {pagination.totalPages}

                    )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const PageSizeControl = () => { return ( {(pagination) => ( <>
                    {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) }

                    Page {pagination().page} of {pagination().totalPages}

                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}
                    {#each pagination().pages as page, index} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}

                    Page {pagination().page} of {pagination().totalPages}

                    {/snippet}
                    ``` ### 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. **Example: link** #### React ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react' import { Pagination, usePagination } from '@ark-ui/react/pagination' import styles from 'styles/pagination.module.css' export const Link = () => { const pagination = usePagination({ type: 'link', count: 100, pageSize: 10, siblingCount: 2, getPageUrl: ({ page }) => `/page=${page}`, }) return (
                    {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )}
                    ) } ``` #### Solid ```tsx import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-solid' import { Pagination, usePagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' import styles from 'styles/pagination.module.css' export const Link = () => { const pagination = usePagination({ type: 'link', count: 100, pageSize: 10, siblingCount: 2, getPageUrl: ({ page }) => `/page=${page}`, }) return (
                    {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | Total number of data items | | `defaultPage` | `number` | No | The initial active page when rendered. Use when you don't need to control the active page of the pagination. | | `defaultPageSize` | `number` | No | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. | | `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links. Only used when `type` is set to "link". | | `ids` | `Partial<{ root: string ellipsis: (index: number) => string prevTrigger: string nextTrigger: string item: (page: number) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Called when the page number is changed | | `onPageSizeChange` | `(details: PageSizeChangeDetails) => void` | No | Called when the page size is changed | | `page` | `number` | No | The controlled active page | | `pageSize` | `number` | No | The controlled number of data items per page | | `siblingCount` | `number` | No | Number of pages to show beside active page | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'button' | 'link'` | No | The type of the trigger element | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePaginationReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'nav'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | Total number of data items | | `defaultPage` | `number` | No | The initial active page when rendered. Use when you don't need to control the active page of the pagination. | | `defaultPageSize` | `number` | No | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. | | `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links. Only used when `type` is set to "link". | | `ids` | `Partial<{ root: string ellipsis: (index: number) => string prevTrigger: string nextTrigger: string item: (page: number) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Called when the page number is changed | | `onPageSizeChange` | `(details: PageSizeChangeDetails) => void` | No | Called when the page size is changed | | `page` | `number` | No | The controlled active page | | `pageSize` | `number` | No | The controlled number of data items per page | | `siblingCount` | `number` | No | Number of pages to show beside active page | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'link' | 'button'` | No | The type of the trigger element | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePaginationReturn` | Yes | | | `asChild` | `(props: ParentProps<'nav'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | Total number of data items | | `defaultPage` | `number` | No | The initial active page when rendered. Use when you don't need to control the active page of the pagination. | | `defaultPageSize` | `number` | No | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. | | `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links. Only used when `type` is set to "link". | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string ellipsis(index: number): string prevTrigger: string nextTrigger: string item(page: number): string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `page` | `number` | No | The controlled active page | | `pageSize` | `number` | No | The controlled number of data items per page | | `siblingCount` | `number` | No | Number of pages to show beside active page | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'button' | 'link'` | No | The type of the trigger element | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PaginationApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'nav'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | Total number of data items | | `defaultPage` | `number` | No | The initial active page when rendered. Use when you don't need to control the active page of the pagination. | | `defaultPageSize` | `number` | No | The initial number of data items per page when rendered. Use when you don't need to control the page size of the pagination. | | `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links. Only used when `type` is set to "link". | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string ellipsis: (index: number) => string prevTrigger: string nextTrigger: string item: (page: number) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `onPageChange` | `(details: PageChangeDetails) => void` | No | Called when the page number is changed | | `onPageSizeChange` | `(details: PageSizeChangeDetails) => void` | No | Called when the page size is changed | | `page` | `number` | No | The controlled active page | | `pageSize` | `number` | No | The controlled number of data items per page | | `ref` | `Element` | No | | | `siblingCount` | `number` | No | Number of pages to show beside active page | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'button' | 'link'` | No | The type of the trigger element | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePaginationContext]>` | Yes | | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | prev-trigger | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePaginationReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'nav'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `page` | `number` | The current page. | | `count` | `number` | The total number of data items. | | `pageSize` | `number` | The number of data items per page. | | `totalPages` | `number` | The total number of pages. | | `pages` | `Pages` | The page range. Represented as an array of page numbers (including ellipsis) | | `previousPage` | `number` | The previous page. | | `nextPage` | `number` | The next page. | | `pageRange` | `PageRange` | The page range. Represented as an object with `start` and `end` properties. | | `slice` | `(data: V[]) => V[]` | Function to slice an array of data based on the current page. | | `setPageSize` | `(size: number) => void` | Function to set the page size. | | `setPage` | `(page: number) => void` | Function to set the current page. | | `goToNextPage` | `VoidFunction` | Function to go to the next page. | | `goToPrevPage` | `VoidFunction` | Function to go to the previous page. | | `goToFirstPage` | `VoidFunction` | Function to go to the first page. | | `goToLastPage` | `VoidFunction` | Function to go to the last page. | --- # Password Input (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import styles from 'styles/password-input.module.css' export const Basic = () => ( Password }> ) ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import styles from 'styles/password-input.module.css' export const Basic = () => ( Password }> ) ``` #### Vue ```vue ``` #### Svelte ```svelte Password {#snippet fallback()} {/snippet} ``` ### 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. **Example: autocomplete** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import styles from 'styles/password-input.module.css' export const Autocomplete = () => ( Password }> ) ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import styles from 'styles/password-input.module.css' export const Autocomplete = () => ( Password }> ) ``` #### Vue ```vue ``` #### Svelte ```svelte Password {#snippet fallback()} {/snippet} ``` ### Controlled Visibility Use the `visible` and `onVisibilityChange` props to control the visibility of the password input. **Example: controlled-visibility** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/password-input.module.css' export const ControlledVisibility = () => { const [visible, setVisible] = useState(false) return ( setVisible(e.visible)}> Password is {visible ? 'visible' : 'hidden'} }> ) } ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/password-input.module.css' export const ControlledVisibility = () => { const [visible, setVisible] = createSignal(false) return ( setVisible(e.visible)}> Password is {visible() ? 'visible' : 'hidden'} }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Password is {visible ? 'visible' : 'hidden'} {#snippet fallback()} {/snippet} ``` ### 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. **Example: root-provider** #### React ```tsx import { PasswordInput, usePasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import styles from 'styles/password-input.module.css' export const RootProvider = () => { const passwordInput = usePasswordInput() return (
                    password input is {passwordInput.visible ? 'visible' : 'hidden'} Password }>
                    ) } ``` #### Solid ```tsx import { PasswordInput, usePasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import styles from 'styles/password-input.module.css' export const RootProvider = () => { const passwordInput = usePasswordInput() return (
                    password input is {passwordInput().visible ? 'visible' : 'hidden'} Password }>
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    password input is {passwordInput().visible ? 'visible' : 'hidden'} Password {#snippet fallback()} {/snippet}
                    ``` ### Field Here's an example of how to use the `PasswordInput` component with the `Field` component. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/password-input.module.css' export const WithField = () => ( Password }> Enter your password Password is required ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import field from 'styles/field.module.css' import styles from 'styles/password-input.module.css' export const WithField = () => ( Password }> Enter your password Password is required ) ``` #### Vue ```vue ``` #### Svelte ```svelte Password {#snippet fallback()} {/snippet} Enter your password Password is required ``` ### Password Managers Use the `ignorePasswordManager` prop to ignore password managers like 1Password, LastPass, etc. This is useful for non-login scenarios (e.g., "api keys", "secure notes", "temporary passwords") > **Currently, this only works for 1Password, LastPass, Bitwarden, Dashlane, and Proton Pass.** **Example: ignore-password-manager** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import styles from 'styles/password-input.module.css' export const IgnorePasswordManager = () => ( API Key }> ) ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import styles from 'styles/password-input.module.css' export const IgnorePasswordManager = () => ( API Key }> ) ``` #### Vue ```vue ``` #### Svelte ```svelte API Key {#snippet fallback()} {/snippet} ``` ### Strength Meter Combine the `PasswordInput` with a password strength library to show visual feedback about password strength. This example uses the [`check-password-strength`](https://www.npmjs.com/package/check-password-strength) package to provide real-time strength validation. **Example: strength-meter** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { passwordStrength, type Options } from 'check-password-strength' import { EyeIcon, EyeOffIcon } from 'lucide-react' import { useMemo, useState } from 'react' import styles from 'styles/password-input.module.css' const strengthOptions: Options = [ { id: 0, value: 'weak', minDiversity: 0, minLength: 0 }, { id: 1, value: 'medium', minDiversity: 2, minLength: 6 }, { id: 2, value: 'strong', minDiversity: 4, minLength: 8 }, ] export const StrengthMeter = () => { const [password, setPassword] = useState('asdfasdf') const strength = useMemo(() => { if (!password) return null const { value } = passwordStrength(password, strengthOptions) return value }, [password]) return ( Password setPassword(e.currentTarget.value)} placeholder="Enter your password" /> }> {strength && (
                    {strength} password
                    )} ) } ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { passwordStrength, type Options } from 'check-password-strength' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import { createMemo, createSignal, Show } from 'solid-js' import styles from 'styles/password-input.module.css' const strengthOptions: Options = [ { id: 0, value: 'weak', minDiversity: 0, minLength: 0 }, { id: 1, value: 'medium', minDiversity: 2, minLength: 6 }, { id: 2, value: 'strong', minDiversity: 4, minLength: 8 }, ] export const StrengthMeter = () => { const [password, setPassword] = createSignal('asdfasdf') const strength = createMemo(() => { if (!password()) return null const { value } = passwordStrength(password(), strengthOptions) return value }) return ( Password setPassword(e.currentTarget.value)} placeholder="Enter your password" /> }> {(value) => (
                    {value()} password
                    )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Password {#snippet fallback()} {/snippet} {#if strength}
                    {strength} password
                    {/if}
                    ``` ### Validation Combine with custom validation logic to show real-time feedback. Use the `invalid` prop to indicate validation errors. **Example: with-validation** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import { useMemo, useState } from 'react' import styles from 'styles/password-input.module.css' export const WithValidation = () => { const [password, setPassword] = useState('') const isValid = useMemo(() => password.length >= 8, [password]) return ( 0}> Password (min 8 characters) setPassword(e.target.value)} placeholder="Enter your password" /> }> {password.length > 0 && !isValid && (

                    Password must be at least 8 characters

                    )} {isValid && password.length > 0 && (

                    Password is valid

                    )}
                    ) } ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import { createMemo, createSignal } from 'solid-js' import styles from 'styles/password-input.module.css' export const WithValidation = () => { const [password, setPassword] = createSignal('') const isValid = createMemo(() => password().length >= 8) return ( 0}> Password (min 8 characters) setPassword(e.currentTarget.value)} placeholder="Enter your password" /> }> {password().length > 0 && !isValid() && (

                    Password must be at least 8 characters

                    )} {isValid() && password().length > 0 && (

                    Password is valid

                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte 0}> Password (min 8 characters) (password = e.currentTarget.value)} placeholder="Enter your password" /> {#snippet fallback()} {/snippet} {#if password.length > 0 && !isValid}

                    Password must be at least 8 characters

                    {/if} {#if isValid && password.length > 0}

                    Password is valid

                    {/if}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoComplete` | `'current-password' | 'new-password'` | No | The autocomplete attribute for the password input. | | `defaultVisible` | `boolean` | No | The default visibility of the password input. | | `disabled` | `boolean` | No | Whether the password input is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ input: string; visibilityTrigger: string }>` | No | The ids of the password input parts | | `ignorePasswordManagers` | `boolean` | No | When `true`, the input will ignore password managers. **Only works for the following password managers** - 1Password, LastPass, Bitwarden, Dashlane, Proton Pass | | `invalid` | `boolean` | No | The invalid state of the password input. | | `name` | `string` | No | The name of the password input. | | `onVisibilityChange` | `(details: VisibilityChangeDetails) => void` | No | Function called when the visibility changes. | | `readOnly` | `boolean` | No | Whether the password input is read only. | | `required` | `boolean` | No | Whether the password input is required. | | `translations` | `Partial<{ visibilityTrigger: ((visible: boolean) => string) | undefined }>` | No | The localized messages to use. | | `visible` | `boolean` | No | Whether the password input is visible. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | The fallback content to display when the password is not visible. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | indicator | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | input | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePasswordInputReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | visibility-trigger | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-state]` | "visible" | "hidden" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoComplete` | `'current-password' | 'new-password'` | No | The autocomplete attribute for the password input. | | `defaultVisible` | `boolean` | No | The default visibility of the password input. | | `disabled` | `boolean` | No | Whether the password input is disabled. | | `ids` | `Partial<{ input: string; visibilityTrigger: string }>` | No | The ids of the password input parts | | `ignorePasswordManagers` | `boolean` | No | When `true`, the input will ignore password managers. **Only works for the following password managers** - 1Password, LastPass, Bitwarden, Dashlane, Proton Pass | | `invalid` | `boolean` | No | The invalid state of the password input. | | `name` | `string` | No | The name of the password input. | | `onVisibilityChange` | `(details: VisibilityChangeDetails) => void` | No | Function called when the visibility changes. | | `readOnly` | `boolean` | No | Whether the password input is read only. | | `required` | `boolean` | No | Whether the password input is required. | | `translations` | `Partial<{ visibilityTrigger: ((visible: boolean) => string) | undefined }>` | No | The localized messages to use. | | `visible` | `boolean` | No | Whether the password input is visible. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `number | boolean | Node | ArrayElement | (string & {})` | No | The fallback content to display when the password is not visible. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | indicator | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | input | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePasswordInputContext` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | visibility-trigger | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-state]` | "visible" | "hidden" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoComplete` | `'current-password' | 'new-password'` | No | The autocomplete attribute for the input | | `defaultVisible` | `boolean` | No | Whether the password is visible by default | | `disabled` | `boolean` | No | Whether the input is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ input: string; visibilityTrigger: string }>` | No | The ids of the elements in the password input. Useful for composition. | | `ignorePasswordManagers` | `boolean` | No | Whether to ignore password managers | | `invalid` | `boolean` | No | Whether the input is in an invalid state | | `name` | `string` | No | The name attribute for the input | | `readOnly` | `boolean` | No | Whether the input is read-only | | `required` | `boolean` | No | Whether the input is required | | `translations` | `Partial<{ visibilityTrigger: ((visible: boolean) => string) | undefined }>` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `visible` | `boolean` | No | Whether the password is visible | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePasswordInputReturn` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `string` | No | The fallback content to display when the password is not visible. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | indicator | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | input | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PasswordInputApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | visibility-trigger | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-state]` | "visible" | "hidden" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoComplete` | `'current-password' | 'new-password'` | No | The autocomplete attribute for the password input. | | `defaultVisible` | `boolean` | No | The default visibility of the password input. | | `disabled` | `boolean` | No | Whether the password input is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ input: string; visibilityTrigger: string }>` | No | The ids of the password input parts | | `ignorePasswordManagers` | `boolean` | No | When `true`, the input will ignore password managers. **Only works for the following password managers** - 1Password, LastPass, Bitwarden, Dashlane, Proton Pass | | `invalid` | `boolean` | No | The invalid state of the password input. | | `name` | `string` | No | The name of the password input. | | `onVisibilityChange` | `(details: VisibilityChangeDetails) => void` | No | Function called when the visibility changes. | | `readOnly` | `boolean` | No | Whether the password input is read only. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the password input is required. | | `translations` | `Partial<{ visibilityTrigger: ((visible: boolean) => string) | undefined }>` | No | The localized messages to use. | | `visible` | `boolean` | No | Whether the password input is visible. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePasswordInputContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `Snippet<[]>` | No | The fallback content to display when the password is not visible. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | indicator | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | input | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePasswordInputReturn` | Yes | | | `ref` | `Element` | No | | **VisibilityTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **VisibilityTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | visibility-trigger | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-state]` | "visible" | "hidden" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `visible` | `boolean` | Whether the password input is visible. | | `disabled` | `boolean` | Whether the password input is disabled. | | `invalid` | `boolean` | Whether the password input is invalid. | | `focus` | `VoidFunction` | Focus the password input. | | `setVisible` | `(value: boolean) => void` | Set the visibility of the password input. | | `toggleVisible` | `VoidFunction` | Toggle the visibility of the password input. | --- # Password Input (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import styles from 'styles/password-input.module.css' export const Basic = () => ( Password }> ) ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import styles from 'styles/password-input.module.css' export const Basic = () => ( Password }> ) ``` #### Vue ```vue ``` #### Svelte ```svelte Password {#snippet fallback()} {/snippet} ``` ### 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. **Example: autocomplete** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import styles from 'styles/password-input.module.css' export const Autocomplete = () => ( Password }> ) ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import styles from 'styles/password-input.module.css' export const Autocomplete = () => ( Password }> ) ``` #### Vue ```vue ``` #### Svelte ```svelte Password {#snippet fallback()} {/snippet} ``` ### Controlled Visibility Use the `visible` and `onVisibilityChange` props to control the visibility of the password input. **Example: controlled-visibility** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/password-input.module.css' export const ControlledVisibility = () => { const [visible, setVisible] = useState(false) return ( setVisible(e.visible)}> Password is {visible ? 'visible' : 'hidden'} }> ) } ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/password-input.module.css' export const ControlledVisibility = () => { const [visible, setVisible] = createSignal(false) return ( setVisible(e.visible)}> Password is {visible() ? 'visible' : 'hidden'} }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Password is {visible ? 'visible' : 'hidden'} {#snippet fallback()} {/snippet} ``` ### 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. **Example: root-provider** #### React ```tsx import { PasswordInput, usePasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import styles from 'styles/password-input.module.css' export const RootProvider = () => { const passwordInput = usePasswordInput() return (
                    password input is {passwordInput.visible ? 'visible' : 'hidden'} Password }>
                    ) } ``` #### Solid ```tsx import { PasswordInput, usePasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import styles from 'styles/password-input.module.css' export const RootProvider = () => { const passwordInput = usePasswordInput() return (
                    password input is {passwordInput().visible ? 'visible' : 'hidden'} Password }>
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    password input is {passwordInput().visible ? 'visible' : 'hidden'} Password {#snippet fallback()} {/snippet}
                    ``` ### Field Here's an example of how to use the `PasswordInput` component with the `Field` component. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/password-input.module.css' export const WithField = () => ( Password }> Enter your password Password is required ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import field from 'styles/field.module.css' import styles from 'styles/password-input.module.css' export const WithField = () => ( Password }> Enter your password Password is required ) ``` #### Vue ```vue ``` #### Svelte ```svelte Password {#snippet fallback()} {/snippet} Enter your password Password is required ``` ### Password Managers Use the `ignorePasswordManager` prop to ignore password managers like 1Password, LastPass, etc. This is useful for non-login scenarios (e.g., "api keys", "secure notes", "temporary passwords") > **Currently, this only works for 1Password, LastPass, Bitwarden, Dashlane, and Proton Pass.** **Example: ignore-password-manager** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import styles from 'styles/password-input.module.css' export const IgnorePasswordManager = () => ( API Key }> ) ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import styles from 'styles/password-input.module.css' export const IgnorePasswordManager = () => ( API Key }> ) ``` #### Vue ```vue ``` #### Svelte ```svelte API Key {#snippet fallback()} {/snippet} ``` ### Strength Meter Combine the `PasswordInput` with a password strength library to show visual feedback about password strength. This example uses the [`check-password-strength`](https://www.npmjs.com/package/check-password-strength) package to provide real-time strength validation. **Example: strength-meter** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { passwordStrength, type Options } from 'check-password-strength' import { EyeIcon, EyeOffIcon } from 'lucide-react' import { useMemo, useState } from 'react' import styles from 'styles/password-input.module.css' const strengthOptions: Options = [ { id: 0, value: 'weak', minDiversity: 0, minLength: 0 }, { id: 1, value: 'medium', minDiversity: 2, minLength: 6 }, { id: 2, value: 'strong', minDiversity: 4, minLength: 8 }, ] export const StrengthMeter = () => { const [password, setPassword] = useState('asdfasdf') const strength = useMemo(() => { if (!password) return null const { value } = passwordStrength(password, strengthOptions) return value }, [password]) return ( Password setPassword(e.currentTarget.value)} placeholder="Enter your password" /> }> {strength && (
                    {strength} password
                    )} ) } ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { passwordStrength, type Options } from 'check-password-strength' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import { createMemo, createSignal, Show } from 'solid-js' import styles from 'styles/password-input.module.css' const strengthOptions: Options = [ { id: 0, value: 'weak', minDiversity: 0, minLength: 0 }, { id: 1, value: 'medium', minDiversity: 2, minLength: 6 }, { id: 2, value: 'strong', minDiversity: 4, minLength: 8 }, ] export const StrengthMeter = () => { const [password, setPassword] = createSignal('asdfasdf') const strength = createMemo(() => { if (!password()) return null const { value } = passwordStrength(password(), strengthOptions) return value }) return ( Password setPassword(e.currentTarget.value)} placeholder="Enter your password" /> }> {(value) => (
                    {value()} password
                    )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Password {#snippet fallback()} {/snippet} {#if strength}
                    {strength} password
                    {/if}
                    ``` ### Validation Combine with custom validation logic to show real-time feedback. Use the `invalid` prop to indicate validation errors. **Example: with-validation** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import { useMemo, useState } from 'react' import styles from 'styles/password-input.module.css' export const WithValidation = () => { const [password, setPassword] = useState('') const isValid = useMemo(() => password.length >= 8, [password]) return ( 0}> Password (min 8 characters) setPassword(e.target.value)} placeholder="Enter your password" /> }> {password.length > 0 && !isValid && (

                    Password must be at least 8 characters

                    )} {isValid && password.length > 0 && (

                    Password is valid

                    )}
                    ) } ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import { createMemo, createSignal } from 'solid-js' import styles from 'styles/password-input.module.css' export const WithValidation = () => { const [password, setPassword] = createSignal('') const isValid = createMemo(() => password().length >= 8) return ( 0}> Password (min 8 characters) setPassword(e.currentTarget.value)} placeholder="Enter your password" /> }> {password().length > 0 && !isValid() && (

                    Password must be at least 8 characters

                    )} {isValid() && password().length > 0 && (

                    Password is valid

                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte 0}> Password (min 8 characters) (password = e.currentTarget.value)} placeholder="Enter your password" /> {#snippet fallback()} {/snippet} {#if password.length > 0 && !isValid}

                    Password must be at least 8 characters

                    {/if} {#if isValid && password.length > 0}

                    Password is valid

                    {/if}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoComplete` | `'current-password' | 'new-password'` | No | The autocomplete attribute for the password input. | | `defaultVisible` | `boolean` | No | The default visibility of the password input. | | `disabled` | `boolean` | No | Whether the password input is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ input: string; visibilityTrigger: string }>` | No | The ids of the password input parts | | `ignorePasswordManagers` | `boolean` | No | When `true`, the input will ignore password managers. **Only works for the following password managers** - 1Password, LastPass, Bitwarden, Dashlane, Proton Pass | | `invalid` | `boolean` | No | The invalid state of the password input. | | `name` | `string` | No | The name of the password input. | | `onVisibilityChange` | `(details: VisibilityChangeDetails) => void` | No | Function called when the visibility changes. | | `readOnly` | `boolean` | No | Whether the password input is read only. | | `required` | `boolean` | No | Whether the password input is required. | | `translations` | `Partial<{ visibilityTrigger: ((visible: boolean) => string) | undefined }>` | No | The localized messages to use. | | `visible` | `boolean` | No | Whether the password input is visible. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | The fallback content to display when the password is not visible. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | indicator | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | input | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePasswordInputReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | visibility-trigger | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-state]` | "visible" | "hidden" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoComplete` | `'current-password' | 'new-password'` | No | The autocomplete attribute for the password input. | | `defaultVisible` | `boolean` | No | The default visibility of the password input. | | `disabled` | `boolean` | No | Whether the password input is disabled. | | `ids` | `Partial<{ input: string; visibilityTrigger: string }>` | No | The ids of the password input parts | | `ignorePasswordManagers` | `boolean` | No | When `true`, the input will ignore password managers. **Only works for the following password managers** - 1Password, LastPass, Bitwarden, Dashlane, Proton Pass | | `invalid` | `boolean` | No | The invalid state of the password input. | | `name` | `string` | No | The name of the password input. | | `onVisibilityChange` | `(details: VisibilityChangeDetails) => void` | No | Function called when the visibility changes. | | `readOnly` | `boolean` | No | Whether the password input is read only. | | `required` | `boolean` | No | Whether the password input is required. | | `translations` | `Partial<{ visibilityTrigger: ((visible: boolean) => string) | undefined }>` | No | The localized messages to use. | | `visible` | `boolean` | No | Whether the password input is visible. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `number | boolean | Node | ArrayElement | (string & {})` | No | The fallback content to display when the password is not visible. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | indicator | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | input | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePasswordInputContext` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | visibility-trigger | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-state]` | "visible" | "hidden" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoComplete` | `'current-password' | 'new-password'` | No | The autocomplete attribute for the input | | `defaultVisible` | `boolean` | No | Whether the password is visible by default | | `disabled` | `boolean` | No | Whether the input is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ input: string; visibilityTrigger: string }>` | No | The ids of the elements in the password input. Useful for composition. | | `ignorePasswordManagers` | `boolean` | No | Whether to ignore password managers | | `invalid` | `boolean` | No | Whether the input is in an invalid state | | `name` | `string` | No | The name attribute for the input | | `readOnly` | `boolean` | No | Whether the input is read-only | | `required` | `boolean` | No | Whether the input is required | | `translations` | `Partial<{ visibilityTrigger: ((visible: boolean) => string) | undefined }>` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `visible` | `boolean` | No | Whether the password is visible | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePasswordInputReturn` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `string` | No | The fallback content to display when the password is not visible. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | indicator | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | input | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PasswordInputApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | visibility-trigger | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-state]` | "visible" | "hidden" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoComplete` | `'current-password' | 'new-password'` | No | The autocomplete attribute for the password input. | | `defaultVisible` | `boolean` | No | The default visibility of the password input. | | `disabled` | `boolean` | No | Whether the password input is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ input: string; visibilityTrigger: string }>` | No | The ids of the password input parts | | `ignorePasswordManagers` | `boolean` | No | When `true`, the input will ignore password managers. **Only works for the following password managers** - 1Password, LastPass, Bitwarden, Dashlane, Proton Pass | | `invalid` | `boolean` | No | The invalid state of the password input. | | `name` | `string` | No | The name of the password input. | | `onVisibilityChange` | `(details: VisibilityChangeDetails) => void` | No | Function called when the visibility changes. | | `readOnly` | `boolean` | No | Whether the password input is read only. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the password input is required. | | `translations` | `Partial<{ visibilityTrigger: ((visible: boolean) => string) | undefined }>` | No | The localized messages to use. | | `visible` | `boolean` | No | Whether the password input is visible. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePasswordInputContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `Snippet<[]>` | No | The fallback content to display when the password is not visible. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | indicator | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | input | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePasswordInputReturn` | Yes | | | `ref` | `Element` | No | | **VisibilityTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **VisibilityTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | visibility-trigger | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-state]` | "visible" | "hidden" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `visible` | `boolean` | Whether the password input is visible. | | `disabled` | `boolean` | Whether the password input is disabled. | | `invalid` | `boolean` | Whether the password input is invalid. | | `focus` | `VoidFunction` | Focus the password input. | | `setVisible` | `(value: boolean) => void` | Set the visibility of the password input. | | `toggleVisible` | `VoidFunction` | Toggle the visibility of the password input. | --- # Password Input (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import styles from 'styles/password-input.module.css' export const Basic = () => ( Password }> ) ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import styles from 'styles/password-input.module.css' export const Basic = () => ( Password }> ) ``` #### Vue ```vue ``` #### Svelte ```svelte Password {#snippet fallback()} {/snippet} ``` ### 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. **Example: autocomplete** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import styles from 'styles/password-input.module.css' export const Autocomplete = () => ( Password }> ) ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import styles from 'styles/password-input.module.css' export const Autocomplete = () => ( Password }> ) ``` #### Vue ```vue ``` #### Svelte ```svelte Password {#snippet fallback()} {/snippet} ``` ### Controlled Visibility Use the `visible` and `onVisibilityChange` props to control the visibility of the password input. **Example: controlled-visibility** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/password-input.module.css' export const ControlledVisibility = () => { const [visible, setVisible] = useState(false) return ( setVisible(e.visible)}> Password is {visible ? 'visible' : 'hidden'} }> ) } ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/password-input.module.css' export const ControlledVisibility = () => { const [visible, setVisible] = createSignal(false) return ( setVisible(e.visible)}> Password is {visible() ? 'visible' : 'hidden'} }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Password is {visible ? 'visible' : 'hidden'} {#snippet fallback()} {/snippet} ``` ### 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. **Example: root-provider** #### React ```tsx import { PasswordInput, usePasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import styles from 'styles/password-input.module.css' export const RootProvider = () => { const passwordInput = usePasswordInput() return (
                    password input is {passwordInput.visible ? 'visible' : 'hidden'} Password }>
                    ) } ``` #### Solid ```tsx import { PasswordInput, usePasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import styles from 'styles/password-input.module.css' export const RootProvider = () => { const passwordInput = usePasswordInput() return (
                    password input is {passwordInput().visible ? 'visible' : 'hidden'} Password }>
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    password input is {passwordInput().visible ? 'visible' : 'hidden'} Password {#snippet fallback()} {/snippet}
                    ``` ### Field Here's an example of how to use the `PasswordInput` component with the `Field` component. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/password-input.module.css' export const WithField = () => ( Password }> Enter your password Password is required ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import field from 'styles/field.module.css' import styles from 'styles/password-input.module.css' export const WithField = () => ( Password }> Enter your password Password is required ) ``` #### Vue ```vue ``` #### Svelte ```svelte Password {#snippet fallback()} {/snippet} Enter your password Password is required ``` ### Password Managers Use the `ignorePasswordManager` prop to ignore password managers like 1Password, LastPass, etc. This is useful for non-login scenarios (e.g., "api keys", "secure notes", "temporary passwords") > **Currently, this only works for 1Password, LastPass, Bitwarden, Dashlane, and Proton Pass.** **Example: ignore-password-manager** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import styles from 'styles/password-input.module.css' export const IgnorePasswordManager = () => ( API Key }> ) ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import styles from 'styles/password-input.module.css' export const IgnorePasswordManager = () => ( API Key }> ) ``` #### Vue ```vue ``` #### Svelte ```svelte API Key {#snippet fallback()} {/snippet} ``` ### Strength Meter Combine the `PasswordInput` with a password strength library to show visual feedback about password strength. This example uses the [`check-password-strength`](https://www.npmjs.com/package/check-password-strength) package to provide real-time strength validation. **Example: strength-meter** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { passwordStrength, type Options } from 'check-password-strength' import { EyeIcon, EyeOffIcon } from 'lucide-react' import { useMemo, useState } from 'react' import styles from 'styles/password-input.module.css' const strengthOptions: Options = [ { id: 0, value: 'weak', minDiversity: 0, minLength: 0 }, { id: 1, value: 'medium', minDiversity: 2, minLength: 6 }, { id: 2, value: 'strong', minDiversity: 4, minLength: 8 }, ] export const StrengthMeter = () => { const [password, setPassword] = useState('asdfasdf') const strength = useMemo(() => { if (!password) return null const { value } = passwordStrength(password, strengthOptions) return value }, [password]) return ( Password setPassword(e.currentTarget.value)} placeholder="Enter your password" /> }> {strength && (
                    {strength} password
                    )} ) } ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { passwordStrength, type Options } from 'check-password-strength' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import { createMemo, createSignal, Show } from 'solid-js' import styles from 'styles/password-input.module.css' const strengthOptions: Options = [ { id: 0, value: 'weak', minDiversity: 0, minLength: 0 }, { id: 1, value: 'medium', minDiversity: 2, minLength: 6 }, { id: 2, value: 'strong', minDiversity: 4, minLength: 8 }, ] export const StrengthMeter = () => { const [password, setPassword] = createSignal('asdfasdf') const strength = createMemo(() => { if (!password()) return null const { value } = passwordStrength(password(), strengthOptions) return value }) return ( Password setPassword(e.currentTarget.value)} placeholder="Enter your password" /> }> {(value) => (
                    {value()} password
                    )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Password {#snippet fallback()} {/snippet} {#if strength}
                    {strength} password
                    {/if}
                    ``` ### Validation Combine with custom validation logic to show real-time feedback. Use the `invalid` prop to indicate validation errors. **Example: with-validation** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import { useMemo, useState } from 'react' import styles from 'styles/password-input.module.css' export const WithValidation = () => { const [password, setPassword] = useState('') const isValid = useMemo(() => password.length >= 8, [password]) return ( 0}> Password (min 8 characters) setPassword(e.target.value)} placeholder="Enter your password" /> }> {password.length > 0 && !isValid && (

                    Password must be at least 8 characters

                    )} {isValid && password.length > 0 && (

                    Password is valid

                    )}
                    ) } ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import { createMemo, createSignal } from 'solid-js' import styles from 'styles/password-input.module.css' export const WithValidation = () => { const [password, setPassword] = createSignal('') const isValid = createMemo(() => password().length >= 8) return ( 0}> Password (min 8 characters) setPassword(e.currentTarget.value)} placeholder="Enter your password" /> }> {password().length > 0 && !isValid() && (

                    Password must be at least 8 characters

                    )} {isValid() && password().length > 0 && (

                    Password is valid

                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte 0}> Password (min 8 characters) (password = e.currentTarget.value)} placeholder="Enter your password" /> {#snippet fallback()} {/snippet} {#if password.length > 0 && !isValid}

                    Password must be at least 8 characters

                    {/if} {#if isValid && password.length > 0}

                    Password is valid

                    {/if}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoComplete` | `'current-password' | 'new-password'` | No | The autocomplete attribute for the password input. | | `defaultVisible` | `boolean` | No | The default visibility of the password input. | | `disabled` | `boolean` | No | Whether the password input is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ input: string; visibilityTrigger: string }>` | No | The ids of the password input parts | | `ignorePasswordManagers` | `boolean` | No | When `true`, the input will ignore password managers. **Only works for the following password managers** - 1Password, LastPass, Bitwarden, Dashlane, Proton Pass | | `invalid` | `boolean` | No | The invalid state of the password input. | | `name` | `string` | No | The name of the password input. | | `onVisibilityChange` | `(details: VisibilityChangeDetails) => void` | No | Function called when the visibility changes. | | `readOnly` | `boolean` | No | Whether the password input is read only. | | `required` | `boolean` | No | Whether the password input is required. | | `translations` | `Partial<{ visibilityTrigger: ((visible: boolean) => string) | undefined }>` | No | The localized messages to use. | | `visible` | `boolean` | No | Whether the password input is visible. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | The fallback content to display when the password is not visible. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | indicator | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | input | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePasswordInputReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | visibility-trigger | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-state]` | "visible" | "hidden" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoComplete` | `'current-password' | 'new-password'` | No | The autocomplete attribute for the password input. | | `defaultVisible` | `boolean` | No | The default visibility of the password input. | | `disabled` | `boolean` | No | Whether the password input is disabled. | | `ids` | `Partial<{ input: string; visibilityTrigger: string }>` | No | The ids of the password input parts | | `ignorePasswordManagers` | `boolean` | No | When `true`, the input will ignore password managers. **Only works for the following password managers** - 1Password, LastPass, Bitwarden, Dashlane, Proton Pass | | `invalid` | `boolean` | No | The invalid state of the password input. | | `name` | `string` | No | The name of the password input. | | `onVisibilityChange` | `(details: VisibilityChangeDetails) => void` | No | Function called when the visibility changes. | | `readOnly` | `boolean` | No | Whether the password input is read only. | | `required` | `boolean` | No | Whether the password input is required. | | `translations` | `Partial<{ visibilityTrigger: ((visible: boolean) => string) | undefined }>` | No | The localized messages to use. | | `visible` | `boolean` | No | Whether the password input is visible. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `number | boolean | Node | ArrayElement | (string & {})` | No | The fallback content to display when the password is not visible. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | indicator | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | input | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePasswordInputContext` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | visibility-trigger | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-state]` | "visible" | "hidden" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoComplete` | `'current-password' | 'new-password'` | No | The autocomplete attribute for the input | | `defaultVisible` | `boolean` | No | Whether the password is visible by default | | `disabled` | `boolean` | No | Whether the input is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ input: string; visibilityTrigger: string }>` | No | The ids of the elements in the password input. Useful for composition. | | `ignorePasswordManagers` | `boolean` | No | Whether to ignore password managers | | `invalid` | `boolean` | No | Whether the input is in an invalid state | | `name` | `string` | No | The name attribute for the input | | `readOnly` | `boolean` | No | Whether the input is read-only | | `required` | `boolean` | No | Whether the input is required | | `translations` | `Partial<{ visibilityTrigger: ((visible: boolean) => string) | undefined }>` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `visible` | `boolean` | No | Whether the password is visible | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePasswordInputReturn` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `string` | No | The fallback content to display when the password is not visible. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | indicator | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | input | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PasswordInputApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | visibility-trigger | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-state]` | "visible" | "hidden" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoComplete` | `'current-password' | 'new-password'` | No | The autocomplete attribute for the password input. | | `defaultVisible` | `boolean` | No | The default visibility of the password input. | | `disabled` | `boolean` | No | Whether the password input is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ input: string; visibilityTrigger: string }>` | No | The ids of the password input parts | | `ignorePasswordManagers` | `boolean` | No | When `true`, the input will ignore password managers. **Only works for the following password managers** - 1Password, LastPass, Bitwarden, Dashlane, Proton Pass | | `invalid` | `boolean` | No | The invalid state of the password input. | | `name` | `string` | No | The name of the password input. | | `onVisibilityChange` | `(details: VisibilityChangeDetails) => void` | No | Function called when the visibility changes. | | `readOnly` | `boolean` | No | Whether the password input is read only. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the password input is required. | | `translations` | `Partial<{ visibilityTrigger: ((visible: boolean) => string) | undefined }>` | No | The localized messages to use. | | `visible` | `boolean` | No | Whether the password input is visible. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePasswordInputContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `Snippet<[]>` | No | The fallback content to display when the password is not visible. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | indicator | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | input | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePasswordInputReturn` | Yes | | | `ref` | `Element` | No | | **VisibilityTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **VisibilityTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | visibility-trigger | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-state]` | "visible" | "hidden" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `visible` | `boolean` | Whether the password input is visible. | | `disabled` | `boolean` | Whether the password input is disabled. | | `invalid` | `boolean` | Whether the password input is invalid. | | `focus` | `VoidFunction` | Focus the password input. | | `setVisible` | `(value: boolean) => void` | Set the visibility of the password input. | | `toggleVisible` | `VoidFunction` | Toggle the visibility of the password input. | --- # Password Input (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import styles from 'styles/password-input.module.css' export const Basic = () => ( Password }> ) ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import styles from 'styles/password-input.module.css' export const Basic = () => ( Password }> ) ``` #### Vue ```vue ``` #### Svelte ```svelte Password {#snippet fallback()} {/snippet} ``` ### 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. **Example: autocomplete** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import styles from 'styles/password-input.module.css' export const Autocomplete = () => ( Password }> ) ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import styles from 'styles/password-input.module.css' export const Autocomplete = () => ( Password }> ) ``` #### Vue ```vue ``` #### Svelte ```svelte Password {#snippet fallback()} {/snippet} ``` ### Controlled Visibility Use the `visible` and `onVisibilityChange` props to control the visibility of the password input. **Example: controlled-visibility** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/password-input.module.css' export const ControlledVisibility = () => { const [visible, setVisible] = useState(false) return ( setVisible(e.visible)}> Password is {visible ? 'visible' : 'hidden'} }> ) } ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/password-input.module.css' export const ControlledVisibility = () => { const [visible, setVisible] = createSignal(false) return ( setVisible(e.visible)}> Password is {visible() ? 'visible' : 'hidden'} }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Password is {visible ? 'visible' : 'hidden'} {#snippet fallback()} {/snippet} ``` ### 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. **Example: root-provider** #### React ```tsx import { PasswordInput, usePasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import styles from 'styles/password-input.module.css' export const RootProvider = () => { const passwordInput = usePasswordInput() return (
                    password input is {passwordInput.visible ? 'visible' : 'hidden'} Password }>
                    ) } ``` #### Solid ```tsx import { PasswordInput, usePasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import styles from 'styles/password-input.module.css' export const RootProvider = () => { const passwordInput = usePasswordInput() return (
                    password input is {passwordInput().visible ? 'visible' : 'hidden'} Password }>
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    password input is {passwordInput().visible ? 'visible' : 'hidden'} Password {#snippet fallback()} {/snippet}
                    ``` ### Field Here's an example of how to use the `PasswordInput` component with the `Field` component. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/password-input.module.css' export const WithField = () => ( Password }> Enter your password Password is required ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import field from 'styles/field.module.css' import styles from 'styles/password-input.module.css' export const WithField = () => ( Password }> Enter your password Password is required ) ``` #### Vue ```vue ``` #### Svelte ```svelte Password {#snippet fallback()} {/snippet} Enter your password Password is required ``` ### Password Managers Use the `ignorePasswordManager` prop to ignore password managers like 1Password, LastPass, etc. This is useful for non-login scenarios (e.g., "api keys", "secure notes", "temporary passwords") > **Currently, this only works for 1Password, LastPass, Bitwarden, Dashlane, and Proton Pass.** **Example: ignore-password-manager** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import styles from 'styles/password-input.module.css' export const IgnorePasswordManager = () => ( API Key }> ) ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import styles from 'styles/password-input.module.css' export const IgnorePasswordManager = () => ( API Key }> ) ``` #### Vue ```vue ``` #### Svelte ```svelte API Key {#snippet fallback()} {/snippet} ``` ### Strength Meter Combine the `PasswordInput` with a password strength library to show visual feedback about password strength. This example uses the [`check-password-strength`](https://www.npmjs.com/package/check-password-strength) package to provide real-time strength validation. **Example: strength-meter** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { passwordStrength, type Options } from 'check-password-strength' import { EyeIcon, EyeOffIcon } from 'lucide-react' import { useMemo, useState } from 'react' import styles from 'styles/password-input.module.css' const strengthOptions: Options = [ { id: 0, value: 'weak', minDiversity: 0, minLength: 0 }, { id: 1, value: 'medium', minDiversity: 2, minLength: 6 }, { id: 2, value: 'strong', minDiversity: 4, minLength: 8 }, ] export const StrengthMeter = () => { const [password, setPassword] = useState('asdfasdf') const strength = useMemo(() => { if (!password) return null const { value } = passwordStrength(password, strengthOptions) return value }, [password]) return ( Password setPassword(e.currentTarget.value)} placeholder="Enter your password" /> }> {strength && (
                    {strength} password
                    )} ) } ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { passwordStrength, type Options } from 'check-password-strength' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import { createMemo, createSignal, Show } from 'solid-js' import styles from 'styles/password-input.module.css' const strengthOptions: Options = [ { id: 0, value: 'weak', minDiversity: 0, minLength: 0 }, { id: 1, value: 'medium', minDiversity: 2, minLength: 6 }, { id: 2, value: 'strong', minDiversity: 4, minLength: 8 }, ] export const StrengthMeter = () => { const [password, setPassword] = createSignal('asdfasdf') const strength = createMemo(() => { if (!password()) return null const { value } = passwordStrength(password(), strengthOptions) return value }) return ( Password setPassword(e.currentTarget.value)} placeholder="Enter your password" /> }> {(value) => (
                    {value()} password
                    )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Password {#snippet fallback()} {/snippet} {#if strength}
                    {strength} password
                    {/if}
                    ``` ### Validation Combine with custom validation logic to show real-time feedback. Use the `invalid` prop to indicate validation errors. **Example: with-validation** #### React ```tsx import { PasswordInput } from '@ark-ui/react/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-react' import { useMemo, useState } from 'react' import styles from 'styles/password-input.module.css' export const WithValidation = () => { const [password, setPassword] = useState('') const isValid = useMemo(() => password.length >= 8, [password]) return ( 0}> Password (min 8 characters) setPassword(e.target.value)} placeholder="Enter your password" /> }> {password.length > 0 && !isValid && (

                    Password must be at least 8 characters

                    )} {isValid && password.length > 0 && (

                    Password is valid

                    )}
                    ) } ``` #### Solid ```tsx import { PasswordInput } from '@ark-ui/solid/password-input' import { EyeIcon, EyeOffIcon } from 'lucide-solid' import { createMemo, createSignal } from 'solid-js' import styles from 'styles/password-input.module.css' export const WithValidation = () => { const [password, setPassword] = createSignal('') const isValid = createMemo(() => password().length >= 8) return ( 0}> Password (min 8 characters) setPassword(e.currentTarget.value)} placeholder="Enter your password" /> }> {password().length > 0 && !isValid() && (

                    Password must be at least 8 characters

                    )} {isValid() && password().length > 0 && (

                    Password is valid

                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte 0}> Password (min 8 characters) (password = e.currentTarget.value)} placeholder="Enter your password" /> {#snippet fallback()} {/snippet} {#if password.length > 0 && !isValid}

                    Password must be at least 8 characters

                    {/if} {#if isValid && password.length > 0}

                    Password is valid

                    {/if}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoComplete` | `'current-password' | 'new-password'` | No | The autocomplete attribute for the password input. | | `defaultVisible` | `boolean` | No | The default visibility of the password input. | | `disabled` | `boolean` | No | Whether the password input is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ input: string; visibilityTrigger: string }>` | No | The ids of the password input parts | | `ignorePasswordManagers` | `boolean` | No | When `true`, the input will ignore password managers. **Only works for the following password managers** - 1Password, LastPass, Bitwarden, Dashlane, Proton Pass | | `invalid` | `boolean` | No | The invalid state of the password input. | | `name` | `string` | No | The name of the password input. | | `onVisibilityChange` | `(details: VisibilityChangeDetails) => void` | No | Function called when the visibility changes. | | `readOnly` | `boolean` | No | Whether the password input is read only. | | `required` | `boolean` | No | Whether the password input is required. | | `translations` | `Partial<{ visibilityTrigger: ((visible: boolean) => string) | undefined }>` | No | The localized messages to use. | | `visible` | `boolean` | No | Whether the password input is visible. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | The fallback content to display when the password is not visible. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | indicator | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | input | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePasswordInputReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | visibility-trigger | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-state]` | "visible" | "hidden" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoComplete` | `'current-password' | 'new-password'` | No | The autocomplete attribute for the password input. | | `defaultVisible` | `boolean` | No | The default visibility of the password input. | | `disabled` | `boolean` | No | Whether the password input is disabled. | | `ids` | `Partial<{ input: string; visibilityTrigger: string }>` | No | The ids of the password input parts | | `ignorePasswordManagers` | `boolean` | No | When `true`, the input will ignore password managers. **Only works for the following password managers** - 1Password, LastPass, Bitwarden, Dashlane, Proton Pass | | `invalid` | `boolean` | No | The invalid state of the password input. | | `name` | `string` | No | The name of the password input. | | `onVisibilityChange` | `(details: VisibilityChangeDetails) => void` | No | Function called when the visibility changes. | | `readOnly` | `boolean` | No | Whether the password input is read only. | | `required` | `boolean` | No | Whether the password input is required. | | `translations` | `Partial<{ visibilityTrigger: ((visible: boolean) => string) | undefined }>` | No | The localized messages to use. | | `visible` | `boolean` | No | Whether the password input is visible. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `number | boolean | Node | ArrayElement | (string & {})` | No | The fallback content to display when the password is not visible. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | indicator | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | input | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePasswordInputContext` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | visibility-trigger | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-state]` | "visible" | "hidden" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoComplete` | `'current-password' | 'new-password'` | No | The autocomplete attribute for the input | | `defaultVisible` | `boolean` | No | Whether the password is visible by default | | `disabled` | `boolean` | No | Whether the input is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ input: string; visibilityTrigger: string }>` | No | The ids of the elements in the password input. Useful for composition. | | `ignorePasswordManagers` | `boolean` | No | Whether to ignore password managers | | `invalid` | `boolean` | No | Whether the input is in an invalid state | | `name` | `string` | No | The name attribute for the input | | `readOnly` | `boolean` | No | Whether the input is read-only | | `required` | `boolean` | No | Whether the input is required | | `translations` | `Partial<{ visibilityTrigger: ((visible: boolean) => string) | undefined }>` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `visible` | `boolean` | No | Whether the password is visible | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePasswordInputReturn` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `string` | No | The fallback content to display when the password is not visible. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | indicator | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | input | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PasswordInputApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **VisibilityTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | visibility-trigger | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-state]` | "visible" | "hidden" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoComplete` | `'current-password' | 'new-password'` | No | The autocomplete attribute for the password input. | | `defaultVisible` | `boolean` | No | The default visibility of the password input. | | `disabled` | `boolean` | No | Whether the password input is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ input: string; visibilityTrigger: string }>` | No | The ids of the password input parts | | `ignorePasswordManagers` | `boolean` | No | When `true`, the input will ignore password managers. **Only works for the following password managers** - 1Password, LastPass, Bitwarden, Dashlane, Proton Pass | | `invalid` | `boolean` | No | The invalid state of the password input. | | `name` | `string` | No | The name of the password input. | | `onVisibilityChange` | `(details: VisibilityChangeDetails) => void` | No | Function called when the visibility changes. | | `readOnly` | `boolean` | No | Whether the password input is read only. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the password input is required. | | `translations` | `Partial<{ visibilityTrigger: ((visible: boolean) => string) | undefined }>` | No | The localized messages to use. | | `visible` | `boolean` | No | Whether the password input is visible. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePasswordInputContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `Snippet<[]>` | No | The fallback content to display when the password is not visible. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | indicator | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | input | | `[data-state]` | "visible" | "hidden" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePasswordInputReturn` | Yes | | | `ref` | `Element` | No | | **VisibilityTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **VisibilityTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | password-input | | `[data-part]` | visibility-trigger | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-state]` | "visible" | "hidden" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `visible` | `boolean` | Whether the password input is visible. | | `disabled` | `boolean` | Whether the password input is disabled. | | `invalid` | `boolean` | Whether the password input is invalid. | | `focus` | `VoidFunction` | Focus the password input. | | `setVisible` | `(value: boolean) => void` | Set the visibility of the password input. | | `toggleVisible` | `VoidFunction` | Toggle the visibility of the password input. | --- # Pin Input (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const Basic = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const Basic = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### Placeholder To customize the default pin input placeholder `○` for each input, pass the placeholder prop and set it to your desired value. **Example: custom-placeholder** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const CustomPlaceholder = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const CustomPlaceholder = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### 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`. **Example: blur-on-complete** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const BlurOnComplete = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const BlurOnComplete = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### 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. **Example: otp-mode** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const OTPMode = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const OTPMode = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### 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`. **Example: mask** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const Mask = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const Mask = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### Change Events The pin input component invokes several callback functions when the user enters: - `onValueChange` — Callback invoked when the value is changed. - `onValueComplete` — Callback invoked when all fields have been completed (by typing or pasting). - `onValueInvalid` — Callback invoked when an invalid value is entered into the input. An invalid value is any value that doesn't match the specified "type". ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { PinInput } from '@ark-ui/react/pin-input' import fieldStyles from 'styles/field.module.css' import styles from 'styles/pin-input.module.css' export const WithField = () => ( Label {[0, 1, 2].map((id, index) => ( ))} Additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import fieldStyles from 'styles/field.module.css' import styles from 'styles/pin-input.module.css' export const WithField = () => ( Label {(id) => } Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} Additional Info Error Info ``` ### 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. **Example: root-provider** #### React ```tsx import { PinInput, usePinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const RootProvider = () => { const pinInput = usePinInput({ onValueComplete: (e) => alert(e.valueAsString) }) return (
                    Label {[0, 1, 2].map((id, index) => ( ))}
                    ) } ``` #### Solid ```tsx import { PinInput, usePinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const RootProvider = () => { const pinInput = usePinInput({ onValueComplete: (e) => alert(e.valueAsString) }) return (
                    Label {(id) => }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label {#each [0, 1, 2] as id, index (id)} {/each}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input: (id: string) => string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called on input change | | `onValueComplete` | `(details: ValueChangeDetails) => void` | No | Function called when all inputs have valid values | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function called when an invalid value is entered | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphanumeric' | 'alphabetic'` | No | The type of value the pin-input should allow | | `value` | `string[]` | No | The controlled value of the the pin input. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-required]` | Present when required | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePinInputReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input: (id: string) => string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called on input change | | `onValueComplete` | `(details: ValueChangeDetails) => void` | No | Function called when all inputs have valid values | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function called when an invalid value is entered | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphanumeric' | 'alphabetic'` | No | The type of value the pin-input should allow | | `value` | `string[]` | No | The controlled value of the the pin input. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-required]` | Present when required | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePinInputReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input(id: string): string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `modelValue` | `string[]` | No | The v-model value of the pin input | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphanumeric' | 'alphabetic'` | No | The type of value the pin-input should allow | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-required]` | Present when required | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PinInputApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input: (id: string) => string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called on input change | | `onValueComplete` | `(details: ValueChangeDetails) => void` | No | Function called when all inputs have valid values | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function called when an invalid value is entered | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphanumeric' | 'alphabetic'` | No | The type of value the pin-input should allow | | `value` | `string[]` | No | The controlled value of the the pin input. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePinInputContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-required]` | Present when required | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePinInputReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string[]` | The value of the input as an array of strings. | | `valueAsString` | `string` | The value of the input as a string. | | `complete` | `boolean` | Whether all inputs are filled. | | `count` | `number` | The number of inputs to render | | `items` | `number[]` | The array of input values. | | `setValue` | `(value: string[]) => void` | Function to set the value of the inputs. | | `clearValue` | `VoidFunction` | Function to clear the value of the inputs. | | `setValueAtIndex` | `(index: number, value: string) => void` | Function to set the value of the input at a specific index. | | `focus` | `VoidFunction` | Function to focus the pin-input. This will focus the first input. | ## Accessibility ### Keyboard Support **`ArrowLeft`** Description: Moves focus to the previous input **`ArrowRight`** Description: Moves focus to the next input **`Backspace`** Description: Deletes the value in the current input and moves focus to the previous input **`Delete`** Description: Deletes the value in the current input **`Control + V`** Description: Pastes the value into the input fields --- # Pin Input (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const Basic = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const Basic = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### Placeholder To customize the default pin input placeholder `○` for each input, pass the placeholder prop and set it to your desired value. **Example: custom-placeholder** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const CustomPlaceholder = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const CustomPlaceholder = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### 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`. **Example: blur-on-complete** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const BlurOnComplete = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const BlurOnComplete = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### 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. **Example: otp-mode** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const OTPMode = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const OTPMode = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### 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`. **Example: mask** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const Mask = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const Mask = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### Change Events The pin input component invokes several callback functions when the user enters: - `onValueChange` — Callback invoked when the value is changed. - `onValueComplete` — Callback invoked when all fields have been completed (by typing or pasting). - `onValueInvalid` — Callback invoked when an invalid value is entered into the input. An invalid value is any value that doesn't match the specified "type". ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { PinInput } from '@ark-ui/react/pin-input' import fieldStyles from 'styles/field.module.css' import styles from 'styles/pin-input.module.css' export const WithField = () => ( Label {[0, 1, 2].map((id, index) => ( ))} Additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import fieldStyles from 'styles/field.module.css' import styles from 'styles/pin-input.module.css' export const WithField = () => ( Label {(id) => } Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} Additional Info Error Info ``` ### 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. **Example: root-provider** #### React ```tsx import { PinInput, usePinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const RootProvider = () => { const pinInput = usePinInput({ onValueComplete: (e) => alert(e.valueAsString) }) return (
                    Label {[0, 1, 2].map((id, index) => ( ))}
                    ) } ``` #### Solid ```tsx import { PinInput, usePinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const RootProvider = () => { const pinInput = usePinInput({ onValueComplete: (e) => alert(e.valueAsString) }) return (
                    Label {(id) => }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label {#each [0, 1, 2] as id, index (id)} {/each}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input: (id: string) => string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called on input change | | `onValueComplete` | `(details: ValueChangeDetails) => void` | No | Function called when all inputs have valid values | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function called when an invalid value is entered | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphanumeric' | 'alphabetic'` | No | The type of value the pin-input should allow | | `value` | `string[]` | No | The controlled value of the the pin input. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-required]` | Present when required | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePinInputReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input: (id: string) => string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called on input change | | `onValueComplete` | `(details: ValueChangeDetails) => void` | No | Function called when all inputs have valid values | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function called when an invalid value is entered | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphanumeric' | 'alphabetic'` | No | The type of value the pin-input should allow | | `value` | `string[]` | No | The controlled value of the the pin input. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-required]` | Present when required | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePinInputReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input(id: string): string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `modelValue` | `string[]` | No | The v-model value of the pin input | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphanumeric' | 'alphabetic'` | No | The type of value the pin-input should allow | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-required]` | Present when required | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PinInputApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input: (id: string) => string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called on input change | | `onValueComplete` | `(details: ValueChangeDetails) => void` | No | Function called when all inputs have valid values | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function called when an invalid value is entered | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphanumeric' | 'alphabetic'` | No | The type of value the pin-input should allow | | `value` | `string[]` | No | The controlled value of the the pin input. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePinInputContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-required]` | Present when required | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePinInputReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string[]` | The value of the input as an array of strings. | | `valueAsString` | `string` | The value of the input as a string. | | `complete` | `boolean` | Whether all inputs are filled. | | `count` | `number` | The number of inputs to render | | `items` | `number[]` | The array of input values. | | `setValue` | `(value: string[]) => void` | Function to set the value of the inputs. | | `clearValue` | `VoidFunction` | Function to clear the value of the inputs. | | `setValueAtIndex` | `(index: number, value: string) => void` | Function to set the value of the input at a specific index. | | `focus` | `VoidFunction` | Function to focus the pin-input. This will focus the first input. | ## Accessibility ### Keyboard Support **`ArrowLeft`** Description: Moves focus to the previous input **`ArrowRight`** Description: Moves focus to the next input **`Backspace`** Description: Deletes the value in the current input and moves focus to the previous input **`Delete`** Description: Deletes the value in the current input **`Control + V`** Description: Pastes the value into the input fields --- # Pin Input (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const Basic = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const Basic = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### Placeholder To customize the default pin input placeholder `○` for each input, pass the placeholder prop and set it to your desired value. **Example: custom-placeholder** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const CustomPlaceholder = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const CustomPlaceholder = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### 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`. **Example: blur-on-complete** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const BlurOnComplete = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const BlurOnComplete = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### 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. **Example: otp-mode** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const OTPMode = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const OTPMode = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### 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`. **Example: mask** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const Mask = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const Mask = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### Change Events The pin input component invokes several callback functions when the user enters: - `onValueChange` — Callback invoked when the value is changed. - `onValueComplete` — Callback invoked when all fields have been completed (by typing or pasting). - `onValueInvalid` — Callback invoked when an invalid value is entered into the input. An invalid value is any value that doesn't match the specified "type". ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { PinInput } from '@ark-ui/react/pin-input' import fieldStyles from 'styles/field.module.css' import styles from 'styles/pin-input.module.css' export const WithField = () => ( Label {[0, 1, 2].map((id, index) => ( ))} Additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import fieldStyles from 'styles/field.module.css' import styles from 'styles/pin-input.module.css' export const WithField = () => ( Label {(id) => } Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} Additional Info Error Info ``` ### 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. **Example: root-provider** #### React ```tsx import { PinInput, usePinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const RootProvider = () => { const pinInput = usePinInput({ onValueComplete: (e) => alert(e.valueAsString) }) return (
                    Label {[0, 1, 2].map((id, index) => ( ))}
                    ) } ``` #### Solid ```tsx import { PinInput, usePinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const RootProvider = () => { const pinInput = usePinInput({ onValueComplete: (e) => alert(e.valueAsString) }) return (
                    Label {(id) => }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label {#each [0, 1, 2] as id, index (id)} {/each}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input: (id: string) => string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called on input change | | `onValueComplete` | `(details: ValueChangeDetails) => void` | No | Function called when all inputs have valid values | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function called when an invalid value is entered | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphanumeric' | 'alphabetic'` | No | The type of value the pin-input should allow | | `value` | `string[]` | No | The controlled value of the the pin input. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-required]` | Present when required | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePinInputReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input: (id: string) => string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called on input change | | `onValueComplete` | `(details: ValueChangeDetails) => void` | No | Function called when all inputs have valid values | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function called when an invalid value is entered | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphanumeric' | 'alphabetic'` | No | The type of value the pin-input should allow | | `value` | `string[]` | No | The controlled value of the the pin input. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-required]` | Present when required | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePinInputReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input(id: string): string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `modelValue` | `string[]` | No | The v-model value of the pin input | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphanumeric' | 'alphabetic'` | No | The type of value the pin-input should allow | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-required]` | Present when required | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PinInputApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input: (id: string) => string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called on input change | | `onValueComplete` | `(details: ValueChangeDetails) => void` | No | Function called when all inputs have valid values | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function called when an invalid value is entered | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphanumeric' | 'alphabetic'` | No | The type of value the pin-input should allow | | `value` | `string[]` | No | The controlled value of the the pin input. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePinInputContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-required]` | Present when required | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePinInputReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string[]` | The value of the input as an array of strings. | | `valueAsString` | `string` | The value of the input as a string. | | `complete` | `boolean` | Whether all inputs are filled. | | `count` | `number` | The number of inputs to render | | `items` | `number[]` | The array of input values. | | `setValue` | `(value: string[]) => void` | Function to set the value of the inputs. | | `clearValue` | `VoidFunction` | Function to clear the value of the inputs. | | `setValueAtIndex` | `(index: number, value: string) => void` | Function to set the value of the input at a specific index. | | `focus` | `VoidFunction` | Function to focus the pin-input. This will focus the first input. | ## Accessibility ### Keyboard Support **`ArrowLeft`** Description: Moves focus to the previous input **`ArrowRight`** Description: Moves focus to the next input **`Backspace`** Description: Deletes the value in the current input and moves focus to the previous input **`Delete`** Description: Deletes the value in the current input **`Control + V`** Description: Pastes the value into the input fields --- # Pin Input (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const Basic = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const Basic = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### Placeholder To customize the default pin input placeholder `○` for each input, pass the placeholder prop and set it to your desired value. **Example: custom-placeholder** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const CustomPlaceholder = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const CustomPlaceholder = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### 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`. **Example: blur-on-complete** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const BlurOnComplete = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const BlurOnComplete = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### 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. **Example: otp-mode** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const OTPMode = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const OTPMode = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### 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`. **Example: mask** #### React ```tsx import { PinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const Mask = () => ( Label {[0, 1, 2].map((id, index) => ( ))} ) ``` #### Solid ```tsx import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const Mask = () => ( Label {(id) => } ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} ``` ### Change Events The pin input component invokes several callback functions when the user enters: - `onValueChange` — Callback invoked when the value is changed. - `onValueComplete` — Callback invoked when all fields have been completed (by typing or pasting). - `onValueInvalid` — Callback invoked when an invalid value is entered into the input. An invalid value is any value that doesn't match the specified "type". ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { PinInput } from '@ark-ui/react/pin-input' import fieldStyles from 'styles/field.module.css' import styles from 'styles/pin-input.module.css' export const WithField = () => ( Label {[0, 1, 2].map((id, index) => ( ))} Additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { PinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import fieldStyles from 'styles/field.module.css' import styles from 'styles/pin-input.module.css' export const WithField = () => ( Label {(id) => } Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each [0, 1, 2] as id, index (id)} {/each} Additional Info Error Info ``` ### 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. **Example: root-provider** #### React ```tsx import { PinInput, usePinInput } from '@ark-ui/react/pin-input' import styles from 'styles/pin-input.module.css' export const RootProvider = () => { const pinInput = usePinInput({ onValueComplete: (e) => alert(e.valueAsString) }) return (
                    Label {[0, 1, 2].map((id, index) => ( ))}
                    ) } ``` #### Solid ```tsx import { PinInput, usePinInput } from '@ark-ui/solid/pin-input' import { Index } from 'solid-js' import styles from 'styles/pin-input.module.css' export const RootProvider = () => { const pinInput = usePinInput({ onValueComplete: (e) => alert(e.valueAsString) }) return (
                    Label {(id) => }
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label {#each [0, 1, 2] as id, index (id)} {/each}
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input: (id: string) => string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called on input change | | `onValueComplete` | `(details: ValueChangeDetails) => void` | No | Function called when all inputs have valid values | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function called when an invalid value is entered | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphanumeric' | 'alphabetic'` | No | The type of value the pin-input should allow | | `value` | `string[]` | No | The controlled value of the the pin input. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-required]` | Present when required | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePinInputReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input: (id: string) => string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called on input change | | `onValueComplete` | `(details: ValueChangeDetails) => void` | No | Function called when all inputs have valid values | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function called when an invalid value is entered | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphanumeric' | 'alphabetic'` | No | The type of value the pin-input should allow | | `value` | `string[]` | No | The controlled value of the the pin input. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-required]` | Present when required | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePinInputReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input(id: string): string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `modelValue` | `string[]` | No | The v-model value of the pin input | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphanumeric' | 'alphabetic'` | No | The type of value the pin-input should allow | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-required]` | Present when required | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PinInputApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to auto-focus the first input. | | `blurOnComplete` | `boolean` | No | Whether to blur the input when the value is complete | | `count` | `number` | No | The number of inputs to render to improve SSR aria attributes. This will be required in next major version. | | `defaultValue` | `string[]` | No | The initial value of the the pin input when rendered. Use when you don't need to control the value of the pin input. | | `disabled` | `boolean` | No | Whether the inputs are disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string hiddenInput: string label: string control: string input: (id: string) => string }>` | No | The ids of the elements in the pin input. Useful for composition. | | `invalid` | `boolean` | No | Whether the pin input is in the invalid state | | `mask` | `boolean` | No | If `true`, the input's value will be masked just like `type=password` | | `name` | `string` | No | The name of the input element. Useful for form submission. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called on input change | | `onValueComplete` | `(details: ValueChangeDetails) => void` | No | Function called when all inputs have valid values | | `onValueInvalid` | `(details: ValueInvalidDetails) => void` | No | Function called when an invalid value is entered | | `otp` | `boolean` | No | If `true`, the pin input component signals to its fields that they should use `autocomplete="one-time-code"`. | | `pattern` | `string` | No | The regular expression that the user-entered input value is checked against. | | `placeholder` | `string` | No | The placeholder text for the input | | `readOnly` | `boolean` | No | Whether the pin input is in the valid state | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the pin input is required | | `selectOnFocus` | `boolean` | No | Whether to select input value when input is focused | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `type` | `'numeric' | 'alphanumeric' | 'alphabetic'` | No | The type of value the pin-input should allow | | `value` | `string[]` | No | The controlled value of the the pin input. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the pin-input value is complete | | `[data-readonly]` | Present when read-only | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePinInputContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | input | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the input value is complete | | `[data-index]` | The index of the item | | `[data-invalid]` | Present when invalid | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pin-input | | `[data-part]` | label | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-complete]` | Present when the label value is complete | | `[data-required]` | Present when required | | `[data-readonly]` | Present when read-only | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePinInputReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string[]` | The value of the input as an array of strings. | | `valueAsString` | `string` | The value of the input as a string. | | `complete` | `boolean` | Whether all inputs are filled. | | `count` | `number` | The number of inputs to render | | `items` | `number[]` | The array of input values. | | `setValue` | `(value: string[]) => void` | Function to set the value of the inputs. | | `clearValue` | `VoidFunction` | Function to clear the value of the inputs. | | `setValueAtIndex` | `(index: number, value: string) => void` | Function to set the value of the input at a specific index. | | `focus` | `VoidFunction` | Function to focus the pin-input. This will focus the first input. | ## Accessibility ### Keyboard Support **`ArrowLeft`** Description: Moves focus to the previous input **`ArrowRight`** Description: Moves focus to the next input **`Backspace`** Description: Deletes the value in the current input and moves focus to the previous input **`Delete`** Description: Deletes the value in the current input **`Control + V`** Description: Pastes the value into the input fields --- # Popover (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Basic = () => ( Click Me Favorite Frameworks Manage and organize your favorite web frameworks. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Basic = () => ( Click Me Favorite Frameworks Manage and organize your favorite web frameworks. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Favorite Frameworks Manage and organize your favorite web frameworks. ``` ### Controlled Use the `open` and `onOpenChange` props to control the open state of the popover. **Example: controlled** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return ( setOpen(e.open)}> Click Me Team Members Invite colleagues to collaborate on this project. ) } ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return ( setOpen(e.open)}> Click Me Team Members Invite colleagues to collaborate on this project. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Team Members Invite colleagues to collaborate on this project. ``` ### 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. **Example: root-provider** #### React ```tsx import { Popover, usePopover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const RootProvider = () => { const popover = usePopover({ positioning: { placement: 'bottom-start', }, }) return (
                    Controlled Externally This popover is controlled via the usePopover hook.
                    ) } ``` #### Solid ```tsx import { Popover, usePopover } from '@ark-ui/solid/popover' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const RootProvider = () => { const popover = usePopover() return (
                    Controlled Externally This popover is controlled via the usePopover hook.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Controlled Externally This popover is controlled via the usePopover hook.
                    ``` ### Arrow Use `Popover.Arrow` and `Popover.ArrowTip` to render an arrow pointing to the trigger. **Example: arrow** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Arrow = () => ( Click Me Notifications You have 3 unread messages in your inbox. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Arrow = () => ( Click Me Notifications You have 3 unread messages in your inbox. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Notifications You have 3 unread messages in your inbox. ``` ### Placement To change the placement of the popover, set the `positioning` prop. **Example: positioning** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Positioning = () => ( Click Me Left Placement This popover appears on the left with custom offset values. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Positioning = () => ( Click Me Left Placement This popover appears on the left with custom offset values. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Left Placement This popover appears on the left with custom offset values. ``` ### 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`. **Example: close-behavior** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const CloseBehavior = () => ( Click Me Quick Actions Press Escape or click outside to close this popover. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const CloseBehavior = () => ( Click Me Quick Actions Press Escape or click outside to close this popover. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Quick Actions Press Escape or click outside to close this popover. ``` ### 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 - hide content behind the popover from screen readers To make the popover modal, set the `modal` prop to `true`. When `modal={true}`, we set the `portalled` attribute to `true` as well. **Example: modal** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Modal = () => ( Click Me Confirm Action Focus is trapped inside this modal popover until dismissed. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Modal = () => ( Click Me Confirm Action Focus is trapped inside this modal popover until dismissed. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Confirm Action Focus is trapped inside this modal popover until dismissed. ``` ### Anchor Use `Popover.Anchor` to position the popover relative to a different element than the trigger. **Example: anchor** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import field from 'styles/field.module.css' import styles from 'styles/popover.module.css' export const Anchor = () => { return (
                    Click Me
                    Title Description
                    ) } ``` ### Same Width Use `positioning.sameWidth` to make the popover match the width of its trigger element. **Example: same-width** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const SameWidth = () => { return ( Click Me Matched Width This popover matches the width of its trigger element. ) } ``` ### Dialog Integration When rendering a popover inside a dialog, you have two options for proper layering: 1. **Keep the Portal with `lazyMount` and `unmountOnExit`** - This ensures the popover is properly unmounted when the dialog closes, preventing stale DOM nodes. 2. **Remove the Portal** - Render the popover inline within the dialog content. This works well but may have z-index considerations. **Example: with-dialog** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/popover.module.css' export const WithDialog = () => ( Open Dialog Edit Profile Update your profile information below.
                    More Options Additional Settings This popover renders correctly above the dialog.
                    ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/popover.module.css' export const WithDialog = () => ( Open Dialog Edit Profile Update your profile information below.
                    More Options Additional Settings This popover renders correctly above the dialog.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Edit Profile Update your profile information below.
                    More Options Additional Settings This popover renders correctly above the dialog.
                    ``` ### Nested Popovers can be nested within each other. Each nested popover maintains its own open state and positioning. **Example: nested** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Nested = () => { return ( Click Me Settings Manage your preferences and account settings. Advanced Advanced Settings Configure advanced options for power users. ) } ``` ## Guides ### Available Size The following css variables are exposed to the `Popover.Positioner` which you can use to style the `Popover.Content` ```css /* width of the popover trigger */ --reference-width: ; /* width of the available viewport */ --available-width: ; /* height of the available viewport */ --available-height: ; ``` For example, if you want to make sure the maximum height doesn't exceed the available height, use the following css: ```css [data-scope='popover'][data-part='content'] { max-height: calc(var(--available-height) - 100px); } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `autoFocus` | `boolean` | No | Whether to automatically set focus on the first focusable content within the popover when opened. | | `closeOnEscape` | `boolean` | No | Whether to close the popover when the escape key is pressed. | | `closeOnInteractOutside` | `boolean` | No | Whether to close the popover when the user clicks outside of the popover. | | `defaultOpen` | `boolean` | No | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ anchor: string trigger: string content: string title: string description: string closeTrigger: string positioner: string arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The element to focus on when the popover is opened. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function invoked when the popover opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the popover | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `portalled` | `boolean` | No | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Anchor Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-expanded]` | Present when expanded | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested popovers | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePopoverReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `autoFocus` | `boolean` | No | Whether to automatically set focus on the first focusable content within the popover when opened. | | `closeOnEscape` | `boolean` | No | Whether to close the popover when the escape key is pressed. | | `closeOnInteractOutside` | `boolean` | No | Whether to close the popover when the user clicks outside of the popover. | | `defaultOpen` | `boolean` | No | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ anchor: string trigger: string content: string title: string description: string closeTrigger: string positioner: string arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The element to focus on when the popover is opened. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function invoked when the popover opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the popover | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `portalled` | `boolean` | No | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Anchor Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-expanded]` | Present when expanded | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested popovers | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePopoverReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `autoFocus` | `boolean` | No | Whether to automatically set focus on the first focusable content within the popover when opened. | | `closeOnEscape` | `boolean` | No | Whether to close the popover when the escape key is pressed. | | `closeOnInteractOutside` | `boolean` | No | Whether to close the popover when the user clicks outside of the popover. | | `defaultOpen` | `boolean` | No | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ anchor: string trigger: string content: string title: string description: string closeTrigger: string positioner: string arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `initialFocusEl` | `() => HTMLElement | null` | No | The element to focus on when the popover is opened. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | | `open` | `boolean` | No | The controlled open state of the popover | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `portalled` | `boolean` | No | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Anchor Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-expanded]` | Present when expanded | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested popovers | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PopoverApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `autoFocus` | `boolean` | No | Whether to automatically set focus on the first focusable content within the popover when opened. | | `closeOnEscape` | `boolean` | No | Whether to close the popover when the escape key is pressed. | | `closeOnInteractOutside` | `boolean` | No | Whether to close the popover when the user clicks outside of the popover. | | `defaultOpen` | `boolean` | No | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ anchor: string trigger: string content: string title: string description: string closeTrigger: string positioner: string arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The element to focus on when the popover is opened. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function invoked when the popover opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the popover | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `portalled` | `boolean` | No | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Anchor Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-expanded]` | Present when expanded | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested popovers | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePopoverContext]>` | No | | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'p'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePopoverReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `portalled` | `boolean` | Whether the popover is portalled. | | `open` | `boolean` | Whether the popover is open | | `setOpen` | `(open: boolean) => void` | Function to open or close the popover | | `reposition` | `(options?: Partial) => void` | Function to reposition the popover | ## Accessibility ### Keyboard Support **`Space`** Description: Opens/closes the popover. **`Enter`** Description: Opens/closes the popover. **`Tab`** Description: Moves focus to the next focusable element within the content.
                    Note: If there are no focusable elements, focus is moved to the next focusable element after the trigger.
                    **`Shift + Tab`** Description: Moves focus to the previous focusable element within the content
                    Note: If there are no focusable elements, focus is moved to the trigger.
                    **`Esc`** Description: Closes the popover and moves focus to the trigger. --- # Popover (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Basic = () => ( Click Me Favorite Frameworks Manage and organize your favorite web frameworks. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Basic = () => ( Click Me Favorite Frameworks Manage and organize your favorite web frameworks. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Favorite Frameworks Manage and organize your favorite web frameworks. ``` ### Controlled Use the `open` and `onOpenChange` props to control the open state of the popover. **Example: controlled** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return ( setOpen(e.open)}> Click Me Team Members Invite colleagues to collaborate on this project. ) } ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return ( setOpen(e.open)}> Click Me Team Members Invite colleagues to collaborate on this project. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Team Members Invite colleagues to collaborate on this project. ``` ### 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. **Example: root-provider** #### React ```tsx import { Popover, usePopover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const RootProvider = () => { const popover = usePopover({ positioning: { placement: 'bottom-start', }, }) return (
                    Controlled Externally This popover is controlled via the usePopover hook.
                    ) } ``` #### Solid ```tsx import { Popover, usePopover } from '@ark-ui/solid/popover' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const RootProvider = () => { const popover = usePopover() return (
                    Controlled Externally This popover is controlled via the usePopover hook.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Controlled Externally This popover is controlled via the usePopover hook.
                    ``` ### Arrow Use `Popover.Arrow` and `Popover.ArrowTip` to render an arrow pointing to the trigger. **Example: arrow** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Arrow = () => ( Click Me Notifications You have 3 unread messages in your inbox. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Arrow = () => ( Click Me Notifications You have 3 unread messages in your inbox. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Notifications You have 3 unread messages in your inbox. ``` ### Placement To change the placement of the popover, set the `positioning` prop. **Example: positioning** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Positioning = () => ( Click Me Left Placement This popover appears on the left with custom offset values. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Positioning = () => ( Click Me Left Placement This popover appears on the left with custom offset values. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Left Placement This popover appears on the left with custom offset values. ``` ### 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`. **Example: close-behavior** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const CloseBehavior = () => ( Click Me Quick Actions Press Escape or click outside to close this popover. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const CloseBehavior = () => ( Click Me Quick Actions Press Escape or click outside to close this popover. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Quick Actions Press Escape or click outside to close this popover. ``` ### 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 - hide content behind the popover from screen readers To make the popover modal, set the `modal` prop to `true`. When `modal={true}`, we set the `portalled` attribute to `true` as well. **Example: modal** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Modal = () => ( Click Me Confirm Action Focus is trapped inside this modal popover until dismissed. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Modal = () => ( Click Me Confirm Action Focus is trapped inside this modal popover until dismissed. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Confirm Action Focus is trapped inside this modal popover until dismissed. ``` ### Anchor Use `Popover.Anchor` to position the popover relative to a different element than the trigger. **Example: anchor** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import field from 'styles/field.module.css' import styles from 'styles/popover.module.css' export const Anchor = () => { return (
                    Click Me
                    Title Description
                    ) } ``` ### Same Width Use `positioning.sameWidth` to make the popover match the width of its trigger element. **Example: same-width** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const SameWidth = () => { return ( Click Me Matched Width This popover matches the width of its trigger element. ) } ``` ### Dialog Integration When rendering a popover inside a dialog, you have two options for proper layering: 1. **Keep the Portal with `lazyMount` and `unmountOnExit`** - This ensures the popover is properly unmounted when the dialog closes, preventing stale DOM nodes. 2. **Remove the Portal** - Render the popover inline within the dialog content. This works well but may have z-index considerations. **Example: with-dialog** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/popover.module.css' export const WithDialog = () => ( Open Dialog Edit Profile Update your profile information below.
                    More Options Additional Settings This popover renders correctly above the dialog.
                    ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/popover.module.css' export const WithDialog = () => ( Open Dialog Edit Profile Update your profile information below.
                    More Options Additional Settings This popover renders correctly above the dialog.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Edit Profile Update your profile information below.
                    More Options Additional Settings This popover renders correctly above the dialog.
                    ``` ### Nested Popovers can be nested within each other. Each nested popover maintains its own open state and positioning. **Example: nested** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Nested = () => { return ( Click Me Settings Manage your preferences and account settings. Advanced Advanced Settings Configure advanced options for power users. ) } ``` ## Guides ### Available Size The following css variables are exposed to the `Popover.Positioner` which you can use to style the `Popover.Content` ```css /* width of the popover trigger */ --reference-width: ; /* width of the available viewport */ --available-width: ; /* height of the available viewport */ --available-height: ; ``` For example, if you want to make sure the maximum height doesn't exceed the available height, use the following css: ```css [data-scope='popover'][data-part='content'] { max-height: calc(var(--available-height) - 100px); } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `autoFocus` | `boolean` | No | Whether to automatically set focus on the first focusable content within the popover when opened. | | `closeOnEscape` | `boolean` | No | Whether to close the popover when the escape key is pressed. | | `closeOnInteractOutside` | `boolean` | No | Whether to close the popover when the user clicks outside of the popover. | | `defaultOpen` | `boolean` | No | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ anchor: string trigger: string content: string title: string description: string closeTrigger: string positioner: string arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The element to focus on when the popover is opened. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function invoked when the popover opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the popover | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `portalled` | `boolean` | No | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Anchor Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-expanded]` | Present when expanded | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested popovers | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePopoverReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `autoFocus` | `boolean` | No | Whether to automatically set focus on the first focusable content within the popover when opened. | | `closeOnEscape` | `boolean` | No | Whether to close the popover when the escape key is pressed. | | `closeOnInteractOutside` | `boolean` | No | Whether to close the popover when the user clicks outside of the popover. | | `defaultOpen` | `boolean` | No | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ anchor: string trigger: string content: string title: string description: string closeTrigger: string positioner: string arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The element to focus on when the popover is opened. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function invoked when the popover opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the popover | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `portalled` | `boolean` | No | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Anchor Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-expanded]` | Present when expanded | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested popovers | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePopoverReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `autoFocus` | `boolean` | No | Whether to automatically set focus on the first focusable content within the popover when opened. | | `closeOnEscape` | `boolean` | No | Whether to close the popover when the escape key is pressed. | | `closeOnInteractOutside` | `boolean` | No | Whether to close the popover when the user clicks outside of the popover. | | `defaultOpen` | `boolean` | No | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ anchor: string trigger: string content: string title: string description: string closeTrigger: string positioner: string arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `initialFocusEl` | `() => HTMLElement | null` | No | The element to focus on when the popover is opened. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | | `open` | `boolean` | No | The controlled open state of the popover | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `portalled` | `boolean` | No | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Anchor Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-expanded]` | Present when expanded | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested popovers | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PopoverApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `autoFocus` | `boolean` | No | Whether to automatically set focus on the first focusable content within the popover when opened. | | `closeOnEscape` | `boolean` | No | Whether to close the popover when the escape key is pressed. | | `closeOnInteractOutside` | `boolean` | No | Whether to close the popover when the user clicks outside of the popover. | | `defaultOpen` | `boolean` | No | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ anchor: string trigger: string content: string title: string description: string closeTrigger: string positioner: string arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The element to focus on when the popover is opened. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function invoked when the popover opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the popover | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `portalled` | `boolean` | No | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Anchor Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-expanded]` | Present when expanded | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested popovers | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePopoverContext]>` | No | | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'p'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePopoverReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `portalled` | `boolean` | Whether the popover is portalled. | | `open` | `boolean` | Whether the popover is open | | `setOpen` | `(open: boolean) => void` | Function to open or close the popover | | `reposition` | `(options?: Partial) => void` | Function to reposition the popover | ## Accessibility ### Keyboard Support **`Space`** Description: Opens/closes the popover. **`Enter`** Description: Opens/closes the popover. **`Tab`** Description: Moves focus to the next focusable element within the content.
                    Note: If there are no focusable elements, focus is moved to the next focusable element after the trigger.
                    **`Shift + Tab`** Description: Moves focus to the previous focusable element within the content
                    Note: If there are no focusable elements, focus is moved to the trigger.
                    **`Esc`** Description: Closes the popover and moves focus to the trigger. --- # Popover (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Basic = () => ( Click Me Favorite Frameworks Manage and organize your favorite web frameworks. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Basic = () => ( Click Me Favorite Frameworks Manage and organize your favorite web frameworks. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Favorite Frameworks Manage and organize your favorite web frameworks. ``` ### Controlled Use the `open` and `onOpenChange` props to control the open state of the popover. **Example: controlled** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return ( setOpen(e.open)}> Click Me Team Members Invite colleagues to collaborate on this project. ) } ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return ( setOpen(e.open)}> Click Me Team Members Invite colleagues to collaborate on this project. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Team Members Invite colleagues to collaborate on this project. ``` ### 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. **Example: root-provider** #### React ```tsx import { Popover, usePopover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const RootProvider = () => { const popover = usePopover({ positioning: { placement: 'bottom-start', }, }) return (
                    Controlled Externally This popover is controlled via the usePopover hook.
                    ) } ``` #### Solid ```tsx import { Popover, usePopover } from '@ark-ui/solid/popover' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const RootProvider = () => { const popover = usePopover() return (
                    Controlled Externally This popover is controlled via the usePopover hook.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Controlled Externally This popover is controlled via the usePopover hook.
                    ``` ### Arrow Use `Popover.Arrow` and `Popover.ArrowTip` to render an arrow pointing to the trigger. **Example: arrow** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Arrow = () => ( Click Me Notifications You have 3 unread messages in your inbox. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Arrow = () => ( Click Me Notifications You have 3 unread messages in your inbox. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Notifications You have 3 unread messages in your inbox. ``` ### Placement To change the placement of the popover, set the `positioning` prop. **Example: positioning** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Positioning = () => ( Click Me Left Placement This popover appears on the left with custom offset values. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Positioning = () => ( Click Me Left Placement This popover appears on the left with custom offset values. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Left Placement This popover appears on the left with custom offset values. ``` ### 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`. **Example: close-behavior** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const CloseBehavior = () => ( Click Me Quick Actions Press Escape or click outside to close this popover. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const CloseBehavior = () => ( Click Me Quick Actions Press Escape or click outside to close this popover. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Quick Actions Press Escape or click outside to close this popover. ``` ### 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 - hide content behind the popover from screen readers To make the popover modal, set the `modal` prop to `true`. When `modal={true}`, we set the `portalled` attribute to `true` as well. **Example: modal** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Modal = () => ( Click Me Confirm Action Focus is trapped inside this modal popover until dismissed. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Modal = () => ( Click Me Confirm Action Focus is trapped inside this modal popover until dismissed. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Confirm Action Focus is trapped inside this modal popover until dismissed. ``` ### Anchor Use `Popover.Anchor` to position the popover relative to a different element than the trigger. **Example: anchor** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import field from 'styles/field.module.css' import styles from 'styles/popover.module.css' export const Anchor = () => { return (
                    Click Me
                    Title Description
                    ) } ``` ### Same Width Use `positioning.sameWidth` to make the popover match the width of its trigger element. **Example: same-width** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const SameWidth = () => { return ( Click Me Matched Width This popover matches the width of its trigger element. ) } ``` ### Dialog Integration When rendering a popover inside a dialog, you have two options for proper layering: 1. **Keep the Portal with `lazyMount` and `unmountOnExit`** - This ensures the popover is properly unmounted when the dialog closes, preventing stale DOM nodes. 2. **Remove the Portal** - Render the popover inline within the dialog content. This works well but may have z-index considerations. **Example: with-dialog** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/popover.module.css' export const WithDialog = () => ( Open Dialog Edit Profile Update your profile information below.
                    More Options Additional Settings This popover renders correctly above the dialog.
                    ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/popover.module.css' export const WithDialog = () => ( Open Dialog Edit Profile Update your profile information below.
                    More Options Additional Settings This popover renders correctly above the dialog.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Edit Profile Update your profile information below.
                    More Options Additional Settings This popover renders correctly above the dialog.
                    ``` ### Nested Popovers can be nested within each other. Each nested popover maintains its own open state and positioning. **Example: nested** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Nested = () => { return ( Click Me Settings Manage your preferences and account settings. Advanced Advanced Settings Configure advanced options for power users. ) } ``` ## Guides ### Available Size The following css variables are exposed to the `Popover.Positioner` which you can use to style the `Popover.Content` ```css /* width of the popover trigger */ --reference-width: ; /* width of the available viewport */ --available-width: ; /* height of the available viewport */ --available-height: ; ``` For example, if you want to make sure the maximum height doesn't exceed the available height, use the following css: ```css [data-scope='popover'][data-part='content'] { max-height: calc(var(--available-height) - 100px); } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `autoFocus` | `boolean` | No | Whether to automatically set focus on the first focusable content within the popover when opened. | | `closeOnEscape` | `boolean` | No | Whether to close the popover when the escape key is pressed. | | `closeOnInteractOutside` | `boolean` | No | Whether to close the popover when the user clicks outside of the popover. | | `defaultOpen` | `boolean` | No | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ anchor: string trigger: string content: string title: string description: string closeTrigger: string positioner: string arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The element to focus on when the popover is opened. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function invoked when the popover opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the popover | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `portalled` | `boolean` | No | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Anchor Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-expanded]` | Present when expanded | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested popovers | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePopoverReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `autoFocus` | `boolean` | No | Whether to automatically set focus on the first focusable content within the popover when opened. | | `closeOnEscape` | `boolean` | No | Whether to close the popover when the escape key is pressed. | | `closeOnInteractOutside` | `boolean` | No | Whether to close the popover when the user clicks outside of the popover. | | `defaultOpen` | `boolean` | No | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ anchor: string trigger: string content: string title: string description: string closeTrigger: string positioner: string arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The element to focus on when the popover is opened. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function invoked when the popover opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the popover | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `portalled` | `boolean` | No | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Anchor Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-expanded]` | Present when expanded | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested popovers | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePopoverReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `autoFocus` | `boolean` | No | Whether to automatically set focus on the first focusable content within the popover when opened. | | `closeOnEscape` | `boolean` | No | Whether to close the popover when the escape key is pressed. | | `closeOnInteractOutside` | `boolean` | No | Whether to close the popover when the user clicks outside of the popover. | | `defaultOpen` | `boolean` | No | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ anchor: string trigger: string content: string title: string description: string closeTrigger: string positioner: string arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `initialFocusEl` | `() => HTMLElement | null` | No | The element to focus on when the popover is opened. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | | `open` | `boolean` | No | The controlled open state of the popover | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `portalled` | `boolean` | No | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Anchor Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-expanded]` | Present when expanded | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested popovers | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PopoverApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `autoFocus` | `boolean` | No | Whether to automatically set focus on the first focusable content within the popover when opened. | | `closeOnEscape` | `boolean` | No | Whether to close the popover when the escape key is pressed. | | `closeOnInteractOutside` | `boolean` | No | Whether to close the popover when the user clicks outside of the popover. | | `defaultOpen` | `boolean` | No | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ anchor: string trigger: string content: string title: string description: string closeTrigger: string positioner: string arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The element to focus on when the popover is opened. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function invoked when the popover opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the popover | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `portalled` | `boolean` | No | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Anchor Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-expanded]` | Present when expanded | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested popovers | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePopoverContext]>` | No | | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'p'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePopoverReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `portalled` | `boolean` | Whether the popover is portalled. | | `open` | `boolean` | Whether the popover is open | | `setOpen` | `(open: boolean) => void` | Function to open or close the popover | | `reposition` | `(options?: Partial) => void` | Function to reposition the popover | ## Accessibility ### Keyboard Support **`Space`** Description: Opens/closes the popover. **`Enter`** Description: Opens/closes the popover. **`Tab`** Description: Moves focus to the next focusable element within the content.
                    Note: If there are no focusable elements, focus is moved to the next focusable element after the trigger.
                    **`Shift + Tab`** Description: Moves focus to the previous focusable element within the content
                    Note: If there are no focusable elements, focus is moved to the trigger.
                    **`Esc`** Description: Closes the popover and moves focus to the trigger. --- # Popover (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Basic = () => ( Click Me Favorite Frameworks Manage and organize your favorite web frameworks. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Basic = () => ( Click Me Favorite Frameworks Manage and organize your favorite web frameworks. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Favorite Frameworks Manage and organize your favorite web frameworks. ``` ### Controlled Use the `open` and `onOpenChange` props to control the open state of the popover. **Example: controlled** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return ( setOpen(e.open)}> Click Me Team Members Invite colleagues to collaborate on this project. ) } ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return ( setOpen(e.open)}> Click Me Team Members Invite colleagues to collaborate on this project. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Team Members Invite colleagues to collaborate on this project. ``` ### 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. **Example: root-provider** #### React ```tsx import { Popover, usePopover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const RootProvider = () => { const popover = usePopover({ positioning: { placement: 'bottom-start', }, }) return (
                    Controlled Externally This popover is controlled via the usePopover hook.
                    ) } ``` #### Solid ```tsx import { Popover, usePopover } from '@ark-ui/solid/popover' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const RootProvider = () => { const popover = usePopover() return (
                    Controlled Externally This popover is controlled via the usePopover hook.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Controlled Externally This popover is controlled via the usePopover hook.
                    ``` ### Arrow Use `Popover.Arrow` and `Popover.ArrowTip` to render an arrow pointing to the trigger. **Example: arrow** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Arrow = () => ( Click Me Notifications You have 3 unread messages in your inbox. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Arrow = () => ( Click Me Notifications You have 3 unread messages in your inbox. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Notifications You have 3 unread messages in your inbox. ``` ### Placement To change the placement of the popover, set the `positioning` prop. **Example: positioning** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Positioning = () => ( Click Me Left Placement This popover appears on the left with custom offset values. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Positioning = () => ( Click Me Left Placement This popover appears on the left with custom offset values. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Left Placement This popover appears on the left with custom offset values. ``` ### 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`. **Example: close-behavior** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const CloseBehavior = () => ( Click Me Quick Actions Press Escape or click outside to close this popover. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const CloseBehavior = () => ( Click Me Quick Actions Press Escape or click outside to close this popover. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Quick Actions Press Escape or click outside to close this popover. ``` ### 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 - hide content behind the popover from screen readers To make the popover modal, set the `modal` prop to `true`. When `modal={true}`, we set the `portalled` attribute to `true` as well. **Example: modal** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Modal = () => ( Click Me Confirm Action Focus is trapped inside this modal popover until dismissed. ) ``` #### Solid ```tsx import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Modal = () => ( Click Me Confirm Action Focus is trapped inside this modal popover until dismissed. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Click Me Confirm Action Focus is trapped inside this modal popover until dismissed. ``` ### Anchor Use `Popover.Anchor` to position the popover relative to a different element than the trigger. **Example: anchor** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import field from 'styles/field.module.css' import styles from 'styles/popover.module.css' export const Anchor = () => { return (
                    Click Me
                    Title Description
                    ) } ``` ### Same Width Use `positioning.sameWidth` to make the popover match the width of its trigger element. **Example: same-width** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const SameWidth = () => { return ( Click Me Matched Width This popover matches the width of its trigger element. ) } ``` ### Dialog Integration When rendering a popover inside a dialog, you have two options for proper layering: 1. **Keep the Portal with `lazyMount` and `unmountOnExit`** - This ensures the popover is properly unmounted when the dialog closes, preventing stale DOM nodes. 2. **Remove the Portal** - Render the popover inline within the dialog content. This works well but may have z-index considerations. **Example: with-dialog** #### React ```tsx import { Dialog } from '@ark-ui/react/dialog' import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/popover.module.css' export const WithDialog = () => ( Open Dialog Edit Profile Update your profile information below.
                    More Options Additional Settings This popover renders correctly above the dialog.
                    ) ``` #### Solid ```tsx import { Dialog } from '@ark-ui/solid/dialog' import { Popover } from '@ark-ui/solid/popover' import { XIcon } from 'lucide-solid' import { Portal } from 'solid-js/web' import button from 'styles/button.module.css' import dialog from 'styles/dialog.module.css' import styles from 'styles/popover.module.css' export const WithDialog = () => ( Open Dialog Edit Profile Update your profile information below.
                    More Options Additional Settings This popover renders correctly above the dialog.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte Open Dialog Edit Profile Update your profile information below.
                    More Options Additional Settings This popover renders correctly above the dialog.
                    ``` ### Nested Popovers can be nested within each other. Each nested popover maintains its own open state and positioning. **Example: nested** #### React ```tsx import { Popover } from '@ark-ui/react/popover' import { Portal } from '@ark-ui/react/portal' import button from 'styles/button.module.css' import styles from 'styles/popover.module.css' export const Nested = () => { return ( Click Me Settings Manage your preferences and account settings. Advanced Advanced Settings Configure advanced options for power users. ) } ``` ## Guides ### Available Size The following css variables are exposed to the `Popover.Positioner` which you can use to style the `Popover.Content` ```css /* width of the popover trigger */ --reference-width: ; /* width of the available viewport */ --available-width: ; /* height of the available viewport */ --available-height: ; ``` For example, if you want to make sure the maximum height doesn't exceed the available height, use the following css: ```css [data-scope='popover'][data-part='content'] { max-height: calc(var(--available-height) - 100px); } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `autoFocus` | `boolean` | No | Whether to automatically set focus on the first focusable content within the popover when opened. | | `closeOnEscape` | `boolean` | No | Whether to close the popover when the escape key is pressed. | | `closeOnInteractOutside` | `boolean` | No | Whether to close the popover when the user clicks outside of the popover. | | `defaultOpen` | `boolean` | No | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ anchor: string trigger: string content: string title: string description: string closeTrigger: string positioner: string arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The element to focus on when the popover is opened. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function invoked when the popover opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the popover | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `portalled` | `boolean` | No | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Anchor Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-expanded]` | Present when expanded | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested popovers | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePopoverReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `autoFocus` | `boolean` | No | Whether to automatically set focus on the first focusable content within the popover when opened. | | `closeOnEscape` | `boolean` | No | Whether to close the popover when the escape key is pressed. | | `closeOnInteractOutside` | `boolean` | No | Whether to close the popover when the user clicks outside of the popover. | | `defaultOpen` | `boolean` | No | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ anchor: string trigger: string content: string title: string description: string closeTrigger: string positioner: string arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The element to focus on when the popover is opened. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function invoked when the popover opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the popover | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `portalled` | `boolean` | No | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Anchor Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-expanded]` | Present when expanded | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested popovers | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePopoverReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `autoFocus` | `boolean` | No | Whether to automatically set focus on the first focusable content within the popover when opened. | | `closeOnEscape` | `boolean` | No | Whether to close the popover when the escape key is pressed. | | `closeOnInteractOutside` | `boolean` | No | Whether to close the popover when the user clicks outside of the popover. | | `defaultOpen` | `boolean` | No | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ anchor: string trigger: string content: string title: string description: string closeTrigger: string positioner: string arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `initialFocusEl` | `() => HTMLElement | null` | No | The element to focus on when the popover is opened. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | | `open` | `boolean` | No | The controlled open state of the popover | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `portalled` | `boolean` | No | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Anchor Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-expanded]` | Present when expanded | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested popovers | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `PopoverApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `autoFocus` | `boolean` | No | Whether to automatically set focus on the first focusable content within the popover when opened. | | `closeOnEscape` | `boolean` | No | Whether to close the popover when the escape key is pressed. | | `closeOnInteractOutside` | `boolean` | No | Whether to close the popover when the user clicks outside of the popover. | | `defaultOpen` | `boolean` | No | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ anchor: string trigger: string content: string title: string description: string closeTrigger: string positioner: string arrow: string }>` | No | The ids of the elements in the popover. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `initialFocusEl` | `() => HTMLElement | null` | No | The element to focus on when the popover is opened. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `modal` | `boolean` | No | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | | `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function invoked when the popover opens or closes | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed | | `open` | `boolean` | No | The controlled open state of the popover | | `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | `portalled` | `boolean` | No | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Anchor Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-expanded]` | Present when expanded | | `[data-placement]` | The placement of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested popovers | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePopoverContext]>` | No | | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'p'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UsePopoverReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | popover | | `[data-part]` | trigger | | `[data-placement]` | The placement of the trigger | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `portalled` | `boolean` | Whether the popover is portalled. | | `open` | `boolean` | Whether the popover is open | | `setOpen` | `(open: boolean) => void` | Function to open or close the popover | | `reposition` | `(options?: Partial) => void` | Function to reposition the popover | ## Accessibility ### Keyboard Support **`Space`** Description: Opens/closes the popover. **`Enter`** Description: Opens/closes the popover. **`Tab`** Description: Moves focus to the next focusable element within the content.
                    Note: If there are no focusable elements, focus is moved to the next focusable element after the trigger.
                    **`Shift + Tab`** Description: Moves focus to the previous focusable element within the content
                    Note: If there are no focusable elements, focus is moved to the trigger.
                    **`Esc`** Description: Closes the popover and moves focus to the trigger. --- # QR Code (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { QrCode } from '@ark-ui/react/qr-code' import styles from 'styles/qr-code.module.css' export const Basic = () => { return ( ) } ``` #### Solid ```tsx import { QrCode } from '@ark-ui/solid/qr-code' import styles from 'styles/qr-code.module.css' export const Basic = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### 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. **Example: overlay** #### React ```tsx import { QrCode } from '@ark-ui/react/qr-code' import styles from 'styles/qr-code.module.css' export const Overlay = () => { return ( Ark UI Logo ) } ``` #### Solid ```tsx import { QrCode } from '@ark-ui/solid/qr-code' import styles from 'styles/qr-code.module.css' export const Overlay = () => { return ( Ark UI Logo ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Ark UI Logo ``` ### 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 **Example: error-correction** #### React ```tsx import { QrCode } from '@ark-ui/react/qr-code' import { RadioGroup } from '@ark-ui/react/radio-group' import { useState } from 'react' import styles from 'styles/qr-code.module.css' import radio from 'styles/radio-group.module.css' type ErrorLevel = 'L' | 'M' | 'Q' | 'H' export const ErrorCorrection = () => { const [errorLevel, setErrorLevel] = useState('L') return (
                    setErrorLevel(e.value as ErrorLevel)} >
                    {['L', 'M', 'Q', 'H'].map((level) => ( {level} ))}
                    ) } ``` #### Solid ```tsx import { QrCode } from '@ark-ui/solid/qr-code' import { RadioGroup } from '@ark-ui/solid/radio-group' import { For, createSignal } from 'solid-js' import styles from 'styles/qr-code.module.css' import radio from 'styles/radio-group.module.css' type ErrorLevel = 'L' | 'M' | 'Q' | 'H' export const ErrorCorrection = () => { const [errorLevel, setErrorLevel] = createSignal('L') return (
                    setErrorLevel(e.value as ErrorLevel)} >
                    {(level) => ( {level} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    (errorLevel = e.value as ErrorLevel)} >
                    {#each levels as level} {level} {/each}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { QrCode, useQrCode } from '@ark-ui/react/qr-code' import styles from 'styles/qr-code.module.css' export const RootProvider = () => { const qrCode = useQrCode({ value: 'http://ark-ui.com' }) return (
                    {qrCode.value}
                    ) } ``` #### Solid ```tsx import { QrCode, useQrCode } from '@ark-ui/solid/qr-code' import styles from 'styles/qr-code.module.css' export const RootProvider = () => { const qrCode = useQrCode({ value: 'http://ark-ui.com' }) return (
                    {qrCode().value}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {qrCode().value}
                    ``` ### 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. **Example: download** #### React ```tsx import { QrCode } from '@ark-ui/react/qr-code' import button from 'styles/button.module.css' import styles from 'styles/qr-code.module.css' export const Download = () => { return ( Download ) } ``` #### Solid ```tsx import { QrCode } from '@ark-ui/solid/qr-code' import button from 'styles/button.module.css' import styles from 'styles/qr-code.module.css' export const Download = () => { return ( Download ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Download ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to encode when rendered. Use when you don't need to control the value of the qr code. | | `encoding` | `QrCodeGenerateOptions` | No | The qr code encoding options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; frame: string }>` | No | The element ids. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the value changes. | | `pixelSize` | `number` | No | The pixel size of the qr code. | | `value` | `string` | No | The controlled value to encode. | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--qrcode-pixel-size` | The size of the Root | | `--qrcode-width` | The width of the Root | | `--qrcode-height` | The height of the Root | **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fileName` | `string` | Yes | The name of the file. | | `mimeType` | `DataUrlType` | Yes | The mime type of the image. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `quality` | `number` | No | The quality of the image. | **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Overlay Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Pattern Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseQrCodeReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to encode when rendered. Use when you don't need to control the value of the qr code. | | `encoding` | `QrCodeGenerateOptions` | No | The qr code encoding options. | | `ids` | `Partial<{ root: string; frame: string }>` | No | The element ids. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the value changes. | | `pixelSize` | `number` | No | The pixel size of the qr code. | | `value` | `string` | No | The controlled value to encode. | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--qrcode-pixel-size` | The size of the Root | | `--qrcode-width` | The width of the Root | | `--qrcode-height` | The height of the Root | **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fileName` | `string` | Yes | The name of the file. | | `mimeType` | `DataUrlType` | Yes | The mime type of the image. | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `quality` | `number` | No | The quality of the image. | **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'svg'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Overlay Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Pattern Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'path'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseQrCodeReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to encode when rendered. Use when you don't need to control the value of the qr code. | | `encoding` | `QrCodeGenerateOptions` | No | The qr code encoding options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; frame: string }>` | No | The element ids. | | `modelValue` | `string` | No | The v-model value of the qr code | | `pixelSize` | `number` | No | The pixel size of the qr code. | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--qrcode-pixel-size` | The size of the Root | | `--qrcode-width` | The width of the Root | | `--qrcode-height` | The height of the Root | **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fileName` | `string` | Yes | The name of the file. | | `mimeType` | `DataUrlType` | Yes | The mime type of the image. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `quality` | `number` | No | The quality of the image. | **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Overlay Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Pattern Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `QrCodeApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to encode when rendered. Use when you don't need to control the value of the qr code. | | `encoding` | `QrCodeGenerateOptions` | No | The qr code encoding options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; frame: string }>` | No | The element ids. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the value changes. | | `pixelSize` | `number` | No | The pixel size of the qr code. | | `ref` | `Element` | No | | | `value` | `string` | No | The controlled value to encode. | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--qrcode-pixel-size` | The size of the Root | | `--qrcode-width` | The width of the Root | | `--qrcode-height` | The height of the Root | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `api` | `Snippet<[UseQrCodeContext]>` | No | | **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fileName` | `string` | Yes | The name of the file. | | `mimeType` | `DataUrlType` | Yes | The mime type of the image. | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `quality` | `number` | No | The quality of the image. | | `ref` | `Element` | No | | **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'svg'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Overlay Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Pattern Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'path'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseQrCodeReturn` | Yes | | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string` | The value to encode. | | `setValue` | `(value: string) => void` | Set the value to encode. | | `getDataUrl` | `(type: DataUrlType, quality?: number) => Promise` | Returns the data URL of the qr code. | --- # QR Code (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { QrCode } from '@ark-ui/react/qr-code' import styles from 'styles/qr-code.module.css' export const Basic = () => { return ( ) } ``` #### Solid ```tsx import { QrCode } from '@ark-ui/solid/qr-code' import styles from 'styles/qr-code.module.css' export const Basic = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### 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. **Example: overlay** #### React ```tsx import { QrCode } from '@ark-ui/react/qr-code' import styles from 'styles/qr-code.module.css' export const Overlay = () => { return ( Ark UI Logo ) } ``` #### Solid ```tsx import { QrCode } from '@ark-ui/solid/qr-code' import styles from 'styles/qr-code.module.css' export const Overlay = () => { return ( Ark UI Logo ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Ark UI Logo ``` ### 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 **Example: error-correction** #### React ```tsx import { QrCode } from '@ark-ui/react/qr-code' import { RadioGroup } from '@ark-ui/react/radio-group' import { useState } from 'react' import styles from 'styles/qr-code.module.css' import radio from 'styles/radio-group.module.css' type ErrorLevel = 'L' | 'M' | 'Q' | 'H' export const ErrorCorrection = () => { const [errorLevel, setErrorLevel] = useState('L') return (
                    setErrorLevel(e.value as ErrorLevel)} >
                    {['L', 'M', 'Q', 'H'].map((level) => ( {level} ))}
                    ) } ``` #### Solid ```tsx import { QrCode } from '@ark-ui/solid/qr-code' import { RadioGroup } from '@ark-ui/solid/radio-group' import { For, createSignal } from 'solid-js' import styles from 'styles/qr-code.module.css' import radio from 'styles/radio-group.module.css' type ErrorLevel = 'L' | 'M' | 'Q' | 'H' export const ErrorCorrection = () => { const [errorLevel, setErrorLevel] = createSignal('L') return (
                    setErrorLevel(e.value as ErrorLevel)} >
                    {(level) => ( {level} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    (errorLevel = e.value as ErrorLevel)} >
                    {#each levels as level} {level} {/each}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { QrCode, useQrCode } from '@ark-ui/react/qr-code' import styles from 'styles/qr-code.module.css' export const RootProvider = () => { const qrCode = useQrCode({ value: 'http://ark-ui.com' }) return (
                    {qrCode.value}
                    ) } ``` #### Solid ```tsx import { QrCode, useQrCode } from '@ark-ui/solid/qr-code' import styles from 'styles/qr-code.module.css' export const RootProvider = () => { const qrCode = useQrCode({ value: 'http://ark-ui.com' }) return (
                    {qrCode().value}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {qrCode().value}
                    ``` ### 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. **Example: download** #### React ```tsx import { QrCode } from '@ark-ui/react/qr-code' import button from 'styles/button.module.css' import styles from 'styles/qr-code.module.css' export const Download = () => { return ( Download ) } ``` #### Solid ```tsx import { QrCode } from '@ark-ui/solid/qr-code' import button from 'styles/button.module.css' import styles from 'styles/qr-code.module.css' export const Download = () => { return ( Download ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Download ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to encode when rendered. Use when you don't need to control the value of the qr code. | | `encoding` | `QrCodeGenerateOptions` | No | The qr code encoding options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; frame: string }>` | No | The element ids. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the value changes. | | `pixelSize` | `number` | No | The pixel size of the qr code. | | `value` | `string` | No | The controlled value to encode. | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--qrcode-pixel-size` | The size of the Root | | `--qrcode-width` | The width of the Root | | `--qrcode-height` | The height of the Root | **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fileName` | `string` | Yes | The name of the file. | | `mimeType` | `DataUrlType` | Yes | The mime type of the image. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `quality` | `number` | No | The quality of the image. | **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Overlay Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Pattern Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseQrCodeReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to encode when rendered. Use when you don't need to control the value of the qr code. | | `encoding` | `QrCodeGenerateOptions` | No | The qr code encoding options. | | `ids` | `Partial<{ root: string; frame: string }>` | No | The element ids. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the value changes. | | `pixelSize` | `number` | No | The pixel size of the qr code. | | `value` | `string` | No | The controlled value to encode. | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--qrcode-pixel-size` | The size of the Root | | `--qrcode-width` | The width of the Root | | `--qrcode-height` | The height of the Root | **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fileName` | `string` | Yes | The name of the file. | | `mimeType` | `DataUrlType` | Yes | The mime type of the image. | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `quality` | `number` | No | The quality of the image. | **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'svg'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Overlay Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Pattern Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'path'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseQrCodeReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to encode when rendered. Use when you don't need to control the value of the qr code. | | `encoding` | `QrCodeGenerateOptions` | No | The qr code encoding options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; frame: string }>` | No | The element ids. | | `modelValue` | `string` | No | The v-model value of the qr code | | `pixelSize` | `number` | No | The pixel size of the qr code. | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--qrcode-pixel-size` | The size of the Root | | `--qrcode-width` | The width of the Root | | `--qrcode-height` | The height of the Root | **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fileName` | `string` | Yes | The name of the file. | | `mimeType` | `DataUrlType` | Yes | The mime type of the image. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `quality` | `number` | No | The quality of the image. | **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Overlay Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Pattern Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `QrCodeApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to encode when rendered. Use when you don't need to control the value of the qr code. | | `encoding` | `QrCodeGenerateOptions` | No | The qr code encoding options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; frame: string }>` | No | The element ids. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the value changes. | | `pixelSize` | `number` | No | The pixel size of the qr code. | | `ref` | `Element` | No | | | `value` | `string` | No | The controlled value to encode. | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--qrcode-pixel-size` | The size of the Root | | `--qrcode-width` | The width of the Root | | `--qrcode-height` | The height of the Root | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `api` | `Snippet<[UseQrCodeContext]>` | No | | **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fileName` | `string` | Yes | The name of the file. | | `mimeType` | `DataUrlType` | Yes | The mime type of the image. | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `quality` | `number` | No | The quality of the image. | | `ref` | `Element` | No | | **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'svg'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Overlay Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Pattern Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'path'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseQrCodeReturn` | Yes | | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string` | The value to encode. | | `setValue` | `(value: string) => void` | Set the value to encode. | | `getDataUrl` | `(type: DataUrlType, quality?: number) => Promise` | Returns the data URL of the qr code. | --- # QR Code (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { QrCode } from '@ark-ui/react/qr-code' import styles from 'styles/qr-code.module.css' export const Basic = () => { return ( ) } ``` #### Solid ```tsx import { QrCode } from '@ark-ui/solid/qr-code' import styles from 'styles/qr-code.module.css' export const Basic = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### 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. **Example: overlay** #### React ```tsx import { QrCode } from '@ark-ui/react/qr-code' import styles from 'styles/qr-code.module.css' export const Overlay = () => { return ( Ark UI Logo ) } ``` #### Solid ```tsx import { QrCode } from '@ark-ui/solid/qr-code' import styles from 'styles/qr-code.module.css' export const Overlay = () => { return ( Ark UI Logo ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Ark UI Logo ``` ### 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 **Example: error-correction** #### React ```tsx import { QrCode } from '@ark-ui/react/qr-code' import { RadioGroup } from '@ark-ui/react/radio-group' import { useState } from 'react' import styles from 'styles/qr-code.module.css' import radio from 'styles/radio-group.module.css' type ErrorLevel = 'L' | 'M' | 'Q' | 'H' export const ErrorCorrection = () => { const [errorLevel, setErrorLevel] = useState('L') return (
                    setErrorLevel(e.value as ErrorLevel)} >
                    {['L', 'M', 'Q', 'H'].map((level) => ( {level} ))}
                    ) } ``` #### Solid ```tsx import { QrCode } from '@ark-ui/solid/qr-code' import { RadioGroup } from '@ark-ui/solid/radio-group' import { For, createSignal } from 'solid-js' import styles from 'styles/qr-code.module.css' import radio from 'styles/radio-group.module.css' type ErrorLevel = 'L' | 'M' | 'Q' | 'H' export const ErrorCorrection = () => { const [errorLevel, setErrorLevel] = createSignal('L') return (
                    setErrorLevel(e.value as ErrorLevel)} >
                    {(level) => ( {level} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    (errorLevel = e.value as ErrorLevel)} >
                    {#each levels as level} {level} {/each}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { QrCode, useQrCode } from '@ark-ui/react/qr-code' import styles from 'styles/qr-code.module.css' export const RootProvider = () => { const qrCode = useQrCode({ value: 'http://ark-ui.com' }) return (
                    {qrCode.value}
                    ) } ``` #### Solid ```tsx import { QrCode, useQrCode } from '@ark-ui/solid/qr-code' import styles from 'styles/qr-code.module.css' export const RootProvider = () => { const qrCode = useQrCode({ value: 'http://ark-ui.com' }) return (
                    {qrCode().value}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {qrCode().value}
                    ``` ### 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. **Example: download** #### React ```tsx import { QrCode } from '@ark-ui/react/qr-code' import button from 'styles/button.module.css' import styles from 'styles/qr-code.module.css' export const Download = () => { return ( Download ) } ``` #### Solid ```tsx import { QrCode } from '@ark-ui/solid/qr-code' import button from 'styles/button.module.css' import styles from 'styles/qr-code.module.css' export const Download = () => { return ( Download ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Download ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to encode when rendered. Use when you don't need to control the value of the qr code. | | `encoding` | `QrCodeGenerateOptions` | No | The qr code encoding options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; frame: string }>` | No | The element ids. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the value changes. | | `pixelSize` | `number` | No | The pixel size of the qr code. | | `value` | `string` | No | The controlled value to encode. | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--qrcode-pixel-size` | The size of the Root | | `--qrcode-width` | The width of the Root | | `--qrcode-height` | The height of the Root | **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fileName` | `string` | Yes | The name of the file. | | `mimeType` | `DataUrlType` | Yes | The mime type of the image. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `quality` | `number` | No | The quality of the image. | **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Overlay Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Pattern Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseQrCodeReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to encode when rendered. Use when you don't need to control the value of the qr code. | | `encoding` | `QrCodeGenerateOptions` | No | The qr code encoding options. | | `ids` | `Partial<{ root: string; frame: string }>` | No | The element ids. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the value changes. | | `pixelSize` | `number` | No | The pixel size of the qr code. | | `value` | `string` | No | The controlled value to encode. | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--qrcode-pixel-size` | The size of the Root | | `--qrcode-width` | The width of the Root | | `--qrcode-height` | The height of the Root | **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fileName` | `string` | Yes | The name of the file. | | `mimeType` | `DataUrlType` | Yes | The mime type of the image. | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `quality` | `number` | No | The quality of the image. | **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'svg'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Overlay Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Pattern Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'path'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseQrCodeReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to encode when rendered. Use when you don't need to control the value of the qr code. | | `encoding` | `QrCodeGenerateOptions` | No | The qr code encoding options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; frame: string }>` | No | The element ids. | | `modelValue` | `string` | No | The v-model value of the qr code | | `pixelSize` | `number` | No | The pixel size of the qr code. | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--qrcode-pixel-size` | The size of the Root | | `--qrcode-width` | The width of the Root | | `--qrcode-height` | The height of the Root | **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fileName` | `string` | Yes | The name of the file. | | `mimeType` | `DataUrlType` | Yes | The mime type of the image. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `quality` | `number` | No | The quality of the image. | **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Overlay Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Pattern Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `QrCodeApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to encode when rendered. Use when you don't need to control the value of the qr code. | | `encoding` | `QrCodeGenerateOptions` | No | The qr code encoding options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; frame: string }>` | No | The element ids. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the value changes. | | `pixelSize` | `number` | No | The pixel size of the qr code. | | `ref` | `Element` | No | | | `value` | `string` | No | The controlled value to encode. | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--qrcode-pixel-size` | The size of the Root | | `--qrcode-width` | The width of the Root | | `--qrcode-height` | The height of the Root | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `api` | `Snippet<[UseQrCodeContext]>` | No | | **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fileName` | `string` | Yes | The name of the file. | | `mimeType` | `DataUrlType` | Yes | The mime type of the image. | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `quality` | `number` | No | The quality of the image. | | `ref` | `Element` | No | | **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'svg'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Overlay Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Pattern Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'path'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseQrCodeReturn` | Yes | | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string` | The value to encode. | | `setValue` | `(value: string) => void` | Set the value to encode. | | `getDataUrl` | `(type: DataUrlType, quality?: number) => Promise` | Returns the data URL of the qr code. | --- # QR Code (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { QrCode } from '@ark-ui/react/qr-code' import styles from 'styles/qr-code.module.css' export const Basic = () => { return ( ) } ``` #### Solid ```tsx import { QrCode } from '@ark-ui/solid/qr-code' import styles from 'styles/qr-code.module.css' export const Basic = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### 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. **Example: overlay** #### React ```tsx import { QrCode } from '@ark-ui/react/qr-code' import styles from 'styles/qr-code.module.css' export const Overlay = () => { return ( Ark UI Logo ) } ``` #### Solid ```tsx import { QrCode } from '@ark-ui/solid/qr-code' import styles from 'styles/qr-code.module.css' export const Overlay = () => { return ( Ark UI Logo ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Ark UI Logo ``` ### 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 **Example: error-correction** #### React ```tsx import { QrCode } from '@ark-ui/react/qr-code' import { RadioGroup } from '@ark-ui/react/radio-group' import { useState } from 'react' import styles from 'styles/qr-code.module.css' import radio from 'styles/radio-group.module.css' type ErrorLevel = 'L' | 'M' | 'Q' | 'H' export const ErrorCorrection = () => { const [errorLevel, setErrorLevel] = useState('L') return (
                    setErrorLevel(e.value as ErrorLevel)} >
                    {['L', 'M', 'Q', 'H'].map((level) => ( {level} ))}
                    ) } ``` #### Solid ```tsx import { QrCode } from '@ark-ui/solid/qr-code' import { RadioGroup } from '@ark-ui/solid/radio-group' import { For, createSignal } from 'solid-js' import styles from 'styles/qr-code.module.css' import radio from 'styles/radio-group.module.css' type ErrorLevel = 'L' | 'M' | 'Q' | 'H' export const ErrorCorrection = () => { const [errorLevel, setErrorLevel] = createSignal('L') return (
                    setErrorLevel(e.value as ErrorLevel)} >
                    {(level) => ( {level} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    (errorLevel = e.value as ErrorLevel)} >
                    {#each levels as level} {level} {/each}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { QrCode, useQrCode } from '@ark-ui/react/qr-code' import styles from 'styles/qr-code.module.css' export const RootProvider = () => { const qrCode = useQrCode({ value: 'http://ark-ui.com' }) return (
                    {qrCode.value}
                    ) } ``` #### Solid ```tsx import { QrCode, useQrCode } from '@ark-ui/solid/qr-code' import styles from 'styles/qr-code.module.css' export const RootProvider = () => { const qrCode = useQrCode({ value: 'http://ark-ui.com' }) return (
                    {qrCode().value}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {qrCode().value}
                    ``` ### 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. **Example: download** #### React ```tsx import { QrCode } from '@ark-ui/react/qr-code' import button from 'styles/button.module.css' import styles from 'styles/qr-code.module.css' export const Download = () => { return ( Download ) } ``` #### Solid ```tsx import { QrCode } from '@ark-ui/solid/qr-code' import button from 'styles/button.module.css' import styles from 'styles/qr-code.module.css' export const Download = () => { return ( Download ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Download ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to encode when rendered. Use when you don't need to control the value of the qr code. | | `encoding` | `QrCodeGenerateOptions` | No | The qr code encoding options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; frame: string }>` | No | The element ids. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the value changes. | | `pixelSize` | `number` | No | The pixel size of the qr code. | | `value` | `string` | No | The controlled value to encode. | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--qrcode-pixel-size` | The size of the Root | | `--qrcode-width` | The width of the Root | | `--qrcode-height` | The height of the Root | **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fileName` | `string` | Yes | The name of the file. | | `mimeType` | `DataUrlType` | Yes | The mime type of the image. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `quality` | `number` | No | The quality of the image. | **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Overlay Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Pattern Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseQrCodeReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to encode when rendered. Use when you don't need to control the value of the qr code. | | `encoding` | `QrCodeGenerateOptions` | No | The qr code encoding options. | | `ids` | `Partial<{ root: string; frame: string }>` | No | The element ids. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the value changes. | | `pixelSize` | `number` | No | The pixel size of the qr code. | | `value` | `string` | No | The controlled value to encode. | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--qrcode-pixel-size` | The size of the Root | | `--qrcode-width` | The width of the Root | | `--qrcode-height` | The height of the Root | **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fileName` | `string` | Yes | The name of the file. | | `mimeType` | `DataUrlType` | Yes | The mime type of the image. | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `quality` | `number` | No | The quality of the image. | **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'svg'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Overlay Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Pattern Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'path'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseQrCodeReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to encode when rendered. Use when you don't need to control the value of the qr code. | | `encoding` | `QrCodeGenerateOptions` | No | The qr code encoding options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; frame: string }>` | No | The element ids. | | `modelValue` | `string` | No | The v-model value of the qr code | | `pixelSize` | `number` | No | The pixel size of the qr code. | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--qrcode-pixel-size` | The size of the Root | | `--qrcode-width` | The width of the Root | | `--qrcode-height` | The height of the Root | **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fileName` | `string` | Yes | The name of the file. | | `mimeType` | `DataUrlType` | Yes | The mime type of the image. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `quality` | `number` | No | The quality of the image. | **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Overlay Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Pattern Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `QrCodeApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value to encode when rendered. Use when you don't need to control the value of the qr code. | | `encoding` | `QrCodeGenerateOptions` | No | The qr code encoding options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; frame: string }>` | No | The element ids. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the value changes. | | `pixelSize` | `number` | No | The pixel size of the qr code. | | `ref` | `Element` | No | | | `value` | `string` | No | The controlled value to encode. | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--qrcode-pixel-size` | The size of the Root | | `--qrcode-width` | The width of the Root | | `--qrcode-height` | The height of the Root | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `api` | `Snippet<[UseQrCodeContext]>` | No | | **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fileName` | `string` | Yes | The name of the file. | | `mimeType` | `DataUrlType` | Yes | The mime type of the image. | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `quality` | `number` | No | The quality of the image. | | `ref` | `Element` | No | | **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'svg'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Overlay Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Pattern Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'path'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseQrCodeReturn` | Yes | | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string` | The value to encode. | | `setValue` | `(value: string) => void` | Set the value to encode. | | `getDataUrl` | `(type: DataUrlType, quality?: number) => Promise` | Returns the data URL of the qr code. | --- # Radio Group (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { RadioGroup } from '@ark-ui/react/radio-group' import styles from 'styles/radio-group.module.css' export const Basic = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { RadioGroup } from '@ark-ui/solid/radio-group' import { For } from 'solid-js' import styles from 'styles/radio-group.module.css' export const Basic = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {(framework) => ( {framework} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#each frameworks as framework} {framework} {/each} ``` ### 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. **Example: initial-value** #### React ```tsx import { RadioGroup } from '@ark-ui/react/radio-group' import styles from 'styles/radio-group.module.css' export const InitialValue = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { RadioGroup } from '@ark-ui/solid/radio-group' import { For } from 'solid-js' import styles from 'styles/radio-group.module.css' export const InitialValue = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {(framework) => ( {framework} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#each frameworks as framework} {framework} {/each} ``` ### Controlled For a controlled Radio Group, the state is managed using the `value` prop, and updates when the `onValueChange` event handler is called: **Example: controlled** #### React ```tsx import { RadioGroup } from '@ark-ui/react/radio-group' import { useState } from 'react' import styles from 'styles/radio-group.module.css' export const Controlled = () => { const frameworks = ['React', 'Solid', 'Vue'] const [value, setValue] = useState(null) return ( setValue(e.value)}> Framework {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { RadioGroup } from '@ark-ui/solid/radio-group' import { For, createSignal } from 'solid-js' import styles from 'styles/radio-group.module.css' export const Controlled = () => { const frameworks = ['React', 'Solid', 'Vue'] const [value, setValue] = createSignal(null) return ( setValue(e.value)}> Framework {(framework) => ( {framework} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#each frameworks as framework} {framework} {/each} ``` ### 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. **Example: root-provider** #### React ```tsx import { RadioGroup, useRadioGroup } from '@ark-ui/react/radio-group' import button from 'styles/button.module.css' import styles from 'styles/radio-group.module.css' export const RootProvider = () => { const frameworks = ['React', 'Solid', 'Vue'] const radioGroup = useRadioGroup({ defaultValue: 'React' }) return (
                    Framework {frameworks.map((framework) => ( {framework} ))}
                    ) } ``` #### Solid ```tsx import { RadioGroup, useRadioGroup } from '@ark-ui/solid/radio-group' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/radio-group.module.css' export const RootProvider = () => { const frameworks = ['React', 'Solid', 'Vue'] const radioGroup = useRadioGroup({ defaultValue: 'React' }) return (
                    Framework {(framework) => ( {framework} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Framework {#each frameworks as framework} {framework} {/each}
                    ``` ### Disabled To make a radio group disabled, set the `disabled` prop to `true`. **Example: disabled** #### React ```tsx import { RadioGroup } from '@ark-ui/react/radio-group' import styles from 'styles/radio-group.module.css' export const Disabled = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { RadioGroup } from '@ark-ui/solid/radio-group' import { For } from 'solid-js' import styles from 'styles/radio-group.module.css' export const Disabled = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {(framework) => ( {framework} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#each frameworks as framework} {framework} {/each} ``` ## Guides ### asChild The `RadioGroup.Item` component renders as a `label` element by default. This ensures proper form semantics and accessibility, as radio groups are form controls that require labels to provide meaningful context for users. When using the `asChild` prop, you must **render a `label` element** as the direct child of `RadioGroup.Item` to maintain valid HTML structure and accessibility compliance. ```tsx // INCORRECT usage ❌
                    // CORRECT usage ✅ ``` ### Hidden Input The `RadioGroup.ItemHiddenInput` component renders a hidden HTML input element that enables proper form submission and integration with native form behaviors. This component is essential for the radio group to function correctly as it: - Provides the underlying input element that browsers use for form submission - Enables integration with form libraries and validation systems - Ensures the radio group works with native form reset functionality ```tsx // INCORRECT usage ❌ // CORRECT usage ✅ ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. | | `disabled` | `boolean` | No | If `true`, the radio group will be disabled | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string indicator: string item: (value: string) => string itemLabel: (value: string) => string itemControl: (value: string) => string itemHiddenInput: (value: string) => string }>` | No | The ids of the elements in the radio. Useful for composition. | | `name` | `string` | No | The name of the input fields in the radio (Useful for form submission). | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called once a radio is checked | | `orientation` | `'horizontal' | 'vertical'` | No | Orientation of the radio group | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `value` | `string` | No | The controlled value of the radio group | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | root | | `[data-orientation]` | The orientation of the radio-group | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the indicator | **Indicator CSS Variables:** | Variable | Description | |----------|-------------| | `--transition-property` | The transition property value for the Indicator | | `--left` | The left position value | | `--top` | The top position value | | `--width` | The width of the element | | `--height` | The height of the element | **ItemControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | item-control | | `[data-active]` | Present when active or pressed | **ItemHiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `invalid` | `boolean` | No | | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | label | | `[data-orientation]` | The orientation of the label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRadioGroupReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. | | `disabled` | `boolean` | No | If `true`, the radio group will be disabled | | `form` | `string` | No | The associate form of the underlying input. | | `ids` | `Partial<{ root: string label: string indicator: string item: (value: string) => string itemLabel: (value: string) => string itemControl: (value: string) => string itemHiddenInput: (value: string) => string }>` | No | The ids of the elements in the radio. Useful for composition. | | `name` | `string` | No | The name of the input fields in the radio (Useful for form submission). | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called once a radio is checked | | `orientation` | `'horizontal' | 'vertical'` | No | Orientation of the radio group | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `value` | `string` | No | The controlled value of the radio group | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | root | | `[data-orientation]` | The orientation of the radio-group | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the indicator | **Indicator CSS Variables:** | Variable | Description | |----------|-------------| | `--transition-property` | The transition property value for the Indicator | | `--left` | The left position value | | `--top` | The top position value | | `--width` | The width of the element | | `--height` | The height of the element | **ItemControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | item-control | | `[data-active]` | Present when active or pressed | **ItemHiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `invalid` | `boolean` | No | | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | label | | `[data-orientation]` | The orientation of the label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRadioGroupReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. | | `disabled` | `boolean` | No | If `true`, the radio group will be disabled | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string indicator: string item(value: string): string itemLabel(value: string): string itemControl(value: string): string itemHiddenInput(value: string): string }>` | No | The ids of the elements in the radio. Useful for composition. | | `modelValue` | `string` | No | The v-model value of the radio group | | `name` | `string` | No | The name of the input fields in the radio (Useful for form submission). | | `orientation` | `'horizontal' | 'vertical'` | No | Orientation of the radio group | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | root | | `[data-orientation]` | The orientation of the radio-group | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the indicator | **Indicator CSS Variables:** | Variable | Description | |----------|-------------| | `--transition-property` | The transition property value for the Indicator | | `--left` | The left position value | | `--top` | The top position value | | `--width` | The width of the element | | `--height` | The height of the element | **ItemControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | item-control | | `[data-active]` | Present when active or pressed | **ItemHiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `invalid` | `boolean` | No | | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | label | | `[data-orientation]` | The orientation of the label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RadioGroupApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. | | `disabled` | `boolean` | No | If `true`, the radio group will be disabled | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string indicator: string item: (value: string) => string itemLabel: (value: string) => string itemControl: (value: string) => string itemHiddenInput: (value: string) => string }>` | No | The ids of the elements in the radio. Useful for composition. | | `name` | `string` | No | The name of the input fields in the radio (Useful for form submission). | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called once a radio is checked | | `orientation` | `'horizontal' | 'vertical'` | No | Orientation of the radio group | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `ref` | `Element` | No | | | `value` | `string` | No | The controlled value of the radio group | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | root | | `[data-orientation]` | The orientation of the radio-group | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the indicator | **Indicator CSS Variables:** | Variable | Description | |----------|-------------| | `--transition-property` | The transition property value for the Indicator | | `--left` | The left position value | | `--top` | The top position value | | `--width` | The width of the element | | `--height` | The height of the element | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseRadioGroupItemContext]>` | Yes | | **ItemControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | item-control | | `[data-active]` | Present when active or pressed | **ItemHiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `invalid` | `boolean` | No | | | `ref` | `Element` | No | | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | label | | `[data-orientation]` | The orientation of the label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRadioGroupReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string` | The current value of the radio group | | `setValue` | `(value: string) => void` | Function to set the value of the radio group | | `clearValue` | `VoidFunction` | Function to clear the value of the radio group | | `focus` | `VoidFunction` | Function to focus the radio group | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state details of a radio input | ## Accessibility Complies with the [Radio WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/radio/). ### Keyboard Support **`Tab`** Description: Moves focus to either the checked radio item or the first radio item in the group. **`Space`** Description: When focus is on an unchecked radio item, checks it. **`ArrowDown`** Description: Moves focus and checks the next radio item in the group. **`ArrowRight`** Description: Moves focus and checks the next radio item in the group. **`ArrowUp`** Description: Moves focus to the previous radio item in the group. **`ArrowLeft`** Description: Moves focus to the previous radio item in the group. --- # Radio Group (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { RadioGroup } from '@ark-ui/react/radio-group' import styles from 'styles/radio-group.module.css' export const Basic = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { RadioGroup } from '@ark-ui/solid/radio-group' import { For } from 'solid-js' import styles from 'styles/radio-group.module.css' export const Basic = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {(framework) => ( {framework} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#each frameworks as framework} {framework} {/each} ``` ### 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. **Example: initial-value** #### React ```tsx import { RadioGroup } from '@ark-ui/react/radio-group' import styles from 'styles/radio-group.module.css' export const InitialValue = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { RadioGroup } from '@ark-ui/solid/radio-group' import { For } from 'solid-js' import styles from 'styles/radio-group.module.css' export const InitialValue = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {(framework) => ( {framework} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#each frameworks as framework} {framework} {/each} ``` ### Controlled For a controlled Radio Group, the state is managed using the `value` prop, and updates when the `onValueChange` event handler is called: **Example: controlled** #### React ```tsx import { RadioGroup } from '@ark-ui/react/radio-group' import { useState } from 'react' import styles from 'styles/radio-group.module.css' export const Controlled = () => { const frameworks = ['React', 'Solid', 'Vue'] const [value, setValue] = useState(null) return ( setValue(e.value)}> Framework {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { RadioGroup } from '@ark-ui/solid/radio-group' import { For, createSignal } from 'solid-js' import styles from 'styles/radio-group.module.css' export const Controlled = () => { const frameworks = ['React', 'Solid', 'Vue'] const [value, setValue] = createSignal(null) return ( setValue(e.value)}> Framework {(framework) => ( {framework} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#each frameworks as framework} {framework} {/each} ``` ### 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. **Example: root-provider** #### React ```tsx import { RadioGroup, useRadioGroup } from '@ark-ui/react/radio-group' import button from 'styles/button.module.css' import styles from 'styles/radio-group.module.css' export const RootProvider = () => { const frameworks = ['React', 'Solid', 'Vue'] const radioGroup = useRadioGroup({ defaultValue: 'React' }) return (
                    Framework {frameworks.map((framework) => ( {framework} ))}
                    ) } ``` #### Solid ```tsx import { RadioGroup, useRadioGroup } from '@ark-ui/solid/radio-group' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/radio-group.module.css' export const RootProvider = () => { const frameworks = ['React', 'Solid', 'Vue'] const radioGroup = useRadioGroup({ defaultValue: 'React' }) return (
                    Framework {(framework) => ( {framework} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Framework {#each frameworks as framework} {framework} {/each}
                    ``` ### Disabled To make a radio group disabled, set the `disabled` prop to `true`. **Example: disabled** #### React ```tsx import { RadioGroup } from '@ark-ui/react/radio-group' import styles from 'styles/radio-group.module.css' export const Disabled = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { RadioGroup } from '@ark-ui/solid/radio-group' import { For } from 'solid-js' import styles from 'styles/radio-group.module.css' export const Disabled = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {(framework) => ( {framework} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#each frameworks as framework} {framework} {/each} ``` ## Guides ### asChild The `RadioGroup.Item` component renders as a `label` element by default. This ensures proper form semantics and accessibility, as radio groups are form controls that require labels to provide meaningful context for users. When using the `asChild` prop, you must **render a `label` element** as the direct child of `RadioGroup.Item` to maintain valid HTML structure and accessibility compliance. ```tsx // INCORRECT usage ❌
                    // CORRECT usage ✅ ``` ### Hidden Input The `RadioGroup.ItemHiddenInput` component renders a hidden HTML input element that enables proper form submission and integration with native form behaviors. This component is essential for the radio group to function correctly as it: - Provides the underlying input element that browsers use for form submission - Enables integration with form libraries and validation systems - Ensures the radio group works with native form reset functionality ```tsx // INCORRECT usage ❌ // CORRECT usage ✅ ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. | | `disabled` | `boolean` | No | If `true`, the radio group will be disabled | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string indicator: string item: (value: string) => string itemLabel: (value: string) => string itemControl: (value: string) => string itemHiddenInput: (value: string) => string }>` | No | The ids of the elements in the radio. Useful for composition. | | `name` | `string` | No | The name of the input fields in the radio (Useful for form submission). | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called once a radio is checked | | `orientation` | `'horizontal' | 'vertical'` | No | Orientation of the radio group | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `value` | `string` | No | The controlled value of the radio group | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | root | | `[data-orientation]` | The orientation of the radio-group | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the indicator | **Indicator CSS Variables:** | Variable | Description | |----------|-------------| | `--transition-property` | The transition property value for the Indicator | | `--left` | The left position value | | `--top` | The top position value | | `--width` | The width of the element | | `--height` | The height of the element | **ItemControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | item-control | | `[data-active]` | Present when active or pressed | **ItemHiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `invalid` | `boolean` | No | | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | label | | `[data-orientation]` | The orientation of the label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRadioGroupReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. | | `disabled` | `boolean` | No | If `true`, the radio group will be disabled | | `form` | `string` | No | The associate form of the underlying input. | | `ids` | `Partial<{ root: string label: string indicator: string item: (value: string) => string itemLabel: (value: string) => string itemControl: (value: string) => string itemHiddenInput: (value: string) => string }>` | No | The ids of the elements in the radio. Useful for composition. | | `name` | `string` | No | The name of the input fields in the radio (Useful for form submission). | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called once a radio is checked | | `orientation` | `'horizontal' | 'vertical'` | No | Orientation of the radio group | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `value` | `string` | No | The controlled value of the radio group | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | root | | `[data-orientation]` | The orientation of the radio-group | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the indicator | **Indicator CSS Variables:** | Variable | Description | |----------|-------------| | `--transition-property` | The transition property value for the Indicator | | `--left` | The left position value | | `--top` | The top position value | | `--width` | The width of the element | | `--height` | The height of the element | **ItemControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | item-control | | `[data-active]` | Present when active or pressed | **ItemHiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `invalid` | `boolean` | No | | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | label | | `[data-orientation]` | The orientation of the label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRadioGroupReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. | | `disabled` | `boolean` | No | If `true`, the radio group will be disabled | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string indicator: string item(value: string): string itemLabel(value: string): string itemControl(value: string): string itemHiddenInput(value: string): string }>` | No | The ids of the elements in the radio. Useful for composition. | | `modelValue` | `string` | No | The v-model value of the radio group | | `name` | `string` | No | The name of the input fields in the radio (Useful for form submission). | | `orientation` | `'horizontal' | 'vertical'` | No | Orientation of the radio group | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | root | | `[data-orientation]` | The orientation of the radio-group | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the indicator | **Indicator CSS Variables:** | Variable | Description | |----------|-------------| | `--transition-property` | The transition property value for the Indicator | | `--left` | The left position value | | `--top` | The top position value | | `--width` | The width of the element | | `--height` | The height of the element | **ItemControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | item-control | | `[data-active]` | Present when active or pressed | **ItemHiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `invalid` | `boolean` | No | | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | label | | `[data-orientation]` | The orientation of the label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RadioGroupApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. | | `disabled` | `boolean` | No | If `true`, the radio group will be disabled | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string indicator: string item: (value: string) => string itemLabel: (value: string) => string itemControl: (value: string) => string itemHiddenInput: (value: string) => string }>` | No | The ids of the elements in the radio. Useful for composition. | | `name` | `string` | No | The name of the input fields in the radio (Useful for form submission). | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called once a radio is checked | | `orientation` | `'horizontal' | 'vertical'` | No | Orientation of the radio group | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `ref` | `Element` | No | | | `value` | `string` | No | The controlled value of the radio group | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | root | | `[data-orientation]` | The orientation of the radio-group | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the indicator | **Indicator CSS Variables:** | Variable | Description | |----------|-------------| | `--transition-property` | The transition property value for the Indicator | | `--left` | The left position value | | `--top` | The top position value | | `--width` | The width of the element | | `--height` | The height of the element | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseRadioGroupItemContext]>` | Yes | | **ItemControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | item-control | | `[data-active]` | Present when active or pressed | **ItemHiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `invalid` | `boolean` | No | | | `ref` | `Element` | No | | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | label | | `[data-orientation]` | The orientation of the label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRadioGroupReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string` | The current value of the radio group | | `setValue` | `(value: string) => void` | Function to set the value of the radio group | | `clearValue` | `VoidFunction` | Function to clear the value of the radio group | | `focus` | `VoidFunction` | Function to focus the radio group | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state details of a radio input | ## Accessibility Complies with the [Radio WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/radio/). ### Keyboard Support **`Tab`** Description: Moves focus to either the checked radio item or the first radio item in the group. **`Space`** Description: When focus is on an unchecked radio item, checks it. **`ArrowDown`** Description: Moves focus and checks the next radio item in the group. **`ArrowRight`** Description: Moves focus and checks the next radio item in the group. **`ArrowUp`** Description: Moves focus to the previous radio item in the group. **`ArrowLeft`** Description: Moves focus to the previous radio item in the group. --- # Radio Group (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { RadioGroup } from '@ark-ui/react/radio-group' import styles from 'styles/radio-group.module.css' export const Basic = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { RadioGroup } from '@ark-ui/solid/radio-group' import { For } from 'solid-js' import styles from 'styles/radio-group.module.css' export const Basic = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {(framework) => ( {framework} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#each frameworks as framework} {framework} {/each} ``` ### 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. **Example: initial-value** #### React ```tsx import { RadioGroup } from '@ark-ui/react/radio-group' import styles from 'styles/radio-group.module.css' export const InitialValue = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { RadioGroup } from '@ark-ui/solid/radio-group' import { For } from 'solid-js' import styles from 'styles/radio-group.module.css' export const InitialValue = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {(framework) => ( {framework} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#each frameworks as framework} {framework} {/each} ``` ### Controlled For a controlled Radio Group, the state is managed using the `value` prop, and updates when the `onValueChange` event handler is called: **Example: controlled** #### React ```tsx import { RadioGroup } from '@ark-ui/react/radio-group' import { useState } from 'react' import styles from 'styles/radio-group.module.css' export const Controlled = () => { const frameworks = ['React', 'Solid', 'Vue'] const [value, setValue] = useState(null) return ( setValue(e.value)}> Framework {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { RadioGroup } from '@ark-ui/solid/radio-group' import { For, createSignal } from 'solid-js' import styles from 'styles/radio-group.module.css' export const Controlled = () => { const frameworks = ['React', 'Solid', 'Vue'] const [value, setValue] = createSignal(null) return ( setValue(e.value)}> Framework {(framework) => ( {framework} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#each frameworks as framework} {framework} {/each} ``` ### 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. **Example: root-provider** #### React ```tsx import { RadioGroup, useRadioGroup } from '@ark-ui/react/radio-group' import button from 'styles/button.module.css' import styles from 'styles/radio-group.module.css' export const RootProvider = () => { const frameworks = ['React', 'Solid', 'Vue'] const radioGroup = useRadioGroup({ defaultValue: 'React' }) return (
                    Framework {frameworks.map((framework) => ( {framework} ))}
                    ) } ``` #### Solid ```tsx import { RadioGroup, useRadioGroup } from '@ark-ui/solid/radio-group' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/radio-group.module.css' export const RootProvider = () => { const frameworks = ['React', 'Solid', 'Vue'] const radioGroup = useRadioGroup({ defaultValue: 'React' }) return (
                    Framework {(framework) => ( {framework} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Framework {#each frameworks as framework} {framework} {/each}
                    ``` ### Disabled To make a radio group disabled, set the `disabled` prop to `true`. **Example: disabled** #### React ```tsx import { RadioGroup } from '@ark-ui/react/radio-group' import styles from 'styles/radio-group.module.css' export const Disabled = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { RadioGroup } from '@ark-ui/solid/radio-group' import { For } from 'solid-js' import styles from 'styles/radio-group.module.css' export const Disabled = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {(framework) => ( {framework} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#each frameworks as framework} {framework} {/each} ``` ## Guides ### asChild The `RadioGroup.Item` component renders as a `label` element by default. This ensures proper form semantics and accessibility, as radio groups are form controls that require labels to provide meaningful context for users. When using the `asChild` prop, you must **render a `label` element** as the direct child of `RadioGroup.Item` to maintain valid HTML structure and accessibility compliance. ```tsx // INCORRECT usage ❌
                    // CORRECT usage ✅ ``` ### Hidden Input The `RadioGroup.ItemHiddenInput` component renders a hidden HTML input element that enables proper form submission and integration with native form behaviors. This component is essential for the radio group to function correctly as it: - Provides the underlying input element that browsers use for form submission - Enables integration with form libraries and validation systems - Ensures the radio group works with native form reset functionality ```tsx // INCORRECT usage ❌ // CORRECT usage ✅ ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. | | `disabled` | `boolean` | No | If `true`, the radio group will be disabled | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string indicator: string item: (value: string) => string itemLabel: (value: string) => string itemControl: (value: string) => string itemHiddenInput: (value: string) => string }>` | No | The ids of the elements in the radio. Useful for composition. | | `name` | `string` | No | The name of the input fields in the radio (Useful for form submission). | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called once a radio is checked | | `orientation` | `'horizontal' | 'vertical'` | No | Orientation of the radio group | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `value` | `string` | No | The controlled value of the radio group | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | root | | `[data-orientation]` | The orientation of the radio-group | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the indicator | **Indicator CSS Variables:** | Variable | Description | |----------|-------------| | `--transition-property` | The transition property value for the Indicator | | `--left` | The left position value | | `--top` | The top position value | | `--width` | The width of the element | | `--height` | The height of the element | **ItemControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | item-control | | `[data-active]` | Present when active or pressed | **ItemHiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `invalid` | `boolean` | No | | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | label | | `[data-orientation]` | The orientation of the label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRadioGroupReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. | | `disabled` | `boolean` | No | If `true`, the radio group will be disabled | | `form` | `string` | No | The associate form of the underlying input. | | `ids` | `Partial<{ root: string label: string indicator: string item: (value: string) => string itemLabel: (value: string) => string itemControl: (value: string) => string itemHiddenInput: (value: string) => string }>` | No | The ids of the elements in the radio. Useful for composition. | | `name` | `string` | No | The name of the input fields in the radio (Useful for form submission). | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called once a radio is checked | | `orientation` | `'horizontal' | 'vertical'` | No | Orientation of the radio group | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `value` | `string` | No | The controlled value of the radio group | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | root | | `[data-orientation]` | The orientation of the radio-group | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the indicator | **Indicator CSS Variables:** | Variable | Description | |----------|-------------| | `--transition-property` | The transition property value for the Indicator | | `--left` | The left position value | | `--top` | The top position value | | `--width` | The width of the element | | `--height` | The height of the element | **ItemControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | item-control | | `[data-active]` | Present when active or pressed | **ItemHiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `invalid` | `boolean` | No | | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | label | | `[data-orientation]` | The orientation of the label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRadioGroupReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. | | `disabled` | `boolean` | No | If `true`, the radio group will be disabled | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string indicator: string item(value: string): string itemLabel(value: string): string itemControl(value: string): string itemHiddenInput(value: string): string }>` | No | The ids of the elements in the radio. Useful for composition. | | `modelValue` | `string` | No | The v-model value of the radio group | | `name` | `string` | No | The name of the input fields in the radio (Useful for form submission). | | `orientation` | `'horizontal' | 'vertical'` | No | Orientation of the radio group | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | root | | `[data-orientation]` | The orientation of the radio-group | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the indicator | **Indicator CSS Variables:** | Variable | Description | |----------|-------------| | `--transition-property` | The transition property value for the Indicator | | `--left` | The left position value | | `--top` | The top position value | | `--width` | The width of the element | | `--height` | The height of the element | **ItemControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | item-control | | `[data-active]` | Present when active or pressed | **ItemHiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `invalid` | `boolean` | No | | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | label | | `[data-orientation]` | The orientation of the label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RadioGroupApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. | | `disabled` | `boolean` | No | If `true`, the radio group will be disabled | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string indicator: string item: (value: string) => string itemLabel: (value: string) => string itemControl: (value: string) => string itemHiddenInput: (value: string) => string }>` | No | The ids of the elements in the radio. Useful for composition. | | `name` | `string` | No | The name of the input fields in the radio (Useful for form submission). | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called once a radio is checked | | `orientation` | `'horizontal' | 'vertical'` | No | Orientation of the radio group | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `ref` | `Element` | No | | | `value` | `string` | No | The controlled value of the radio group | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | root | | `[data-orientation]` | The orientation of the radio-group | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the indicator | **Indicator CSS Variables:** | Variable | Description | |----------|-------------| | `--transition-property` | The transition property value for the Indicator | | `--left` | The left position value | | `--top` | The top position value | | `--width` | The width of the element | | `--height` | The height of the element | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseRadioGroupItemContext]>` | Yes | | **ItemControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | item-control | | `[data-active]` | Present when active or pressed | **ItemHiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `invalid` | `boolean` | No | | | `ref` | `Element` | No | | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | label | | `[data-orientation]` | The orientation of the label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRadioGroupReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string` | The current value of the radio group | | `setValue` | `(value: string) => void` | Function to set the value of the radio group | | `clearValue` | `VoidFunction` | Function to clear the value of the radio group | | `focus` | `VoidFunction` | Function to focus the radio group | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state details of a radio input | ## Accessibility Complies with the [Radio WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/radio/). ### Keyboard Support **`Tab`** Description: Moves focus to either the checked radio item or the first radio item in the group. **`Space`** Description: When focus is on an unchecked radio item, checks it. **`ArrowDown`** Description: Moves focus and checks the next radio item in the group. **`ArrowRight`** Description: Moves focus and checks the next radio item in the group. **`ArrowUp`** Description: Moves focus to the previous radio item in the group. **`ArrowLeft`** Description: Moves focus to the previous radio item in the group. --- # Radio Group (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { RadioGroup } from '@ark-ui/react/radio-group' import styles from 'styles/radio-group.module.css' export const Basic = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { RadioGroup } from '@ark-ui/solid/radio-group' import { For } from 'solid-js' import styles from 'styles/radio-group.module.css' export const Basic = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {(framework) => ( {framework} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#each frameworks as framework} {framework} {/each} ``` ### 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. **Example: initial-value** #### React ```tsx import { RadioGroup } from '@ark-ui/react/radio-group' import styles from 'styles/radio-group.module.css' export const InitialValue = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { RadioGroup } from '@ark-ui/solid/radio-group' import { For } from 'solid-js' import styles from 'styles/radio-group.module.css' export const InitialValue = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {(framework) => ( {framework} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#each frameworks as framework} {framework} {/each} ``` ### Controlled For a controlled Radio Group, the state is managed using the `value` prop, and updates when the `onValueChange` event handler is called: **Example: controlled** #### React ```tsx import { RadioGroup } from '@ark-ui/react/radio-group' import { useState } from 'react' import styles from 'styles/radio-group.module.css' export const Controlled = () => { const frameworks = ['React', 'Solid', 'Vue'] const [value, setValue] = useState(null) return ( setValue(e.value)}> Framework {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { RadioGroup } from '@ark-ui/solid/radio-group' import { For, createSignal } from 'solid-js' import styles from 'styles/radio-group.module.css' export const Controlled = () => { const frameworks = ['React', 'Solid', 'Vue'] const [value, setValue] = createSignal(null) return ( setValue(e.value)}> Framework {(framework) => ( {framework} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#each frameworks as framework} {framework} {/each} ``` ### 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. **Example: root-provider** #### React ```tsx import { RadioGroup, useRadioGroup } from '@ark-ui/react/radio-group' import button from 'styles/button.module.css' import styles from 'styles/radio-group.module.css' export const RootProvider = () => { const frameworks = ['React', 'Solid', 'Vue'] const radioGroup = useRadioGroup({ defaultValue: 'React' }) return (
                    Framework {frameworks.map((framework) => ( {framework} ))}
                    ) } ``` #### Solid ```tsx import { RadioGroup, useRadioGroup } from '@ark-ui/solid/radio-group' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/radio-group.module.css' export const RootProvider = () => { const frameworks = ['React', 'Solid', 'Vue'] const radioGroup = useRadioGroup({ defaultValue: 'React' }) return (
                    Framework {(framework) => ( {framework} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Framework {#each frameworks as framework} {framework} {/each}
                    ``` ### Disabled To make a radio group disabled, set the `disabled` prop to `true`. **Example: disabled** #### React ```tsx import { RadioGroup } from '@ark-ui/react/radio-group' import styles from 'styles/radio-group.module.css' export const Disabled = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { RadioGroup } from '@ark-ui/solid/radio-group' import { For } from 'solid-js' import styles from 'styles/radio-group.module.css' export const Disabled = () => { const frameworks = ['React', 'Solid', 'Vue'] return ( Framework {(framework) => ( {framework} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#each frameworks as framework} {framework} {/each} ``` ## Guides ### asChild The `RadioGroup.Item` component renders as a `label` element by default. This ensures proper form semantics and accessibility, as radio groups are form controls that require labels to provide meaningful context for users. When using the `asChild` prop, you must **render a `label` element** as the direct child of `RadioGroup.Item` to maintain valid HTML structure and accessibility compliance. ```tsx // INCORRECT usage ❌
                    // CORRECT usage ✅ ``` ### Hidden Input The `RadioGroup.ItemHiddenInput` component renders a hidden HTML input element that enables proper form submission and integration with native form behaviors. This component is essential for the radio group to function correctly as it: - Provides the underlying input element that browsers use for form submission - Enables integration with form libraries and validation systems - Ensures the radio group works with native form reset functionality ```tsx // INCORRECT usage ❌ // CORRECT usage ✅ ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. | | `disabled` | `boolean` | No | If `true`, the radio group will be disabled | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string indicator: string item: (value: string) => string itemLabel: (value: string) => string itemControl: (value: string) => string itemHiddenInput: (value: string) => string }>` | No | The ids of the elements in the radio. Useful for composition. | | `name` | `string` | No | The name of the input fields in the radio (Useful for form submission). | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called once a radio is checked | | `orientation` | `'horizontal' | 'vertical'` | No | Orientation of the radio group | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `value` | `string` | No | The controlled value of the radio group | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | root | | `[data-orientation]` | The orientation of the radio-group | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the indicator | **Indicator CSS Variables:** | Variable | Description | |----------|-------------| | `--transition-property` | The transition property value for the Indicator | | `--left` | The left position value | | `--top` | The top position value | | `--width` | The width of the element | | `--height` | The height of the element | **ItemControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | item-control | | `[data-active]` | Present when active or pressed | **ItemHiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `invalid` | `boolean` | No | | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | label | | `[data-orientation]` | The orientation of the label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRadioGroupReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. | | `disabled` | `boolean` | No | If `true`, the radio group will be disabled | | `form` | `string` | No | The associate form of the underlying input. | | `ids` | `Partial<{ root: string label: string indicator: string item: (value: string) => string itemLabel: (value: string) => string itemControl: (value: string) => string itemHiddenInput: (value: string) => string }>` | No | The ids of the elements in the radio. Useful for composition. | | `name` | `string` | No | The name of the input fields in the radio (Useful for form submission). | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called once a radio is checked | | `orientation` | `'horizontal' | 'vertical'` | No | Orientation of the radio group | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `value` | `string` | No | The controlled value of the radio group | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | root | | `[data-orientation]` | The orientation of the radio-group | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the indicator | **Indicator CSS Variables:** | Variable | Description | |----------|-------------| | `--transition-property` | The transition property value for the Indicator | | `--left` | The left position value | | `--top` | The top position value | | `--width` | The width of the element | | `--height` | The height of the element | **ItemControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | item-control | | `[data-active]` | Present when active or pressed | **ItemHiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `invalid` | `boolean` | No | | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | label | | `[data-orientation]` | The orientation of the label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRadioGroupReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. | | `disabled` | `boolean` | No | If `true`, the radio group will be disabled | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string indicator: string item(value: string): string itemLabel(value: string): string itemControl(value: string): string itemHiddenInput(value: string): string }>` | No | The ids of the elements in the radio. Useful for composition. | | `modelValue` | `string` | No | The v-model value of the radio group | | `name` | `string` | No | The name of the input fields in the radio (Useful for form submission). | | `orientation` | `'horizontal' | 'vertical'` | No | Orientation of the radio group | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | root | | `[data-orientation]` | The orientation of the radio-group | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the indicator | **Indicator CSS Variables:** | Variable | Description | |----------|-------------| | `--transition-property` | The transition property value for the Indicator | | `--left` | The left position value | | `--top` | The top position value | | `--width` | The width of the element | | `--height` | The height of the element | **ItemControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | item-control | | `[data-active]` | Present when active or pressed | **ItemHiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `invalid` | `boolean` | No | | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | label | | `[data-orientation]` | The orientation of the label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RadioGroupApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string` | No | The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. | | `disabled` | `boolean` | No | If `true`, the radio group will be disabled | | `form` | `string` | No | The associate form of the underlying input. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string indicator: string item: (value: string) => string itemLabel: (value: string) => string itemControl: (value: string) => string itemHiddenInput: (value: string) => string }>` | No | The ids of the elements in the radio. Useful for composition. | | `name` | `string` | No | The name of the input fields in the radio (Useful for form submission). | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function called once a radio is checked | | `orientation` | `'horizontal' | 'vertical'` | No | Orientation of the radio group | | `readOnly` | `boolean` | No | Whether the checkbox is read-only | | `ref` | `Element` | No | | | `value` | `string` | No | The controlled value of the radio group | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | root | | `[data-orientation]` | The orientation of the radio-group | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the indicator | **Indicator CSS Variables:** | Variable | Description | |----------|-------------| | `--transition-property` | The transition property value for the Indicator | | `--left` | The left position value | | `--top` | The top position value | | `--width` | The width of the element | | `--height` | The height of the element | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseRadioGroupItemContext]>` | Yes | | **ItemControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | item-control | | `[data-active]` | Present when active or pressed | **ItemHiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `invalid` | `boolean` | No | | | `ref` | `Element` | No | | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | radio-group | | `[data-part]` | label | | `[data-orientation]` | The orientation of the label | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRadioGroupReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string` | The current value of the radio group | | `setValue` | `(value: string) => void` | Function to set the value of the radio group | | `clearValue` | `VoidFunction` | Function to clear the value of the radio group | | `focus` | `VoidFunction` | Function to focus the radio group | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state details of a radio input | ## Accessibility Complies with the [Radio WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/radio/). ### Keyboard Support **`Tab`** Description: Moves focus to either the checked radio item or the first radio item in the group. **`Space`** Description: When focus is on an unchecked radio item, checks it. **`ArrowDown`** Description: Moves focus and checks the next radio item in the group. **`ArrowRight`** Description: Moves focus and checks the next radio item in the group. **`ArrowUp`** Description: Moves focus to the previous radio item in the group. **`ArrowLeft`** Description: Moves focus to the previous radio item in the group. --- # Rating Group (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' export const Basic = () => ( Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) } ) ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const Basic = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ### Controlled When using the `RatingGroup` component, you can use the `value` and `onValueChange` props to control the state. **Example: controlled** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/rating-group.module.css' export const Controlled = () => { const [value, setValue] = useState(0) return ( setValue(details.value)}> Label {({ items }) => items.map((item) => ( {({ half, highlighted }) => ( )} )) } ) } ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/rating-group.module.css' export const Controlled = () => { const [value, setValue] = createSignal(0) return ( setValue(details.value)}> Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ### 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. **Example: root-provider** #### React ```tsx import { RatingGroup, useRatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' export const RootProvider = () => { const ratingGroup = useRatingGroup({ count: 5, defaultValue: 3 }) return (
                    value: {ratingGroup.value} Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) }
                    ) } ``` #### Solid ```tsx import { RatingGroup, useRatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const RootProvider = () => { const ratingGroup = useRatingGroup({ defaultValue: 3 }) return (
                    value: {ratingGroup().value} Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    value: {ratingGroup().value} Label {#snippet render(context)} {#each context().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet}
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/rating-group.module.css' export const WithField = () => ( Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) } Additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/rating-group.module.css' export const WithField = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} Additional Info Error Info ``` ### 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. **Example: half-star** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' export const HalfStar = () => ( Label {({ items }) => items.map((item) => ( {({ half, highlighted }) => ( )} )) } ) ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const HalfStar = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ### 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. **Example: form-usage** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' import button from 'styles/button.module.css' export const FormUsage = () => (
                    { e.preventDefault() const formData = new FormData(e.currentTarget) alert(`Rating value: ${formData.get('review')}`) }} > Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) }
                    ) ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const FormUsage = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ### Disabled To make the rating group disabled, set the `disabled` prop to `true`. **Example: disabled** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' export const Disabled = () => ( Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) } ) ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const Disabled = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowHalf` | `boolean` | No | Whether to allow half stars. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the rating. | | `count` | `number` | No | The total number of ratings. | | `defaultValue` | `number` | No | The initial value of the rating when rendered. Use when you don't need to control the value of the rating. | | `disabled` | `boolean` | No | Whether the rating is disabled. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string hiddenInput: string control: string item: (id: string) => string }>` | No | The ids of the elements in the rating. Useful for composition. | | `name` | `string` | No | The name attribute of the rating element (used in forms). | | `onHoverChange` | `(details: HoverChangeDetails) => void` | No | Function to be called when the rating value is hovered. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to be called when the rating value changes. | | `readOnly` | `boolean` | No | Whether the rating is readonly. | | `required` | `boolean` | No | Whether the rating is required. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `number` | No | The controlled value of the rating | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | control | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-checked]` | Present when checked | | `[data-highlighted]` | Present when highlighted | | `[data-half]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRatingGroupReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowHalf` | `boolean` | No | Whether to allow half stars. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the rating. | | `count` | `number` | No | The total number of ratings. | | `defaultValue` | `number` | No | The initial value of the rating when rendered. Use when you don't need to control the value of the rating. | | `disabled` | `boolean` | No | Whether the rating is disabled. | | `form` | `string` | No | The associate form of the underlying input element. | | `ids` | `Partial<{ root: string label: string hiddenInput: string control: string item: (id: string) => string }>` | No | The ids of the elements in the rating. Useful for composition. | | `name` | `string` | No | The name attribute of the rating element (used in forms). | | `onHoverChange` | `(details: HoverChangeDetails) => void` | No | Function to be called when the rating value is hovered. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to be called when the rating value changes. | | `readOnly` | `boolean` | No | Whether the rating is readonly. | | `required` | `boolean` | No | Whether the rating is required. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `number` | No | The controlled value of the rating | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | control | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-checked]` | Present when checked | | `[data-highlighted]` | Present when highlighted | | `[data-half]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRatingGroupReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowHalf` | `boolean` | No | Whether to allow half stars. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the rating. | | `count` | `number` | No | The total number of ratings. | | `defaultValue` | `number` | No | The initial value of the rating when rendered. Use when you don't need to control the value of the rating. | | `disabled` | `boolean` | No | Whether the rating is disabled. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string hiddenInput: string control: string item(id: string): string }>` | No | The ids of the elements in the rating. Useful for composition. | | `modelValue` | `number` | No | The v-model value of the rating group | | `name` | `string` | No | The name attribute of the rating element (used in forms). | | `readOnly` | `boolean` | No | Whether the rating is readonly. | | `required` | `boolean` | No | Whether the rating is required. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | control | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-checked]` | Present when checked | | `[data-highlighted]` | Present when highlighted | | `[data-half]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RatingGroupApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowHalf` | `boolean` | No | Whether to allow half stars. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the rating. | | `count` | `number` | No | The total number of ratings. | | `defaultValue` | `number` | No | The initial value of the rating when rendered. Use when you don't need to control the value of the rating. | | `disabled` | `boolean` | No | Whether the rating is disabled. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string hiddenInput: string control: string item: (id: string) => string }>` | No | The ids of the elements in the rating. Useful for composition. | | `name` | `string` | No | The name attribute of the rating element (used in forms). | | `onHoverChange` | `(details: HoverChangeDetails) => void` | No | Function to be called when the rating value is hovered. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to be called when the rating value changes. | | `readOnly` | `boolean` | No | Whether the rating is readonly. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the rating is required. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `number` | No | The controlled value of the rating | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseRatingGroupContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | control | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseRatingGroupItemContext]>` | Yes | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-checked]` | Present when checked | | `[data-highlighted]` | Present when highlighted | | `[data-half]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRatingGroupReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `setValue` | `(value: number) => void` | Sets the value of the rating group | | `clearValue` | `VoidFunction` | Clears the value of the rating group | | `hovering` | `boolean` | Whether the rating group is being hovered | | `value` | `number` | The current value of the rating group | | `hoveredValue` | `number` | The value of the currently hovered rating | | `count` | `number` | The total number of ratings | | `items` | `number[]` | The array of rating values. Returns an array of numbers from 1 to the max value. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a rating item | ## Accessibility ### Keyboard Support **`ArrowRight`** Description: Moves focus to the next star, increasing the rating value based on the `allowHalf` property. **`ArrowLeft`** Description: Moves focus to the previous star, decreasing the rating value based on the `allowHalf` property. **`Enter`** Description: Selects the focused star in the rating group. --- # Rating Group (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' export const Basic = () => ( Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) } ) ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const Basic = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ### Controlled When using the `RatingGroup` component, you can use the `value` and `onValueChange` props to control the state. **Example: controlled** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/rating-group.module.css' export const Controlled = () => { const [value, setValue] = useState(0) return ( setValue(details.value)}> Label {({ items }) => items.map((item) => ( {({ half, highlighted }) => ( )} )) } ) } ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/rating-group.module.css' export const Controlled = () => { const [value, setValue] = createSignal(0) return ( setValue(details.value)}> Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ### 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. **Example: root-provider** #### React ```tsx import { RatingGroup, useRatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' export const RootProvider = () => { const ratingGroup = useRatingGroup({ count: 5, defaultValue: 3 }) return (
                    value: {ratingGroup.value} Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) }
                    ) } ``` #### Solid ```tsx import { RatingGroup, useRatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const RootProvider = () => { const ratingGroup = useRatingGroup({ defaultValue: 3 }) return (
                    value: {ratingGroup().value} Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    value: {ratingGroup().value} Label {#snippet render(context)} {#each context().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet}
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/rating-group.module.css' export const WithField = () => ( Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) } Additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/rating-group.module.css' export const WithField = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} Additional Info Error Info ``` ### 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. **Example: half-star** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' export const HalfStar = () => ( Label {({ items }) => items.map((item) => ( {({ half, highlighted }) => ( )} )) } ) ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const HalfStar = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ### 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. **Example: form-usage** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' import button from 'styles/button.module.css' export const FormUsage = () => (
                    { e.preventDefault() const formData = new FormData(e.currentTarget) alert(`Rating value: ${formData.get('review')}`) }} > Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) }
                    ) ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const FormUsage = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ### Disabled To make the rating group disabled, set the `disabled` prop to `true`. **Example: disabled** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' export const Disabled = () => ( Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) } ) ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const Disabled = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowHalf` | `boolean` | No | Whether to allow half stars. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the rating. | | `count` | `number` | No | The total number of ratings. | | `defaultValue` | `number` | No | The initial value of the rating when rendered. Use when you don't need to control the value of the rating. | | `disabled` | `boolean` | No | Whether the rating is disabled. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string hiddenInput: string control: string item: (id: string) => string }>` | No | The ids of the elements in the rating. Useful for composition. | | `name` | `string` | No | The name attribute of the rating element (used in forms). | | `onHoverChange` | `(details: HoverChangeDetails) => void` | No | Function to be called when the rating value is hovered. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to be called when the rating value changes. | | `readOnly` | `boolean` | No | Whether the rating is readonly. | | `required` | `boolean` | No | Whether the rating is required. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `number` | No | The controlled value of the rating | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | control | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-checked]` | Present when checked | | `[data-highlighted]` | Present when highlighted | | `[data-half]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRatingGroupReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowHalf` | `boolean` | No | Whether to allow half stars. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the rating. | | `count` | `number` | No | The total number of ratings. | | `defaultValue` | `number` | No | The initial value of the rating when rendered. Use when you don't need to control the value of the rating. | | `disabled` | `boolean` | No | Whether the rating is disabled. | | `form` | `string` | No | The associate form of the underlying input element. | | `ids` | `Partial<{ root: string label: string hiddenInput: string control: string item: (id: string) => string }>` | No | The ids of the elements in the rating. Useful for composition. | | `name` | `string` | No | The name attribute of the rating element (used in forms). | | `onHoverChange` | `(details: HoverChangeDetails) => void` | No | Function to be called when the rating value is hovered. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to be called when the rating value changes. | | `readOnly` | `boolean` | No | Whether the rating is readonly. | | `required` | `boolean` | No | Whether the rating is required. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `number` | No | The controlled value of the rating | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | control | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-checked]` | Present when checked | | `[data-highlighted]` | Present when highlighted | | `[data-half]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRatingGroupReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowHalf` | `boolean` | No | Whether to allow half stars. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the rating. | | `count` | `number` | No | The total number of ratings. | | `defaultValue` | `number` | No | The initial value of the rating when rendered. Use when you don't need to control the value of the rating. | | `disabled` | `boolean` | No | Whether the rating is disabled. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string hiddenInput: string control: string item(id: string): string }>` | No | The ids of the elements in the rating. Useful for composition. | | `modelValue` | `number` | No | The v-model value of the rating group | | `name` | `string` | No | The name attribute of the rating element (used in forms). | | `readOnly` | `boolean` | No | Whether the rating is readonly. | | `required` | `boolean` | No | Whether the rating is required. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | control | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-checked]` | Present when checked | | `[data-highlighted]` | Present when highlighted | | `[data-half]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RatingGroupApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowHalf` | `boolean` | No | Whether to allow half stars. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the rating. | | `count` | `number` | No | The total number of ratings. | | `defaultValue` | `number` | No | The initial value of the rating when rendered. Use when you don't need to control the value of the rating. | | `disabled` | `boolean` | No | Whether the rating is disabled. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string hiddenInput: string control: string item: (id: string) => string }>` | No | The ids of the elements in the rating. Useful for composition. | | `name` | `string` | No | The name attribute of the rating element (used in forms). | | `onHoverChange` | `(details: HoverChangeDetails) => void` | No | Function to be called when the rating value is hovered. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to be called when the rating value changes. | | `readOnly` | `boolean` | No | Whether the rating is readonly. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the rating is required. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `number` | No | The controlled value of the rating | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseRatingGroupContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | control | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseRatingGroupItemContext]>` | Yes | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-checked]` | Present when checked | | `[data-highlighted]` | Present when highlighted | | `[data-half]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRatingGroupReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `setValue` | `(value: number) => void` | Sets the value of the rating group | | `clearValue` | `VoidFunction` | Clears the value of the rating group | | `hovering` | `boolean` | Whether the rating group is being hovered | | `value` | `number` | The current value of the rating group | | `hoveredValue` | `number` | The value of the currently hovered rating | | `count` | `number` | The total number of ratings | | `items` | `number[]` | The array of rating values. Returns an array of numbers from 1 to the max value. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a rating item | ## Accessibility ### Keyboard Support **`ArrowRight`** Description: Moves focus to the next star, increasing the rating value based on the `allowHalf` property. **`ArrowLeft`** Description: Moves focus to the previous star, decreasing the rating value based on the `allowHalf` property. **`Enter`** Description: Selects the focused star in the rating group. --- # Rating Group (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' export const Basic = () => ( Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) } ) ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const Basic = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ### Controlled When using the `RatingGroup` component, you can use the `value` and `onValueChange` props to control the state. **Example: controlled** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/rating-group.module.css' export const Controlled = () => { const [value, setValue] = useState(0) return ( setValue(details.value)}> Label {({ items }) => items.map((item) => ( {({ half, highlighted }) => ( )} )) } ) } ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/rating-group.module.css' export const Controlled = () => { const [value, setValue] = createSignal(0) return ( setValue(details.value)}> Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ### 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. **Example: root-provider** #### React ```tsx import { RatingGroup, useRatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' export const RootProvider = () => { const ratingGroup = useRatingGroup({ count: 5, defaultValue: 3 }) return (
                    value: {ratingGroup.value} Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) }
                    ) } ``` #### Solid ```tsx import { RatingGroup, useRatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const RootProvider = () => { const ratingGroup = useRatingGroup({ defaultValue: 3 }) return (
                    value: {ratingGroup().value} Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    value: {ratingGroup().value} Label {#snippet render(context)} {#each context().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet}
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/rating-group.module.css' export const WithField = () => ( Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) } Additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/rating-group.module.css' export const WithField = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} Additional Info Error Info ``` ### 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. **Example: half-star** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' export const HalfStar = () => ( Label {({ items }) => items.map((item) => ( {({ half, highlighted }) => ( )} )) } ) ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const HalfStar = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ### 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. **Example: form-usage** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' import button from 'styles/button.module.css' export const FormUsage = () => (
                    { e.preventDefault() const formData = new FormData(e.currentTarget) alert(`Rating value: ${formData.get('review')}`) }} > Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) }
                    ) ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const FormUsage = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ### Disabled To make the rating group disabled, set the `disabled` prop to `true`. **Example: disabled** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' export const Disabled = () => ( Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) } ) ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const Disabled = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowHalf` | `boolean` | No | Whether to allow half stars. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the rating. | | `count` | `number` | No | The total number of ratings. | | `defaultValue` | `number` | No | The initial value of the rating when rendered. Use when you don't need to control the value of the rating. | | `disabled` | `boolean` | No | Whether the rating is disabled. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string hiddenInput: string control: string item: (id: string) => string }>` | No | The ids of the elements in the rating. Useful for composition. | | `name` | `string` | No | The name attribute of the rating element (used in forms). | | `onHoverChange` | `(details: HoverChangeDetails) => void` | No | Function to be called when the rating value is hovered. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to be called when the rating value changes. | | `readOnly` | `boolean` | No | Whether the rating is readonly. | | `required` | `boolean` | No | Whether the rating is required. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `number` | No | The controlled value of the rating | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | control | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-checked]` | Present when checked | | `[data-highlighted]` | Present when highlighted | | `[data-half]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRatingGroupReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowHalf` | `boolean` | No | Whether to allow half stars. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the rating. | | `count` | `number` | No | The total number of ratings. | | `defaultValue` | `number` | No | The initial value of the rating when rendered. Use when you don't need to control the value of the rating. | | `disabled` | `boolean` | No | Whether the rating is disabled. | | `form` | `string` | No | The associate form of the underlying input element. | | `ids` | `Partial<{ root: string label: string hiddenInput: string control: string item: (id: string) => string }>` | No | The ids of the elements in the rating. Useful for composition. | | `name` | `string` | No | The name attribute of the rating element (used in forms). | | `onHoverChange` | `(details: HoverChangeDetails) => void` | No | Function to be called when the rating value is hovered. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to be called when the rating value changes. | | `readOnly` | `boolean` | No | Whether the rating is readonly. | | `required` | `boolean` | No | Whether the rating is required. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `number` | No | The controlled value of the rating | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | control | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-checked]` | Present when checked | | `[data-highlighted]` | Present when highlighted | | `[data-half]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRatingGroupReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowHalf` | `boolean` | No | Whether to allow half stars. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the rating. | | `count` | `number` | No | The total number of ratings. | | `defaultValue` | `number` | No | The initial value of the rating when rendered. Use when you don't need to control the value of the rating. | | `disabled` | `boolean` | No | Whether the rating is disabled. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string hiddenInput: string control: string item(id: string): string }>` | No | The ids of the elements in the rating. Useful for composition. | | `modelValue` | `number` | No | The v-model value of the rating group | | `name` | `string` | No | The name attribute of the rating element (used in forms). | | `readOnly` | `boolean` | No | Whether the rating is readonly. | | `required` | `boolean` | No | Whether the rating is required. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | control | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-checked]` | Present when checked | | `[data-highlighted]` | Present when highlighted | | `[data-half]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RatingGroupApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowHalf` | `boolean` | No | Whether to allow half stars. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the rating. | | `count` | `number` | No | The total number of ratings. | | `defaultValue` | `number` | No | The initial value of the rating when rendered. Use when you don't need to control the value of the rating. | | `disabled` | `boolean` | No | Whether the rating is disabled. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string hiddenInput: string control: string item: (id: string) => string }>` | No | The ids of the elements in the rating. Useful for composition. | | `name` | `string` | No | The name attribute of the rating element (used in forms). | | `onHoverChange` | `(details: HoverChangeDetails) => void` | No | Function to be called when the rating value is hovered. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to be called when the rating value changes. | | `readOnly` | `boolean` | No | Whether the rating is readonly. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the rating is required. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `number` | No | The controlled value of the rating | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseRatingGroupContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | control | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseRatingGroupItemContext]>` | Yes | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-checked]` | Present when checked | | `[data-highlighted]` | Present when highlighted | | `[data-half]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRatingGroupReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `setValue` | `(value: number) => void` | Sets the value of the rating group | | `clearValue` | `VoidFunction` | Clears the value of the rating group | | `hovering` | `boolean` | Whether the rating group is being hovered | | `value` | `number` | The current value of the rating group | | `hoveredValue` | `number` | The value of the currently hovered rating | | `count` | `number` | The total number of ratings | | `items` | `number[]` | The array of rating values. Returns an array of numbers from 1 to the max value. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a rating item | ## Accessibility ### Keyboard Support **`ArrowRight`** Description: Moves focus to the next star, increasing the rating value based on the `allowHalf` property. **`ArrowLeft`** Description: Moves focus to the previous star, decreasing the rating value based on the `allowHalf` property. **`Enter`** Description: Selects the focused star in the rating group. --- # Rating Group (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' export const Basic = () => ( Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) } ) ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const Basic = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ### Controlled When using the `RatingGroup` component, you can use the `value` and `onValueChange` props to control the state. **Example: controlled** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/rating-group.module.css' export const Controlled = () => { const [value, setValue] = useState(0) return ( setValue(details.value)}> Label {({ items }) => items.map((item) => ( {({ half, highlighted }) => ( )} )) } ) } ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/rating-group.module.css' export const Controlled = () => { const [value, setValue] = createSignal(0) return ( setValue(details.value)}> Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ### 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. **Example: root-provider** #### React ```tsx import { RatingGroup, useRatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' export const RootProvider = () => { const ratingGroup = useRatingGroup({ count: 5, defaultValue: 3 }) return (
                    value: {ratingGroup.value} Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) }
                    ) } ``` #### Solid ```tsx import { RatingGroup, useRatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const RootProvider = () => { const ratingGroup = useRatingGroup({ defaultValue: 3 }) return (
                    value: {ratingGroup().value} Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    value: {ratingGroup().value} Label {#snippet render(context)} {#each context().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet}
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/rating-group.module.css' export const WithField = () => ( Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) } Additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/rating-group.module.css' export const WithField = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} Additional Info Error Info ``` ### 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. **Example: half-star** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' export const HalfStar = () => ( Label {({ items }) => items.map((item) => ( {({ half, highlighted }) => ( )} )) } ) ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const HalfStar = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ### 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. **Example: form-usage** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' import button from 'styles/button.module.css' export const FormUsage = () => (
                    { e.preventDefault() const formData = new FormData(e.currentTarget) alert(`Rating value: ${formData.get('review')}`) }} > Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) }
                    ) ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const FormUsage = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ### Disabled To make the rating group disabled, set the `disabled` prop to `true`. **Example: disabled** #### React ```tsx import { RatingGroup } from '@ark-ui/react/rating-group' import { StarIcon } from 'lucide-react' import styles from 'styles/rating-group.module.css' export const Disabled = () => ( Label {({ items }) => items.map((item) => ( {({ highlighted }) => ( )} )) } ) ``` #### Solid ```tsx import { RatingGroup } from '@ark-ui/solid/rating-group' import { StarIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/rating-group.module.css' export const Disabled = () => ( Label {(context) => ( {(item) => ( {(itemContext) => ( )} )} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#snippet render(ratingGroup)} {#each ratingGroup().items as item} {#snippet render(itemState)} {/snippet} {/each} {/snippet} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowHalf` | `boolean` | No | Whether to allow half stars. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the rating. | | `count` | `number` | No | The total number of ratings. | | `defaultValue` | `number` | No | The initial value of the rating when rendered. Use when you don't need to control the value of the rating. | | `disabled` | `boolean` | No | Whether the rating is disabled. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string hiddenInput: string control: string item: (id: string) => string }>` | No | The ids of the elements in the rating. Useful for composition. | | `name` | `string` | No | The name attribute of the rating element (used in forms). | | `onHoverChange` | `(details: HoverChangeDetails) => void` | No | Function to be called when the rating value is hovered. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to be called when the rating value changes. | | `readOnly` | `boolean` | No | Whether the rating is readonly. | | `required` | `boolean` | No | Whether the rating is required. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `number` | No | The controlled value of the rating | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | control | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-checked]` | Present when checked | | `[data-highlighted]` | Present when highlighted | | `[data-half]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRatingGroupReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowHalf` | `boolean` | No | Whether to allow half stars. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the rating. | | `count` | `number` | No | The total number of ratings. | | `defaultValue` | `number` | No | The initial value of the rating when rendered. Use when you don't need to control the value of the rating. | | `disabled` | `boolean` | No | Whether the rating is disabled. | | `form` | `string` | No | The associate form of the underlying input element. | | `ids` | `Partial<{ root: string label: string hiddenInput: string control: string item: (id: string) => string }>` | No | The ids of the elements in the rating. Useful for composition. | | `name` | `string` | No | The name attribute of the rating element (used in forms). | | `onHoverChange` | `(details: HoverChangeDetails) => void` | No | Function to be called when the rating value is hovered. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to be called when the rating value changes. | | `readOnly` | `boolean` | No | Whether the rating is readonly. | | `required` | `boolean` | No | Whether the rating is required. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `number` | No | The controlled value of the rating | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | control | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-checked]` | Present when checked | | `[data-highlighted]` | Present when highlighted | | `[data-half]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRatingGroupReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowHalf` | `boolean` | No | Whether to allow half stars. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the rating. | | `count` | `number` | No | The total number of ratings. | | `defaultValue` | `number` | No | The initial value of the rating when rendered. Use when you don't need to control the value of the rating. | | `disabled` | `boolean` | No | Whether the rating is disabled. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string hiddenInput: string control: string item(id: string): string }>` | No | The ids of the elements in the rating. Useful for composition. | | `modelValue` | `number` | No | The v-model value of the rating group | | `name` | `string` | No | The name attribute of the rating element (used in forms). | | `readOnly` | `boolean` | No | Whether the rating is readonly. | | `required` | `boolean` | No | Whether the rating is required. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | control | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-checked]` | Present when checked | | `[data-highlighted]` | Present when highlighted | | `[data-half]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RatingGroupApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `allowHalf` | `boolean` | No | Whether to allow half stars. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether to autofocus the rating. | | `count` | `number` | No | The total number of ratings. | | `defaultValue` | `number` | No | The initial value of the rating when rendered. Use when you don't need to control the value of the rating. | | `disabled` | `boolean` | No | Whether the rating is disabled. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string label: string hiddenInput: string control: string item: (id: string) => string }>` | No | The ids of the elements in the rating. Useful for composition. | | `name` | `string` | No | The name attribute of the rating element (used in forms). | | `onHoverChange` | `(details: HoverChangeDetails) => void` | No | Function to be called when the rating value is hovered. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to be called when the rating value changes. | | `readOnly` | `boolean` | No | Whether the rating is readonly. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the rating is required. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `value` | `number` | No | The controlled value of the rating | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseRatingGroupContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | control | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseRatingGroupItemContext]>` | Yes | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | item | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-checked]` | Present when checked | | `[data-highlighted]` | Present when highlighted | | `[data-half]` | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | rating-group | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseRatingGroupReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `setValue` | `(value: number) => void` | Sets the value of the rating group | | `clearValue` | `VoidFunction` | Clears the value of the rating group | | `hovering` | `boolean` | Whether the rating group is being hovered | | `value` | `number` | The current value of the rating group | | `hoveredValue` | `number` | The value of the currently hovered rating | | `count` | `number` | The total number of ratings | | `items` | `number[]` | The array of rating values. Returns an array of numbers from 1 to the max value. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a rating item | ## Accessibility ### Keyboard Support **`ArrowRight`** Description: Moves focus to the next star, increasing the rating value based on the `allowHalf` property. **`ArrowLeft`** Description: Moves focus to the previous star, decreasing the rating value based on the `allowHalf` property. **`Enter`** Description: Selects the focused star in the rating group. --- # Scroll Area (REACT) ## Anatomy ```tsx ``` ## Required style It's important to note that the scroll area requires the following styles on the `ScrollArea.Viewport` element to hide the native scrollbar: ```css [data-scope='scroll-area'][data-part='viewport'] { scrollbar-width: none; &::-webkit-scrollbar { display: none; } } ``` ## Examples ### Basic Create a basic scrollable area with custom scrollbar. **Example: basic** #### React ```tsx import { ScrollArea } from '@ark-ui/react/scroll-area' import styles from 'styles/scroll-area.module.css' export const Basic = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

                    ) ``` #### Solid ```tsx import { ScrollArea } from '@ark-ui/solid/scroll-area' import styles from 'styles/scroll-area.module.css' export const Basic = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

                    ``` ### Horizontal Configure the scroll area for horizontal scrolling only. **Example: horizontal** #### React ```tsx import { ScrollArea } from '@ark-ui/react/scroll-area' import styles from 'styles/scroll-area.module.css' export const Horizontal = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    ) ``` #### Solid ```tsx import { ScrollArea } from '@ark-ui/solid/scroll-area' import styles from 'styles/scroll-area.module.css' export const Horizontal = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    ``` ### Both Directions Enable scrolling in both horizontal and vertical directions. **Example: both-directions** #### React ```tsx import { ScrollArea } from '@ark-ui/react/scroll-area' import styles from 'styles/scroll-area.module.css' export const BothDirections = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.

                    At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga.

                    ) ``` #### Solid ```tsx import { ScrollArea } from '@ark-ui/solid/scroll-area' import styles from 'styles/scroll-area.module.css' export const BothDirections = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.

                    At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.

                    At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga.

                    ``` ### Nested Scroll areas can be nested within each other for complex layouts. **Example: nested** #### React ```tsx import { ScrollArea } from '@ark-ui/react/scroll-area' import styles from 'styles/scroll-area.module.css' export const Nested = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

                    This is a nested scroll area. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.

                    ) ``` #### Solid ```tsx import { ScrollArea } from '@ark-ui/solid/scroll-area' import styles from 'styles/scroll-area.module.css' export const Nested = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

                    This is a nested scroll area. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

                    This is a nested scroll area. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.

                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ids` | `Partial<{ root: string; viewport: string; content: string; scrollbar: string; thumb: string }>` | No | The ids of the scroll area elements | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | root | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--corner-width` | The width of the Root | | `--corner-height` | The height of the Root | | `--thumb-width` | The width of the slider thumb | | `--thumb-height` | The height of the slider thumb | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | content | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Corner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Corner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | corner | | `[data-hover]` | Present when hovered | | `[data-state]` | "hidden" | "visible" | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseScrollAreaReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrollbar Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **Scrollbar Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | scrollbar | | `[data-orientation]` | The orientation of the scrollbar | | `[data-scrolling]` | Present when scrolling | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | thumb | | `[data-orientation]` | The orientation of the thumb | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | viewport | | `[data-at-top]` | Present when scrolled to the top edge | | `[data-at-bottom]` | Present when scrolled to the bottom edge | | `[data-at-left]` | Present when scrolled to the left edge | | `[data-at-right]` | Present when scrolled to the right edge | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: string; scrollbar: string; thumb: string }>` | No | The ids of the scroll area elements | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | root | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--corner-width` | The width of the Root | | `--corner-height` | The height of the Root | | `--thumb-width` | The width of the slider thumb | | `--thumb-height` | The height of the slider thumb | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | content | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Corner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Corner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | corner | | `[data-hover]` | Present when hovered | | `[data-state]` | "hidden" | "visible" | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseScrollAreaContext` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrollbar Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **Scrollbar Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | scrollbar | | `[data-orientation]` | The orientation of the scrollbar | | `[data-scrolling]` | Present when scrolling | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | thumb | | `[data-orientation]` | The orientation of the thumb | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | viewport | | `[data-at-top]` | Present when scrolled to the top edge | | `[data-at-bottom]` | Present when scrolled to the bottom edge | | `[data-at-left]` | Present when scrolled to the left edge | | `[data-at-right]` | Present when scrolled to the right edge | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: string; scrollbar: string; thumb: string }>` | No | The ids of the scroll area elements | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | root | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--corner-width` | The width of the Root | | `--corner-height` | The height of the Root | | `--thumb-width` | The width of the slider thumb | | `--thumb-height` | The height of the slider thumb | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | content | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Corner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Corner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | corner | | `[data-hover]` | Present when hovered | | `[data-state]` | "hidden" | "visible" | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ScrollAreaApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrollbar Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **Scrollbar Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | scrollbar | | `[data-orientation]` | The orientation of the scrollbar | | `[data-scrolling]` | Present when scrolling | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | thumb | | `[data-orientation]` | The orientation of the thumb | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | viewport | | `[data-at-top]` | Present when scrolled to the top edge | | `[data-at-bottom]` | Present when scrolled to the bottom edge | | `[data-at-left]` | Present when scrolled to the left edge | | `[data-at-right]` | Present when scrolled to the right edge | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: string; scrollbar: string; thumb: string }>` | No | The ids of the scroll area elements | | `ref` | `Element` | No | | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | root | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--corner-width` | The width of the Root | | `--corner-height` | The height of the Root | | `--thumb-width` | The width of the slider thumb | | `--thumb-height` | The height of the slider thumb | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | content | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseScrollAreaContext]>` | Yes | | **Corner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Corner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | corner | | `[data-hover]` | Present when hovered | | `[data-state]` | "hidden" | "visible" | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseScrollAreaContext` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Scrollbar Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | | `ref` | `Element` | No | | **Scrollbar Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | scrollbar | | `[data-orientation]` | The orientation of the scrollbar | | `[data-scrolling]` | Present when scrolling | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | thumb | | `[data-orientation]` | The orientation of the thumb | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | viewport | | `[data-at-top]` | Present when scrolled to the top edge | | `[data-at-bottom]` | Present when scrolled to the bottom edge | | `[data-at-left]` | Present when scrolled to the left edge | | `[data-at-right]` | Present when scrolled to the right edge | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `isAtTop` | `boolean` | Whether the scroll area is at the top | | `isAtBottom` | `boolean` | Whether the scroll area is at the bottom | | `isAtLeft` | `boolean` | Whether the scroll area is at the left | | `isAtRight` | `boolean` | Whether the scroll area is at the right | | `hasOverflowX` | `boolean` | Whether the scroll area has horizontal overflow | | `hasOverflowY` | `boolean` | Whether the scroll area has vertical overflow | | `getScrollProgress` | `() => Point` | Get the scroll progress as values between 0 and 1 | | `scrollToEdge` | `(details: ScrollToEdgeDetails) => void` | Scroll to the edge of the scroll area | | `scrollTo` | `(details: ScrollToDetails) => void` | Scroll to specific coordinates | | `getScrollbarState` | `(props: ScrollbarProps) => ScrollbarState` | Returns the state of the scrollbar | --- # Scroll Area (VUE) ## Anatomy ```tsx ``` ## Required style It's important to note that the scroll area requires the following styles on the `ScrollArea.Viewport` element to hide the native scrollbar: ```css [data-scope='scroll-area'][data-part='viewport'] { scrollbar-width: none; &::-webkit-scrollbar { display: none; } } ``` ## Examples ### Basic Create a basic scrollable area with custom scrollbar. **Example: basic** #### React ```tsx import { ScrollArea } from '@ark-ui/react/scroll-area' import styles from 'styles/scroll-area.module.css' export const Basic = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

                    ) ``` #### Solid ```tsx import { ScrollArea } from '@ark-ui/solid/scroll-area' import styles from 'styles/scroll-area.module.css' export const Basic = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

                    ``` ### Horizontal Configure the scroll area for horizontal scrolling only. **Example: horizontal** #### React ```tsx import { ScrollArea } from '@ark-ui/react/scroll-area' import styles from 'styles/scroll-area.module.css' export const Horizontal = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    ) ``` #### Solid ```tsx import { ScrollArea } from '@ark-ui/solid/scroll-area' import styles from 'styles/scroll-area.module.css' export const Horizontal = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    ``` ### Both Directions Enable scrolling in both horizontal and vertical directions. **Example: both-directions** #### React ```tsx import { ScrollArea } from '@ark-ui/react/scroll-area' import styles from 'styles/scroll-area.module.css' export const BothDirections = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.

                    At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga.

                    ) ``` #### Solid ```tsx import { ScrollArea } from '@ark-ui/solid/scroll-area' import styles from 'styles/scroll-area.module.css' export const BothDirections = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.

                    At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.

                    At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga.

                    ``` ### Nested Scroll areas can be nested within each other for complex layouts. **Example: nested** #### React ```tsx import { ScrollArea } from '@ark-ui/react/scroll-area' import styles from 'styles/scroll-area.module.css' export const Nested = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

                    This is a nested scroll area. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.

                    ) ``` #### Solid ```tsx import { ScrollArea } from '@ark-ui/solid/scroll-area' import styles from 'styles/scroll-area.module.css' export const Nested = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

                    This is a nested scroll area. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

                    This is a nested scroll area. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.

                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ids` | `Partial<{ root: string; viewport: string; content: string; scrollbar: string; thumb: string }>` | No | The ids of the scroll area elements | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | root | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--corner-width` | The width of the Root | | `--corner-height` | The height of the Root | | `--thumb-width` | The width of the slider thumb | | `--thumb-height` | The height of the slider thumb | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | content | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Corner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Corner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | corner | | `[data-hover]` | Present when hovered | | `[data-state]` | "hidden" | "visible" | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseScrollAreaReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrollbar Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **Scrollbar Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | scrollbar | | `[data-orientation]` | The orientation of the scrollbar | | `[data-scrolling]` | Present when scrolling | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | thumb | | `[data-orientation]` | The orientation of the thumb | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | viewport | | `[data-at-top]` | Present when scrolled to the top edge | | `[data-at-bottom]` | Present when scrolled to the bottom edge | | `[data-at-left]` | Present when scrolled to the left edge | | `[data-at-right]` | Present when scrolled to the right edge | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: string; scrollbar: string; thumb: string }>` | No | The ids of the scroll area elements | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | root | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--corner-width` | The width of the Root | | `--corner-height` | The height of the Root | | `--thumb-width` | The width of the slider thumb | | `--thumb-height` | The height of the slider thumb | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | content | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Corner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Corner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | corner | | `[data-hover]` | Present when hovered | | `[data-state]` | "hidden" | "visible" | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseScrollAreaContext` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrollbar Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **Scrollbar Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | scrollbar | | `[data-orientation]` | The orientation of the scrollbar | | `[data-scrolling]` | Present when scrolling | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | thumb | | `[data-orientation]` | The orientation of the thumb | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | viewport | | `[data-at-top]` | Present when scrolled to the top edge | | `[data-at-bottom]` | Present when scrolled to the bottom edge | | `[data-at-left]` | Present when scrolled to the left edge | | `[data-at-right]` | Present when scrolled to the right edge | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: string; scrollbar: string; thumb: string }>` | No | The ids of the scroll area elements | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | root | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--corner-width` | The width of the Root | | `--corner-height` | The height of the Root | | `--thumb-width` | The width of the slider thumb | | `--thumb-height` | The height of the slider thumb | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | content | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Corner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Corner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | corner | | `[data-hover]` | Present when hovered | | `[data-state]` | "hidden" | "visible" | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ScrollAreaApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrollbar Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **Scrollbar Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | scrollbar | | `[data-orientation]` | The orientation of the scrollbar | | `[data-scrolling]` | Present when scrolling | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | thumb | | `[data-orientation]` | The orientation of the thumb | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | viewport | | `[data-at-top]` | Present when scrolled to the top edge | | `[data-at-bottom]` | Present when scrolled to the bottom edge | | `[data-at-left]` | Present when scrolled to the left edge | | `[data-at-right]` | Present when scrolled to the right edge | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: string; scrollbar: string; thumb: string }>` | No | The ids of the scroll area elements | | `ref` | `Element` | No | | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | root | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--corner-width` | The width of the Root | | `--corner-height` | The height of the Root | | `--thumb-width` | The width of the slider thumb | | `--thumb-height` | The height of the slider thumb | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | content | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseScrollAreaContext]>` | Yes | | **Corner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Corner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | corner | | `[data-hover]` | Present when hovered | | `[data-state]` | "hidden" | "visible" | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseScrollAreaContext` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Scrollbar Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | | `ref` | `Element` | No | | **Scrollbar Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | scrollbar | | `[data-orientation]` | The orientation of the scrollbar | | `[data-scrolling]` | Present when scrolling | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | thumb | | `[data-orientation]` | The orientation of the thumb | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | viewport | | `[data-at-top]` | Present when scrolled to the top edge | | `[data-at-bottom]` | Present when scrolled to the bottom edge | | `[data-at-left]` | Present when scrolled to the left edge | | `[data-at-right]` | Present when scrolled to the right edge | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `isAtTop` | `boolean` | Whether the scroll area is at the top | | `isAtBottom` | `boolean` | Whether the scroll area is at the bottom | | `isAtLeft` | `boolean` | Whether the scroll area is at the left | | `isAtRight` | `boolean` | Whether the scroll area is at the right | | `hasOverflowX` | `boolean` | Whether the scroll area has horizontal overflow | | `hasOverflowY` | `boolean` | Whether the scroll area has vertical overflow | | `getScrollProgress` | `() => Point` | Get the scroll progress as values between 0 and 1 | | `scrollToEdge` | `(details: ScrollToEdgeDetails) => void` | Scroll to the edge of the scroll area | | `scrollTo` | `(details: ScrollToDetails) => void` | Scroll to specific coordinates | | `getScrollbarState` | `(props: ScrollbarProps) => ScrollbarState` | Returns the state of the scrollbar | --- # Scroll Area (SVELTE) ## Anatomy ```tsx ``` ## Required style It's important to note that the scroll area requires the following styles on the `ScrollArea.Viewport` element to hide the native scrollbar: ```css [data-scope='scroll-area'][data-part='viewport'] { scrollbar-width: none; &::-webkit-scrollbar { display: none; } } ``` ## Examples ### Basic Create a basic scrollable area with custom scrollbar. **Example: basic** #### React ```tsx import { ScrollArea } from '@ark-ui/react/scroll-area' import styles from 'styles/scroll-area.module.css' export const Basic = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

                    ) ``` #### Solid ```tsx import { ScrollArea } from '@ark-ui/solid/scroll-area' import styles from 'styles/scroll-area.module.css' export const Basic = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

                    ``` ### Horizontal Configure the scroll area for horizontal scrolling only. **Example: horizontal** #### React ```tsx import { ScrollArea } from '@ark-ui/react/scroll-area' import styles from 'styles/scroll-area.module.css' export const Horizontal = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    ) ``` #### Solid ```tsx import { ScrollArea } from '@ark-ui/solid/scroll-area' import styles from 'styles/scroll-area.module.css' export const Horizontal = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    ``` ### Both Directions Enable scrolling in both horizontal and vertical directions. **Example: both-directions** #### React ```tsx import { ScrollArea } from '@ark-ui/react/scroll-area' import styles from 'styles/scroll-area.module.css' export const BothDirections = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.

                    At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga.

                    ) ``` #### Solid ```tsx import { ScrollArea } from '@ark-ui/solid/scroll-area' import styles from 'styles/scroll-area.module.css' export const BothDirections = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.

                    At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.

                    At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga.

                    ``` ### Nested Scroll areas can be nested within each other for complex layouts. **Example: nested** #### React ```tsx import { ScrollArea } from '@ark-ui/react/scroll-area' import styles from 'styles/scroll-area.module.css' export const Nested = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

                    This is a nested scroll area. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.

                    ) ``` #### Solid ```tsx import { ScrollArea } from '@ark-ui/solid/scroll-area' import styles from 'styles/scroll-area.module.css' export const Nested = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

                    This is a nested scroll area. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

                    This is a nested scroll area. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.

                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ids` | `Partial<{ root: string; viewport: string; content: string; scrollbar: string; thumb: string }>` | No | The ids of the scroll area elements | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | root | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--corner-width` | The width of the Root | | `--corner-height` | The height of the Root | | `--thumb-width` | The width of the slider thumb | | `--thumb-height` | The height of the slider thumb | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | content | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Corner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Corner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | corner | | `[data-hover]` | Present when hovered | | `[data-state]` | "hidden" | "visible" | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseScrollAreaReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrollbar Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **Scrollbar Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | scrollbar | | `[data-orientation]` | The orientation of the scrollbar | | `[data-scrolling]` | Present when scrolling | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | thumb | | `[data-orientation]` | The orientation of the thumb | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | viewport | | `[data-at-top]` | Present when scrolled to the top edge | | `[data-at-bottom]` | Present when scrolled to the bottom edge | | `[data-at-left]` | Present when scrolled to the left edge | | `[data-at-right]` | Present when scrolled to the right edge | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: string; scrollbar: string; thumb: string }>` | No | The ids of the scroll area elements | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | root | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--corner-width` | The width of the Root | | `--corner-height` | The height of the Root | | `--thumb-width` | The width of the slider thumb | | `--thumb-height` | The height of the slider thumb | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | content | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Corner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Corner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | corner | | `[data-hover]` | Present when hovered | | `[data-state]` | "hidden" | "visible" | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseScrollAreaContext` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrollbar Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **Scrollbar Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | scrollbar | | `[data-orientation]` | The orientation of the scrollbar | | `[data-scrolling]` | Present when scrolling | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | thumb | | `[data-orientation]` | The orientation of the thumb | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | viewport | | `[data-at-top]` | Present when scrolled to the top edge | | `[data-at-bottom]` | Present when scrolled to the bottom edge | | `[data-at-left]` | Present when scrolled to the left edge | | `[data-at-right]` | Present when scrolled to the right edge | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: string; scrollbar: string; thumb: string }>` | No | The ids of the scroll area elements | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | root | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--corner-width` | The width of the Root | | `--corner-height` | The height of the Root | | `--thumb-width` | The width of the slider thumb | | `--thumb-height` | The height of the slider thumb | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | content | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Corner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Corner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | corner | | `[data-hover]` | Present when hovered | | `[data-state]` | "hidden" | "visible" | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ScrollAreaApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrollbar Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **Scrollbar Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | scrollbar | | `[data-orientation]` | The orientation of the scrollbar | | `[data-scrolling]` | Present when scrolling | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | thumb | | `[data-orientation]` | The orientation of the thumb | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | viewport | | `[data-at-top]` | Present when scrolled to the top edge | | `[data-at-bottom]` | Present when scrolled to the bottom edge | | `[data-at-left]` | Present when scrolled to the left edge | | `[data-at-right]` | Present when scrolled to the right edge | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: string; scrollbar: string; thumb: string }>` | No | The ids of the scroll area elements | | `ref` | `Element` | No | | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | root | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--corner-width` | The width of the Root | | `--corner-height` | The height of the Root | | `--thumb-width` | The width of the slider thumb | | `--thumb-height` | The height of the slider thumb | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | content | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseScrollAreaContext]>` | Yes | | **Corner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Corner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | corner | | `[data-hover]` | Present when hovered | | `[data-state]` | "hidden" | "visible" | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseScrollAreaContext` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Scrollbar Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | | `ref` | `Element` | No | | **Scrollbar Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | scrollbar | | `[data-orientation]` | The orientation of the scrollbar | | `[data-scrolling]` | Present when scrolling | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | thumb | | `[data-orientation]` | The orientation of the thumb | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | viewport | | `[data-at-top]` | Present when scrolled to the top edge | | `[data-at-bottom]` | Present when scrolled to the bottom edge | | `[data-at-left]` | Present when scrolled to the left edge | | `[data-at-right]` | Present when scrolled to the right edge | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `isAtTop` | `boolean` | Whether the scroll area is at the top | | `isAtBottom` | `boolean` | Whether the scroll area is at the bottom | | `isAtLeft` | `boolean` | Whether the scroll area is at the left | | `isAtRight` | `boolean` | Whether the scroll area is at the right | | `hasOverflowX` | `boolean` | Whether the scroll area has horizontal overflow | | `hasOverflowY` | `boolean` | Whether the scroll area has vertical overflow | | `getScrollProgress` | `() => Point` | Get the scroll progress as values between 0 and 1 | | `scrollToEdge` | `(details: ScrollToEdgeDetails) => void` | Scroll to the edge of the scroll area | | `scrollTo` | `(details: ScrollToDetails) => void` | Scroll to specific coordinates | | `getScrollbarState` | `(props: ScrollbarProps) => ScrollbarState` | Returns the state of the scrollbar | --- # Scroll Area (SOLID) ## Anatomy ```tsx ``` ## Required style It's important to note that the scroll area requires the following styles on the `ScrollArea.Viewport` element to hide the native scrollbar: ```css [data-scope='scroll-area'][data-part='viewport'] { scrollbar-width: none; &::-webkit-scrollbar { display: none; } } ``` ## Examples ### Basic Create a basic scrollable area with custom scrollbar. **Example: basic** #### React ```tsx import { ScrollArea } from '@ark-ui/react/scroll-area' import styles from 'styles/scroll-area.module.css' export const Basic = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

                    ) ``` #### Solid ```tsx import { ScrollArea } from '@ark-ui/solid/scroll-area' import styles from 'styles/scroll-area.module.css' export const Basic = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

                    ``` ### Horizontal Configure the scroll area for horizontal scrolling only. **Example: horizontal** #### React ```tsx import { ScrollArea } from '@ark-ui/react/scroll-area' import styles from 'styles/scroll-area.module.css' export const Horizontal = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    ) ``` #### Solid ```tsx import { ScrollArea } from '@ark-ui/solid/scroll-area' import styles from 'styles/scroll-area.module.css' export const Horizontal = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    ``` ### Both Directions Enable scrolling in both horizontal and vertical directions. **Example: both-directions** #### React ```tsx import { ScrollArea } from '@ark-ui/react/scroll-area' import styles from 'styles/scroll-area.module.css' export const BothDirections = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.

                    At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga.

                    ) ``` #### Solid ```tsx import { ScrollArea } from '@ark-ui/solid/scroll-area' import styles from 'styles/scroll-area.module.css' export const BothDirections = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.

                    At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

                    Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.

                    At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga.

                    ``` ### Nested Scroll areas can be nested within each other for complex layouts. **Example: nested** #### React ```tsx import { ScrollArea } from '@ark-ui/react/scroll-area' import styles from 'styles/scroll-area.module.css' export const Nested = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

                    This is a nested scroll area. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.

                    ) ``` #### Solid ```tsx import { ScrollArea } from '@ark-ui/solid/scroll-area' import styles from 'styles/scroll-area.module.css' export const Nested = () => (

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

                    This is a nested scroll area. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

                    This is a nested scroll area. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.

                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ids` | `Partial<{ root: string; viewport: string; content: string; scrollbar: string; thumb: string }>` | No | The ids of the scroll area elements | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | root | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--corner-width` | The width of the Root | | `--corner-height` | The height of the Root | | `--thumb-width` | The width of the slider thumb | | `--thumb-height` | The height of the slider thumb | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | content | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Corner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Corner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | corner | | `[data-hover]` | Present when hovered | | `[data-state]` | "hidden" | "visible" | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseScrollAreaReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrollbar Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **Scrollbar Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | scrollbar | | `[data-orientation]` | The orientation of the scrollbar | | `[data-scrolling]` | Present when scrolling | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | thumb | | `[data-orientation]` | The orientation of the thumb | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | viewport | | `[data-at-top]` | Present when scrolled to the top edge | | `[data-at-bottom]` | Present when scrolled to the bottom edge | | `[data-at-left]` | Present when scrolled to the left edge | | `[data-at-right]` | Present when scrolled to the right edge | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: string; scrollbar: string; thumb: string }>` | No | The ids of the scroll area elements | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | root | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--corner-width` | The width of the Root | | `--corner-height` | The height of the Root | | `--thumb-width` | The width of the slider thumb | | `--thumb-height` | The height of the slider thumb | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | content | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Corner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Corner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | corner | | `[data-hover]` | Present when hovered | | `[data-state]` | "hidden" | "visible" | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseScrollAreaContext` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrollbar Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **Scrollbar Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | scrollbar | | `[data-orientation]` | The orientation of the scrollbar | | `[data-scrolling]` | Present when scrolling | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | thumb | | `[data-orientation]` | The orientation of the thumb | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | viewport | | `[data-at-top]` | Present when scrolled to the top edge | | `[data-at-bottom]` | Present when scrolled to the bottom edge | | `[data-at-left]` | Present when scrolled to the left edge | | `[data-at-right]` | Present when scrolled to the right edge | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: string; scrollbar: string; thumb: string }>` | No | The ids of the scroll area elements | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | root | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--corner-width` | The width of the Root | | `--corner-height` | The height of the Root | | `--thumb-width` | The width of the slider thumb | | `--thumb-height` | The height of the slider thumb | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | content | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Corner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Corner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | corner | | `[data-hover]` | Present when hovered | | `[data-state]` | "hidden" | "visible" | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ScrollAreaApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Scrollbar Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | **Scrollbar Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | scrollbar | | `[data-orientation]` | The orientation of the scrollbar | | `[data-scrolling]` | Present when scrolling | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | thumb | | `[data-orientation]` | The orientation of the thumb | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | viewport | | `[data-at-top]` | Present when scrolled to the top edge | | `[data-at-bottom]` | Present when scrolled to the bottom edge | | `[data-at-left]` | Present when scrolled to the left edge | | `[data-at-right]` | Present when scrolled to the right edge | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; viewport: string; content: string; scrollbar: string; thumb: string }>` | No | The ids of the scroll area elements | | `ref` | `Element` | No | | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | root | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--corner-width` | The width of the Root | | `--corner-height` | The height of the Root | | `--thumb-width` | The width of the slider thumb | | `--thumb-height` | The height of the slider thumb | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | content | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseScrollAreaContext]>` | Yes | | **Corner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Corner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | corner | | `[data-hover]` | Present when hovered | | `[data-state]` | "hidden" | "visible" | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseScrollAreaContext` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Scrollbar Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `orientation` | `Orientation` | No | | | `ref` | `Element` | No | | **Scrollbar Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | scrollbar | | `[data-orientation]` | The orientation of the scrollbar | | `[data-scrolling]` | Present when scrolling | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | thumb | | `[data-orientation]` | The orientation of the thumb | | `[data-hover]` | Present when hovered | | `[data-dragging]` | Present when in the dragging state | **Viewport Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | scroll-area | | `[data-part]` | viewport | | `[data-at-top]` | Present when scrolled to the top edge | | `[data-at-bottom]` | Present when scrolled to the bottom edge | | `[data-at-left]` | Present when scrolled to the left edge | | `[data-at-right]` | Present when scrolled to the right edge | | `[data-overflow-x]` | Present when the content overflows the x-axis | | `[data-overflow-y]` | Present when the content overflows the y-axis | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `isAtTop` | `boolean` | Whether the scroll area is at the top | | `isAtBottom` | `boolean` | Whether the scroll area is at the bottom | | `isAtLeft` | `boolean` | Whether the scroll area is at the left | | `isAtRight` | `boolean` | Whether the scroll area is at the right | | `hasOverflowX` | `boolean` | Whether the scroll area has horizontal overflow | | `hasOverflowY` | `boolean` | Whether the scroll area has vertical overflow | | `getScrollProgress` | `() => Point` | Get the scroll progress as values between 0 and 1 | | `scrollToEdge` | `(details: ScrollToEdgeDetails) => void` | Scroll to the edge of the scroll area | | `scrollTo` | `(details: ScrollToDetails) => void` | Scroll to specific coordinates | | `getScrollbarState` | `(props: ScrollbarProps) => ScrollbarState` | Returns the state of the scrollbar | --- # Segment Group (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { SegmentGroup } from '@ark-ui/react/segment-group' import styles from 'styles/segment-group.module.css' export const Basic = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] return ( {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { SegmentGroup } from '@ark-ui/solid/segment-group' import { Index } from 'solid-js' import styles from 'styles/segment-group.module.css' export const Basic = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] return ( {(framework) => ( {framework()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each frameworks as framework} {framework} {/each} ``` ### 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: **Example: controlled** #### React ```tsx import { SegmentGroup } from '@ark-ui/react/segment-group' import { useState } from 'react' import styles from 'styles/segment-group.module.css' export const Controlled = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] const [value, setValue] = useState(null) return ( setValue(e.value)}> {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { SegmentGroup } from '@ark-ui/solid/segment-group' import { Index, createSignal } from 'solid-js' import styles from 'styles/segment-group.module.css' export const Controlled = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] const [value, setValue] = createSignal(null) return ( setValue(e.value)}> {(framework) => ( {framework()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each frameworks as framework} {framework} {/each} ``` ### 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. **Example: root-provider** #### React ```tsx import { SegmentGroup, useSegmentGroup } from '@ark-ui/react/segment-group' import styles from 'styles/segment-group.module.css' export const RootProvider = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] const segmentGroup = useSegmentGroup({ defaultValue: 'React' }) return (
                    {frameworks.map((framework) => ( {framework} ))} selected: {segmentGroup.value}
                    ) } ``` #### Solid ```tsx import { SegmentGroup, useSegmentGroup } from '@ark-ui/solid/segment-group' import { Index } from 'solid-js' import styles from 'styles/segment-group.module.css' export const RootProvider = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] const segmentGroup = useSegmentGroup({ defaultValue: 'React' }) return (
                    selected: {segmentGroup().value} {(framework) => ( {framework()} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    selected: {segmentGroup().value} {#each frameworks as framework} {framework} {/each}
                    ``` ### Disabled To disable a segment, simply pass the `disabled` prop to the `SegmentGroup.Item` component: **Example: disabled** #### React ```tsx import { SegmentGroup } from '@ark-ui/react/segment-group' import styles from 'styles/segment-group.module.css' export const Disabled = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] return ( {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { SegmentGroup } from '@ark-ui/solid/segment-group' import { Index } from 'solid-js' import styles from 'styles/segment-group.module.css' export const Disabled = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] return ( {(framework) => ( {framework()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each frameworks as framework} {framework} {/each} ``` ## API Reference ## Accessibility Complies with the [Radio WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/radio/). ### Keyboard Support **`Tab`** Description: Moves focus to either the checked radio item or the first radio item in the group. **`Space`** Description: When focus is on an unchecked radio item, checks it. **`ArrowDown`** Description: Moves focus and checks the next radio item in the group. **`ArrowRight`** Description: Moves focus and checks the next radio item in the group. **`ArrowUp`** Description: Moves focus to the previous radio item in the group. **`ArrowLeft`** Description: Moves focus to the previous radio item in the group. --- # Segment Group (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { SegmentGroup } from '@ark-ui/react/segment-group' import styles from 'styles/segment-group.module.css' export const Basic = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] return ( {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { SegmentGroup } from '@ark-ui/solid/segment-group' import { Index } from 'solid-js' import styles from 'styles/segment-group.module.css' export const Basic = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] return ( {(framework) => ( {framework()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each frameworks as framework} {framework} {/each} ``` ### 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: **Example: controlled** #### React ```tsx import { SegmentGroup } from '@ark-ui/react/segment-group' import { useState } from 'react' import styles from 'styles/segment-group.module.css' export const Controlled = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] const [value, setValue] = useState(null) return ( setValue(e.value)}> {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { SegmentGroup } from '@ark-ui/solid/segment-group' import { Index, createSignal } from 'solid-js' import styles from 'styles/segment-group.module.css' export const Controlled = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] const [value, setValue] = createSignal(null) return ( setValue(e.value)}> {(framework) => ( {framework()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each frameworks as framework} {framework} {/each} ``` ### 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. **Example: root-provider** #### React ```tsx import { SegmentGroup, useSegmentGroup } from '@ark-ui/react/segment-group' import styles from 'styles/segment-group.module.css' export const RootProvider = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] const segmentGroup = useSegmentGroup({ defaultValue: 'React' }) return (
                    {frameworks.map((framework) => ( {framework} ))} selected: {segmentGroup.value}
                    ) } ``` #### Solid ```tsx import { SegmentGroup, useSegmentGroup } from '@ark-ui/solid/segment-group' import { Index } from 'solid-js' import styles from 'styles/segment-group.module.css' export const RootProvider = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] const segmentGroup = useSegmentGroup({ defaultValue: 'React' }) return (
                    selected: {segmentGroup().value} {(framework) => ( {framework()} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    selected: {segmentGroup().value} {#each frameworks as framework} {framework} {/each}
                    ``` ### Disabled To disable a segment, simply pass the `disabled` prop to the `SegmentGroup.Item` component: **Example: disabled** #### React ```tsx import { SegmentGroup } from '@ark-ui/react/segment-group' import styles from 'styles/segment-group.module.css' export const Disabled = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] return ( {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { SegmentGroup } from '@ark-ui/solid/segment-group' import { Index } from 'solid-js' import styles from 'styles/segment-group.module.css' export const Disabled = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] return ( {(framework) => ( {framework()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each frameworks as framework} {framework} {/each} ``` ## API Reference ## Accessibility Complies with the [Radio WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/radio/). ### Keyboard Support **`Tab`** Description: Moves focus to either the checked radio item or the first radio item in the group. **`Space`** Description: When focus is on an unchecked radio item, checks it. **`ArrowDown`** Description: Moves focus and checks the next radio item in the group. **`ArrowRight`** Description: Moves focus and checks the next radio item in the group. **`ArrowUp`** Description: Moves focus to the previous radio item in the group. **`ArrowLeft`** Description: Moves focus to the previous radio item in the group. --- # Segment Group (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { SegmentGroup } from '@ark-ui/react/segment-group' import styles from 'styles/segment-group.module.css' export const Basic = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] return ( {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { SegmentGroup } from '@ark-ui/solid/segment-group' import { Index } from 'solid-js' import styles from 'styles/segment-group.module.css' export const Basic = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] return ( {(framework) => ( {framework()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each frameworks as framework} {framework} {/each} ``` ### 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: **Example: controlled** #### React ```tsx import { SegmentGroup } from '@ark-ui/react/segment-group' import { useState } from 'react' import styles from 'styles/segment-group.module.css' export const Controlled = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] const [value, setValue] = useState(null) return ( setValue(e.value)}> {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { SegmentGroup } from '@ark-ui/solid/segment-group' import { Index, createSignal } from 'solid-js' import styles from 'styles/segment-group.module.css' export const Controlled = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] const [value, setValue] = createSignal(null) return ( setValue(e.value)}> {(framework) => ( {framework()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each frameworks as framework} {framework} {/each} ``` ### 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. **Example: root-provider** #### React ```tsx import { SegmentGroup, useSegmentGroup } from '@ark-ui/react/segment-group' import styles from 'styles/segment-group.module.css' export const RootProvider = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] const segmentGroup = useSegmentGroup({ defaultValue: 'React' }) return (
                    {frameworks.map((framework) => ( {framework} ))} selected: {segmentGroup.value}
                    ) } ``` #### Solid ```tsx import { SegmentGroup, useSegmentGroup } from '@ark-ui/solid/segment-group' import { Index } from 'solid-js' import styles from 'styles/segment-group.module.css' export const RootProvider = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] const segmentGroup = useSegmentGroup({ defaultValue: 'React' }) return (
                    selected: {segmentGroup().value} {(framework) => ( {framework()} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    selected: {segmentGroup().value} {#each frameworks as framework} {framework} {/each}
                    ``` ### Disabled To disable a segment, simply pass the `disabled` prop to the `SegmentGroup.Item` component: **Example: disabled** #### React ```tsx import { SegmentGroup } from '@ark-ui/react/segment-group' import styles from 'styles/segment-group.module.css' export const Disabled = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] return ( {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { SegmentGroup } from '@ark-ui/solid/segment-group' import { Index } from 'solid-js' import styles from 'styles/segment-group.module.css' export const Disabled = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] return ( {(framework) => ( {framework()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each frameworks as framework} {framework} {/each} ``` ## API Reference ## Accessibility Complies with the [Radio WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/radio/). ### Keyboard Support **`Tab`** Description: Moves focus to either the checked radio item or the first radio item in the group. **`Space`** Description: When focus is on an unchecked radio item, checks it. **`ArrowDown`** Description: Moves focus and checks the next radio item in the group. **`ArrowRight`** Description: Moves focus and checks the next radio item in the group. **`ArrowUp`** Description: Moves focus to the previous radio item in the group. **`ArrowLeft`** Description: Moves focus to the previous radio item in the group. --- # Segment Group (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { SegmentGroup } from '@ark-ui/react/segment-group' import styles from 'styles/segment-group.module.css' export const Basic = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] return ( {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { SegmentGroup } from '@ark-ui/solid/segment-group' import { Index } from 'solid-js' import styles from 'styles/segment-group.module.css' export const Basic = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] return ( {(framework) => ( {framework()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each frameworks as framework} {framework} {/each} ``` ### 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: **Example: controlled** #### React ```tsx import { SegmentGroup } from '@ark-ui/react/segment-group' import { useState } from 'react' import styles from 'styles/segment-group.module.css' export const Controlled = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] const [value, setValue] = useState(null) return ( setValue(e.value)}> {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { SegmentGroup } from '@ark-ui/solid/segment-group' import { Index, createSignal } from 'solid-js' import styles from 'styles/segment-group.module.css' export const Controlled = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] const [value, setValue] = createSignal(null) return ( setValue(e.value)}> {(framework) => ( {framework()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each frameworks as framework} {framework} {/each} ``` ### 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. **Example: root-provider** #### React ```tsx import { SegmentGroup, useSegmentGroup } from '@ark-ui/react/segment-group' import styles from 'styles/segment-group.module.css' export const RootProvider = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] const segmentGroup = useSegmentGroup({ defaultValue: 'React' }) return (
                    {frameworks.map((framework) => ( {framework} ))} selected: {segmentGroup.value}
                    ) } ``` #### Solid ```tsx import { SegmentGroup, useSegmentGroup } from '@ark-ui/solid/segment-group' import { Index } from 'solid-js' import styles from 'styles/segment-group.module.css' export const RootProvider = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] const segmentGroup = useSegmentGroup({ defaultValue: 'React' }) return (
                    selected: {segmentGroup().value} {(framework) => ( {framework()} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    selected: {segmentGroup().value} {#each frameworks as framework} {framework} {/each}
                    ``` ### Disabled To disable a segment, simply pass the `disabled` prop to the `SegmentGroup.Item` component: **Example: disabled** #### React ```tsx import { SegmentGroup } from '@ark-ui/react/segment-group' import styles from 'styles/segment-group.module.css' export const Disabled = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] return ( {frameworks.map((framework) => ( {framework} ))} ) } ``` #### Solid ```tsx import { SegmentGroup } from '@ark-ui/solid/segment-group' import { Index } from 'solid-js' import styles from 'styles/segment-group.module.css' export const Disabled = () => { const frameworks = ['React', 'Solid', 'Svelte', 'Vue'] return ( {(framework) => ( {framework()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each frameworks as framework} {framework} {/each} ``` ## API Reference ## Accessibility Complies with the [Radio WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/radio/). ### Keyboard Support **`Tab`** Description: Moves focus to either the checked radio item or the first radio item in the group. **`Space`** Description: When focus is on an unchecked radio item, checks it. **`ArrowDown`** Description: Moves focus and checks the next radio item in the group. **`ArrowRight`** Description: Moves focus and checks the next radio item in the group. **`ArrowUp`** Description: Moves focus to the previous radio item in the group. **`ArrowLeft`** Description: Moves focus to the previous radio item in the group. --- # Select (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ], }) export const Basic = () => { return ( Framework
                    Frameworks {frameworks.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ], }) export const Basic = () => { return ( Framework
                    Frameworks {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework
                    Frameworks {#each frameworks.items as item} {item.label} {/each}
                    ``` ### Controlled Use the `value` and `onValueChange` props to control the selected items. **Example: controlled** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/select.module.css' interface Item { label: string value: string disabled?: boolean | undefined } export const Controlled = () => { const [value, setValue] = useState([]) const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte', disabled: true }, ], }) const handleValueChange = (details: Select.ValueChangeDetails) => { setValue(details.value) } return ( Framework
                    Frameworks {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' interface Item { label: string value: string disabled?: boolean } export const Controlled = () => { const [value, setValue] = createSignal([]) const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte', disabled: true }, ], }) const handleValueChange = (details: Select.ValueChangeDetails) => { setValue(details.value) } return ( Framework
                    Frameworks {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework
                    Frameworks {#each collection.items as item (item.value)} {item.label} {/each}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection, useSelect } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ], }) export const RootProvider = () => { const select = useSelect({ collection: frameworks }) return ( <> selected: {JSON.stringify(select.value)} Framework
                    Frameworks {frameworks.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection, useSelect } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ], }) export const RootProvider = () => { const select = useSelect({ collection: frameworks }) return ( <> selected: {JSON.stringify(select().value)} Framework
                    Frameworks {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Framework
                    Frameworks {#each frameworks.items as item} {item.label} {/each}
                    ``` ### Multiple To enable `multiple` item selection: **Example: multiple** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte', disabled: true }, ], }) export const Multiple = () => { return ( Framework
                    Frameworks {frameworks.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte', disabled: true }, ], }) export const Multiple = () => { return ( Framework
                    Frameworks {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework
                    Frameworks {#each frameworks.items as item (item.value)} {item.label} {/each}
                    ``` ### 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. **Example: grouping** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react', type: 'JS' }, { label: 'Solid', value: 'solid', type: 'JS' }, { label: 'Vue', value: 'vue', type: 'JS' }, { label: 'Panda', value: 'panda', type: 'CSS' }, { label: 'Tailwind', value: 'tailwind', type: 'CSS' }, ], groupBy: (item) => item.type, }) export const Grouping = () => { return ( Framework
                    {frameworks.group().map(([type, group]) => ( {type} {group.map((item) => ( {item.label} ))} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react', type: 'JS' }, { label: 'Solid', value: 'solid', type: 'JS' }, { label: 'Vue', value: 'vue', type: 'JS' }, { label: 'Panda', value: 'panda', type: 'CSS' }, { label: 'Tailwind', value: 'tailwind', type: 'CSS' }, ], groupBy: (item) => item.type, }) export const Grouping = () => { return ( Framework
                    {([type, group]) => ( {type} {(item) => ( {item.label} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework
                    {#each frameworks.group() as [type, group]} {type} {#each group as item (item.value)} {item.label} {/each} {/each}
                    ``` ### Field Use `Field` to manage form state, ARIA labels, helper text, and error text. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/select.module.css' export const WithField = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'] }) return ( Label {collection.items.map((item) => ( {item} ))} Additional Info Error Info ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index } from 'solid-js/web' import field from 'styles/field.module.css' import styles from 'styles/select.module.css' export const WithField = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'] }) return ( Label {(item) => ( {item()} )} Additional Info Error Info ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each collection.items as item} {item} {/each} Additional Info Error Info ``` ### Form Usage Here's an example of integrating the `Select` component with a form library. **Example: form-library** #### React ```tsx import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import { Controller, type SubmitHandler, useForm } from 'react-hook-form' import button from 'styles/button.module.css' import styles from 'styles/select.module.css' interface Inputs { framework: string } export const FormLibrary = () => { const { control, handleSubmit } = useForm({ defaultValues: { framework: 'React' }, }) const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) const onSubmit: SubmitHandler = (data) => { window.alert(JSON.stringify(data)) } return (
                    ( field.onChange(e.value[0])} name={field.name} onInteractOutside={() => field.onBlur()} > Framework
                    Frameworks {collection.items.map((item) => ( {item} ))}
                    )} /> ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { createForm, getValue, setValue } from '@modular-forms/solid' import { createMemo } from 'solid-js' import { Index, Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ], }) export const FormLibrary = () => { const [formStore, { Form, Field }] = createForm({ initialValues: { value: 'solid' }, }) const value = createMemo(() => getValue(formStore, 'value')) return ( <>
                    Value is {value()}
                    { window.alert(JSON.stringify(data)) }} > {(field, props) => ( setValue(formStore, field.name, e.value[0])} > Framework
                    Frameworks {(item) => ( {item().label} )}
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Value is {formData.framework}
                    { e.preventDefault() form.handleSubmit() }} > {#snippet children(field)} {@const state = field.state} 0} name={field.name} onValueChange={(details) => { field.handleChange(details.value[0]) }} > Framework
                    Frameworks {#each frameworks.items as item} {item.label} {/each}
                    {/snippet}
                    ``` ### Async Loading Here's an example of how to load the items asynchronously when the select is opened. **Example: async** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/select.module.css' function loadData() { return new Promise((resolve) => { setTimeout(() => resolve(['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Ember']), 500) }) } export const Async = () => { const [items, setItems] = useState(null) const [loading, setLoading] = useState(false) const [error, setError] = useState(null) const collection = createListCollection({ items: items || [], }) const handleOpenChange = (details: Select.OpenChangeDetails) => { if (details.open && items == null) { setLoading(true) setError(null) loadData() .then((data) => setItems(data)) .catch((err) => setError(err)) .finally(() => setLoading(false)) } } return ( Framework {loading ? (
                    Loading...
                    ) : error ? (
                    Error: {error.message}
                    ) : ( collection.items.map((item) => ( {item} )) )}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, Match, Switch, createMemo, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/select.module.css' function loadData() { return new Promise((resolve) => { setTimeout(() => resolve(['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Ember']), 500) }) } export const Async = () => { const [items, setItems] = createSignal(null) const [loading, setLoading] = createSignal(false) const [error, setError] = createSignal(null) const collection = createMemo(() => createListCollection({ items: items() || [], }), ) const handleOpenChange = (details: Select.OpenChangeDetails) => { if (details.open && items() === null) { setLoading(true) setError(null) loadData() .then((data) => setItems(data)) .catch((err) => setError(err)) .finally(() => setLoading(false)) } } return ( Framework
                    Loading...
                    Error: {error()?.message}
                    {(item) => ( {item()} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#if loading}
                    Loading...
                    {:else if error}
                    Error: {error.message}
                    {:else} {#each collection.items as item} {item} {/each} {/if}
                    ``` ### Lazy Mount Use `lazyMount` and `unmountOnExit` to control when content is mounted, improving performance. **Example: lazy-mount** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/select.module.css' export const LazyMount = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Alpine'], }) return ( Framework Clear Frameworks {collection.items.map((item) => ( {item} ))} ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' export const LazyMount = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Alpine'], }) return ( Framework Clear Frameworks {(item) => ( {item()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework Clear Frameworks {#each collection.items as item} {item} {/each} ``` ### Select on Highlight Here's an example of automatically selecting items when they are highlighted (hovered or navigated to with keyboard). **Example: select-on-highlight** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection, useSelect } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/select.module.css' export const SelectOnHighlight = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) const select = useSelect({ collection, onHighlightChange({ highlightedValue }) { if (highlightedValue) { select.selectValue(highlightedValue) } }, }) return ( Framework Clear Frameworks {collection.items.map((item) => ( {item} ))} ) } ``` #### Solid ```tsx import { Select, createListCollection, useSelect } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' export const SelectOnHighlight = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) const select = useSelect({ collection, onHighlightChange({ highlightedValue }) { if (highlightedValue) { select().selectValue(highlightedValue) } }, }) return ( Framework Clear Frameworks {(item) => ( {item()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework Clear Frameworks {#each frameworks.items as item} {item.label} {/each} ``` ### Max Selection Here's an example of limiting the number of items that can be selected in a multiple select. **Example: max-selected** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/select.module.css' const items = ['React', 'Solid', 'Vue', 'Svelte'] const MAX_SELECTION = 2 const hasReachedMax = (value: string[]) => value.length >= MAX_SELECTION export const MaxSelected = () => { const [value, setValue] = useState([]) const collection = createListCollection({ items: items.map((item) => ({ label: item, value: item, disabled: hasReachedMax(value) && !value.includes(item), })), }) const handleValueChange = (details: Select.ValueChangeDetails) => { if (hasReachedMax(value) && details.value.length > value.length) return setValue(details.value) } return ( Framework Frameworks {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { Index, createMemo, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const items = ['React', 'Solid', 'Vue', 'Svelte'] const MAX_SELECTION = 2 const hasReachedMax = (value: string[]) => value.length >= MAX_SELECTION export const MaxSelected = () => { const [value, setValue] = createSignal([]) const collection = createMemo(() => createListCollection({ items: items.map((item) => ({ label: item, value: item, disabled: hasReachedMax(value()) && !value().includes(item), })), }), ) const handleValueChange = (details: Select.ValueChangeDetails) => { if (hasReachedMax(value()) && details.value.length > value().length) return setValue(details.value) } return ( Framework Frameworks {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework Frameworks {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Select All Use `selectAll()` from the select context to select all items at once. **Example: select-all** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/select.module.css' import button from 'styles/button.module.css' const SelectAllButton = () => { return ( {(api) => ( )} ) } export const SelectAll = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'] }) return ( Framework Clear {collection.items.map((item) => ( {item} ))} ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' import button from 'styles/button.module.css' const SelectAllButton = () => { return ( {(api) => ( )} ) } export const SelectAll = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'] }) return ( Framework Clear {(item) => ( {item()} )} ) } ``` #### Vue ```vue ``` ### 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. **Example: overflow** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/select.module.css' export const Overflow = () => { const collection = createListCollection({ items: [ 'Name 1', 'Name 2', 'Name 3', 'Name 4', 'Name 5', 'Name 6', 'Name 7', 'Name 8', 'Name 9', 'Name 10', 'Name 11', 'Name 12', 'Name 13', 'Name 14', ], }) return ( Framework Clear Names {collection.items.map((item) => ( {item} ))} ) } ``` ## Guides ### Type Safety The `Select.RootComponent` type enables you to create typed wrapper components that maintain full type safety for collection items. ```tsx const Select: ArkSelect.RootComponent = (props) => { return {/* ... */} } ``` Use the wrapper with full type inference on `onValueChange` and other callbacks: ```tsx const App = () => { const collection = createListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, ], }) return ( ) } ``` ### Nested Usage When using the Select component within a `Popover` or `Dialog`, avoid rendering its content within a `Portal` or `Teleport`. This ensures the Select's content stays within the Popover/Dialog's DOM hierarchy rather than being portalled to the document body, maintaining proper interaction and accessibility behavior. ### Hidden Select The `Select.HiddenSelect` component renders a native HTML `` element exists in the DOM - **Browser auto-fill**: Browsers can properly auto-fill the select based on previously submitted form data - **Progressive enhancement**: Forms remain functional even if JavaScript fails to load ```tsx {/* Other Select components */} ``` The hidden select automatically syncs with the Select component's value, ensuring form data is always up-to-date. ### Empty State You can create an empty state component that displays when there are no items in the collection. Use the `useSelectContext` hook to check the collection size: ```tsx const SelectEmpty = (props: React.ComponentProps<'div'>) => { const select = useSelectContext() if (select.collection.size === 0) { return
                    } return null } ``` Then use it within your Select content: ```tsx No items to display {/* Your items */} ``` ### Available Size The following css variables are exposed to the `Select.Positioner` which you can use to style the `Select.Content` ```css /* width of the select trigger */ --reference-width: ; /* width of the available viewport */ --available-width: ; /* height of the available viewport */ --available-height: ; ``` For example, if you want to make sure the maximum height doesn't exceed the available height, you can use the following: ```css [data-scope='select'][data-part='content'] { max-height: calc(var(--available-height) - 100px); } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected | | `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the select. | | `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user | | `defaultValue` | `string[]` | No | The initial default value of the select when rendered. Use when you don't need to control the value of the select. | | `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item. **Note:** this is only applicable for single selection | | `disabled` | `boolean` | No | Whether the select is disabled | | `form` | `string` | No | The associate form of the underlying select. | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string control: string trigger: string clearTrigger: string label: string hiddenSelect: string positioner: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the select. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `invalid` | `boolean` | No | Whether the select is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `multiple` | `boolean` | No | Whether to allow multiple selection | | `name` | `string` | No | The `name` attribute of the underlying select. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `open` | `boolean` | No | Whether the select menu is open | | `positioning` | `PositioningOptions` | No | The positioning options of the menu. | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the select is read-only | | `required` | `boolean` | No | Whether the select is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-activedescendant]` | The id the active descendant of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested selects | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **HiddenSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-state]` | "checked" | "unchecked" | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSelectReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-placement]` | The placement of the trigger | | `[data-placeholder-shown]` | Present when placeholder is shown | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is selected. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected | | `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the select. | | `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user | | `defaultValue` | `string[]` | No | The initial default value of the select when rendered. Use when you don't need to control the value of the select. | | `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item. **Note:** this is only applicable for single selection | | `disabled` | `boolean` | No | Whether the select is disabled | | `form` | `string` | No | The associate form of the underlying select. | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string control: string trigger: string clearTrigger: string label: string hiddenSelect: string positioner: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the select. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `invalid` | `boolean` | No | Whether the select is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `multiple` | `boolean` | No | Whether to allow multiple selection | | `name` | `string` | No | The `name` attribute of the underlying select. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `open` | `boolean` | No | Whether the select menu is open | | `positioning` | `PositioningOptions` | No | The positioning options of the menu. | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the select is read-only | | `required` | `boolean` | No | Whether the select is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-activedescendant]` | The id the active descendant of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested selects | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **HiddenSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-state]` | "checked" | "unchecked" | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSelectReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-placement]` | The placement of the trigger | | `[data-placeholder-shown]` | Present when placeholder is shown | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is selected. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected | | `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the select. | | `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user | | `defaultValue` | `string[]` | No | The initial default value of the select when rendered. Use when you don't need to control the value of the select. | | `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item. **Note:** this is only applicable for single selection | | `disabled` | `boolean` | No | Whether the select is disabled | | `form` | `string` | No | The associate form of the underlying select. | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string control: string trigger: string clearTrigger: string label: string hiddenSelect: string positioner: string item(id: string | number): string itemGroup(id: string | number): string itemGroupLabel(id: string | number): string }>` | No | The ids of the elements in the select. Useful for composition. | | `invalid` | `boolean` | No | Whether the select is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `modelValue` | `string[]` | No | The model value of the select | | `multiple` | `boolean` | No | Whether to allow multiple selection | | `name` | `string` | No | The `name` attribute of the underlying select. | | `open` | `boolean` | No | Whether the select menu is open | | `positioning` | `PositioningOptions` | No | The positioning options of the menu. | | `readOnly` | `boolean` | No | Whether the select is read-only | | `required` | `boolean` | No | Whether the select is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-activedescendant]` | The id the active descendant of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested selects | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **HiddenSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-state]` | "checked" | "unchecked" | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SelectApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-placement]` | The placement of the trigger | | `[data-placeholder-shown]` | Present when placeholder is shown | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected | | `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the select. | | `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user | | `defaultValue` | `string[]` | No | The initial default value of the select when rendered. Use when you don't need to control the value of the select. | | `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item. **Note:** this is only applicable for single selection | | `disabled` | `boolean` | No | Whether the select is disabled | | `form` | `string` | No | The associate form of the underlying select. | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string control: string trigger: string clearTrigger: string label: string hiddenSelect: string positioner: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the select. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `invalid` | `boolean` | No | Whether the select is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `multiple` | `boolean` | No | Whether to allow multiple selection | | `name` | `string` | No | The `name` attribute of the underlying select. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `open` | `boolean` | No | Whether the select menu is open | | `positioning` | `PositioningOptions` | No | The positioning options of the menu. | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the select is read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the select is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-activedescendant]` | The id the active descendant of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested selects | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSelectReturn]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **HiddenSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSelectItemContext]>` | Yes | | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | | `ref` | `Element` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `item` | `NonNullable` | No | | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-state]` | "checked" | "unchecked" | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSelectReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `ref` | `Element` | No | | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-placement]` | The placement of the trigger | | `[data-placeholder-shown]` | Present when placeholder is shown | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | | | `ref` | `Element` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focused` | `boolean` | Whether the select is focused | | `open` | `boolean` | Whether the select is open | | `empty` | `boolean` | Whether the select value is empty | | `highlightedValue` | `string` | The value of the highlighted item | | `highlightedItem` | `V` | The highlighted item | | `setHighlightValue` | `(value: string) => void` | Function to highlight a value | | `clearHighlightValue` | `VoidFunction` | Function to clear the highlighted value | | `selectedItems` | `V[]` | The selected items | | `hasSelectedItems` | `boolean` | Whether there's a selected option | | `value` | `string[]` | The selected item keys | | `valueAsString` | `string` | The string representation of the selected items | | `selectValue` | `(value: string) => void` | Function to select a value | | `selectAll` | `VoidFunction` | Function to select all values | | `setValue` | `(value: string[]) => void` | Function to set the value of the select | | `clearValue` | `(value?: string) => void` | Function to clear the value of the select. If a value is provided, it will only clear that value, otherwise, it will clear all values. | | `focus` | `VoidFunction` | Function to focus on the select input | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a select item | | `setOpen` | `(open: boolean) => void` | Function to open or close the select | | `collection` | `ListCollection` | Function to toggle the select | | `reposition` | `(options?: Partial) => void` | Function to set the positioning options of the select | | `multiple` | `boolean` | Whether the select allows multiple selections | | `disabled` | `boolean` | Whether the select is disabled | ## Accessibility Complies with the [Listbox WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/listbox/). ### Keyboard Support **`Space`** Description: When focus is on trigger, opens the select and focuses the first selected item.
                    When focus is on the content, selects the highlighted item.
                    **`Enter`** Description: When focus is on trigger, opens the select and focuses the first selected item.
                    When focus is on content, selects the focused item.
                    **`ArrowDown`** Description: When focus is on trigger, opens the select.
                    When focus is on content, moves focus to the next item.
                    **`ArrowUp`** Description: When focus is on trigger, opens the select.
                    When focus is on content, moves focus to the previous item.
                    **`Esc`** Description: Closes the select and moves focus to trigger. **`A-Z + a-z`** Description: When focus is on trigger, selects the item whose label starts with the typed character.
                    When focus is on the listbox, moves focus to the next item with a label that starts with the typed character.
                    --- # Select (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ], }) export const Basic = () => { return ( Framework
                    Frameworks {frameworks.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ], }) export const Basic = () => { return ( Framework
                    Frameworks {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework
                    Frameworks {#each frameworks.items as item} {item.label} {/each}
                    ``` ### Controlled Use the `value` and `onValueChange` props to control the selected items. **Example: controlled** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/select.module.css' interface Item { label: string value: string disabled?: boolean | undefined } export const Controlled = () => { const [value, setValue] = useState([]) const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte', disabled: true }, ], }) const handleValueChange = (details: Select.ValueChangeDetails) => { setValue(details.value) } return ( Framework
                    Frameworks {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' interface Item { label: string value: string disabled?: boolean } export const Controlled = () => { const [value, setValue] = createSignal([]) const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte', disabled: true }, ], }) const handleValueChange = (details: Select.ValueChangeDetails) => { setValue(details.value) } return ( Framework
                    Frameworks {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework
                    Frameworks {#each collection.items as item (item.value)} {item.label} {/each}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection, useSelect } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ], }) export const RootProvider = () => { const select = useSelect({ collection: frameworks }) return ( <> selected: {JSON.stringify(select.value)} Framework
                    Frameworks {frameworks.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection, useSelect } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ], }) export const RootProvider = () => { const select = useSelect({ collection: frameworks }) return ( <> selected: {JSON.stringify(select().value)} Framework
                    Frameworks {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Framework
                    Frameworks {#each frameworks.items as item} {item.label} {/each}
                    ``` ### Multiple To enable `multiple` item selection: **Example: multiple** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte', disabled: true }, ], }) export const Multiple = () => { return ( Framework
                    Frameworks {frameworks.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte', disabled: true }, ], }) export const Multiple = () => { return ( Framework
                    Frameworks {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework
                    Frameworks {#each frameworks.items as item (item.value)} {item.label} {/each}
                    ``` ### 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. **Example: grouping** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react', type: 'JS' }, { label: 'Solid', value: 'solid', type: 'JS' }, { label: 'Vue', value: 'vue', type: 'JS' }, { label: 'Panda', value: 'panda', type: 'CSS' }, { label: 'Tailwind', value: 'tailwind', type: 'CSS' }, ], groupBy: (item) => item.type, }) export const Grouping = () => { return ( Framework
                    {frameworks.group().map(([type, group]) => ( {type} {group.map((item) => ( {item.label} ))} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react', type: 'JS' }, { label: 'Solid', value: 'solid', type: 'JS' }, { label: 'Vue', value: 'vue', type: 'JS' }, { label: 'Panda', value: 'panda', type: 'CSS' }, { label: 'Tailwind', value: 'tailwind', type: 'CSS' }, ], groupBy: (item) => item.type, }) export const Grouping = () => { return ( Framework
                    {([type, group]) => ( {type} {(item) => ( {item.label} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework
                    {#each frameworks.group() as [type, group]} {type} {#each group as item (item.value)} {item.label} {/each} {/each}
                    ``` ### Field Use `Field` to manage form state, ARIA labels, helper text, and error text. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/select.module.css' export const WithField = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'] }) return ( Label {collection.items.map((item) => ( {item} ))} Additional Info Error Info ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index } from 'solid-js/web' import field from 'styles/field.module.css' import styles from 'styles/select.module.css' export const WithField = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'] }) return ( Label {(item) => ( {item()} )} Additional Info Error Info ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each collection.items as item} {item} {/each} Additional Info Error Info ``` ### Form Usage Here's an example of integrating the `Select` component with a form library. **Example: form-library** #### React ```tsx import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import { Controller, type SubmitHandler, useForm } from 'react-hook-form' import button from 'styles/button.module.css' import styles from 'styles/select.module.css' interface Inputs { framework: string } export const FormLibrary = () => { const { control, handleSubmit } = useForm({ defaultValues: { framework: 'React' }, }) const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) const onSubmit: SubmitHandler = (data) => { window.alert(JSON.stringify(data)) } return (
                    ( field.onChange(e.value[0])} name={field.name} onInteractOutside={() => field.onBlur()} > Framework
                    Frameworks {collection.items.map((item) => ( {item} ))}
                    )} /> ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { createForm, getValue, setValue } from '@modular-forms/solid' import { createMemo } from 'solid-js' import { Index, Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ], }) export const FormLibrary = () => { const [formStore, { Form, Field }] = createForm({ initialValues: { value: 'solid' }, }) const value = createMemo(() => getValue(formStore, 'value')) return ( <>
                    Value is {value()}
                    { window.alert(JSON.stringify(data)) }} > {(field, props) => ( setValue(formStore, field.name, e.value[0])} > Framework
                    Frameworks {(item) => ( {item().label} )}
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Value is {formData.framework}
                    { e.preventDefault() form.handleSubmit() }} > {#snippet children(field)} {@const state = field.state} 0} name={field.name} onValueChange={(details) => { field.handleChange(details.value[0]) }} > Framework
                    Frameworks {#each frameworks.items as item} {item.label} {/each}
                    {/snippet}
                    ``` ### Async Loading Here's an example of how to load the items asynchronously when the select is opened. **Example: async** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/select.module.css' function loadData() { return new Promise((resolve) => { setTimeout(() => resolve(['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Ember']), 500) }) } export const Async = () => { const [items, setItems] = useState(null) const [loading, setLoading] = useState(false) const [error, setError] = useState(null) const collection = createListCollection({ items: items || [], }) const handleOpenChange = (details: Select.OpenChangeDetails) => { if (details.open && items == null) { setLoading(true) setError(null) loadData() .then((data) => setItems(data)) .catch((err) => setError(err)) .finally(() => setLoading(false)) } } return ( Framework {loading ? (
                    Loading...
                    ) : error ? (
                    Error: {error.message}
                    ) : ( collection.items.map((item) => ( {item} )) )}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, Match, Switch, createMemo, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/select.module.css' function loadData() { return new Promise((resolve) => { setTimeout(() => resolve(['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Ember']), 500) }) } export const Async = () => { const [items, setItems] = createSignal(null) const [loading, setLoading] = createSignal(false) const [error, setError] = createSignal(null) const collection = createMemo(() => createListCollection({ items: items() || [], }), ) const handleOpenChange = (details: Select.OpenChangeDetails) => { if (details.open && items() === null) { setLoading(true) setError(null) loadData() .then((data) => setItems(data)) .catch((err) => setError(err)) .finally(() => setLoading(false)) } } return ( Framework
                    Loading...
                    Error: {error()?.message}
                    {(item) => ( {item()} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#if loading}
                    Loading...
                    {:else if error}
                    Error: {error.message}
                    {:else} {#each collection.items as item} {item} {/each} {/if}
                    ``` ### Lazy Mount Use `lazyMount` and `unmountOnExit` to control when content is mounted, improving performance. **Example: lazy-mount** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/select.module.css' export const LazyMount = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Alpine'], }) return ( Framework Clear Frameworks {collection.items.map((item) => ( {item} ))} ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' export const LazyMount = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Alpine'], }) return ( Framework Clear Frameworks {(item) => ( {item()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework Clear Frameworks {#each collection.items as item} {item} {/each} ``` ### Select on Highlight Here's an example of automatically selecting items when they are highlighted (hovered or navigated to with keyboard). **Example: select-on-highlight** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection, useSelect } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/select.module.css' export const SelectOnHighlight = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) const select = useSelect({ collection, onHighlightChange({ highlightedValue }) { if (highlightedValue) { select.selectValue(highlightedValue) } }, }) return ( Framework Clear Frameworks {collection.items.map((item) => ( {item} ))} ) } ``` #### Solid ```tsx import { Select, createListCollection, useSelect } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' export const SelectOnHighlight = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) const select = useSelect({ collection, onHighlightChange({ highlightedValue }) { if (highlightedValue) { select().selectValue(highlightedValue) } }, }) return ( Framework Clear Frameworks {(item) => ( {item()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework Clear Frameworks {#each frameworks.items as item} {item.label} {/each} ``` ### Max Selection Here's an example of limiting the number of items that can be selected in a multiple select. **Example: max-selected** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/select.module.css' const items = ['React', 'Solid', 'Vue', 'Svelte'] const MAX_SELECTION = 2 const hasReachedMax = (value: string[]) => value.length >= MAX_SELECTION export const MaxSelected = () => { const [value, setValue] = useState([]) const collection = createListCollection({ items: items.map((item) => ({ label: item, value: item, disabled: hasReachedMax(value) && !value.includes(item), })), }) const handleValueChange = (details: Select.ValueChangeDetails) => { if (hasReachedMax(value) && details.value.length > value.length) return setValue(details.value) } return ( Framework Frameworks {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { Index, createMemo, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const items = ['React', 'Solid', 'Vue', 'Svelte'] const MAX_SELECTION = 2 const hasReachedMax = (value: string[]) => value.length >= MAX_SELECTION export const MaxSelected = () => { const [value, setValue] = createSignal([]) const collection = createMemo(() => createListCollection({ items: items.map((item) => ({ label: item, value: item, disabled: hasReachedMax(value()) && !value().includes(item), })), }), ) const handleValueChange = (details: Select.ValueChangeDetails) => { if (hasReachedMax(value()) && details.value.length > value().length) return setValue(details.value) } return ( Framework Frameworks {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework Frameworks {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Select All Use `selectAll()` from the select context to select all items at once. **Example: select-all** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/select.module.css' import button from 'styles/button.module.css' const SelectAllButton = () => { return ( {(api) => ( )} ) } export const SelectAll = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'] }) return ( Framework Clear {collection.items.map((item) => ( {item} ))} ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' import button from 'styles/button.module.css' const SelectAllButton = () => { return ( {(api) => ( )} ) } export const SelectAll = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'] }) return ( Framework Clear {(item) => ( {item()} )} ) } ``` #### Vue ```vue ``` ### 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. **Example: overflow** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/select.module.css' export const Overflow = () => { const collection = createListCollection({ items: [ 'Name 1', 'Name 2', 'Name 3', 'Name 4', 'Name 5', 'Name 6', 'Name 7', 'Name 8', 'Name 9', 'Name 10', 'Name 11', 'Name 12', 'Name 13', 'Name 14', ], }) return ( Framework Clear Names {collection.items.map((item) => ( {item} ))} ) } ``` ## Guides ### Type Safety The `Select.RootComponent` type enables you to create typed wrapper components that maintain full type safety for collection items. ```tsx const Select: ArkSelect.RootComponent = (props) => { return {/* ... */} } ``` Use the wrapper with full type inference on `onValueChange` and other callbacks: ```tsx const App = () => { const collection = createListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, ], }) return ( ) } ``` ### Nested Usage When using the Select component within a `Popover` or `Dialog`, avoid rendering its content within a `Portal` or `Teleport`. This ensures the Select's content stays within the Popover/Dialog's DOM hierarchy rather than being portalled to the document body, maintaining proper interaction and accessibility behavior. ### Hidden Select The `Select.HiddenSelect` component renders a native HTML `` element exists in the DOM - **Browser auto-fill**: Browsers can properly auto-fill the select based on previously submitted form data - **Progressive enhancement**: Forms remain functional even if JavaScript fails to load ```tsx {/* Other Select components */} ``` The hidden select automatically syncs with the Select component's value, ensuring form data is always up-to-date. ### Empty State You can create an empty state component that displays when there are no items in the collection. Use the `useSelectContext` hook to check the collection size: ```tsx const SelectEmpty = (props: React.ComponentProps<'div'>) => { const select = useSelectContext() if (select.collection.size === 0) { return
                    } return null } ``` Then use it within your Select content: ```tsx No items to display {/* Your items */} ``` ### Available Size The following css variables are exposed to the `Select.Positioner` which you can use to style the `Select.Content` ```css /* width of the select trigger */ --reference-width: ; /* width of the available viewport */ --available-width: ; /* height of the available viewport */ --available-height: ; ``` For example, if you want to make sure the maximum height doesn't exceed the available height, you can use the following: ```css [data-scope='select'][data-part='content'] { max-height: calc(var(--available-height) - 100px); } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected | | `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the select. | | `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user | | `defaultValue` | `string[]` | No | The initial default value of the select when rendered. Use when you don't need to control the value of the select. | | `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item. **Note:** this is only applicable for single selection | | `disabled` | `boolean` | No | Whether the select is disabled | | `form` | `string` | No | The associate form of the underlying select. | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string control: string trigger: string clearTrigger: string label: string hiddenSelect: string positioner: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the select. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `invalid` | `boolean` | No | Whether the select is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `multiple` | `boolean` | No | Whether to allow multiple selection | | `name` | `string` | No | The `name` attribute of the underlying select. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `open` | `boolean` | No | Whether the select menu is open | | `positioning` | `PositioningOptions` | No | The positioning options of the menu. | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the select is read-only | | `required` | `boolean` | No | Whether the select is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-activedescendant]` | The id the active descendant of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested selects | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **HiddenSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-state]` | "checked" | "unchecked" | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSelectReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-placement]` | The placement of the trigger | | `[data-placeholder-shown]` | Present when placeholder is shown | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is selected. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected | | `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the select. | | `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user | | `defaultValue` | `string[]` | No | The initial default value of the select when rendered. Use when you don't need to control the value of the select. | | `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item. **Note:** this is only applicable for single selection | | `disabled` | `boolean` | No | Whether the select is disabled | | `form` | `string` | No | The associate form of the underlying select. | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string control: string trigger: string clearTrigger: string label: string hiddenSelect: string positioner: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the select. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `invalid` | `boolean` | No | Whether the select is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `multiple` | `boolean` | No | Whether to allow multiple selection | | `name` | `string` | No | The `name` attribute of the underlying select. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `open` | `boolean` | No | Whether the select menu is open | | `positioning` | `PositioningOptions` | No | The positioning options of the menu. | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the select is read-only | | `required` | `boolean` | No | Whether the select is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-activedescendant]` | The id the active descendant of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested selects | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **HiddenSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-state]` | "checked" | "unchecked" | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSelectReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-placement]` | The placement of the trigger | | `[data-placeholder-shown]` | Present when placeholder is shown | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is selected. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected | | `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the select. | | `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user | | `defaultValue` | `string[]` | No | The initial default value of the select when rendered. Use when you don't need to control the value of the select. | | `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item. **Note:** this is only applicable for single selection | | `disabled` | `boolean` | No | Whether the select is disabled | | `form` | `string` | No | The associate form of the underlying select. | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string control: string trigger: string clearTrigger: string label: string hiddenSelect: string positioner: string item(id: string | number): string itemGroup(id: string | number): string itemGroupLabel(id: string | number): string }>` | No | The ids of the elements in the select. Useful for composition. | | `invalid` | `boolean` | No | Whether the select is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `modelValue` | `string[]` | No | The model value of the select | | `multiple` | `boolean` | No | Whether to allow multiple selection | | `name` | `string` | No | The `name` attribute of the underlying select. | | `open` | `boolean` | No | Whether the select menu is open | | `positioning` | `PositioningOptions` | No | The positioning options of the menu. | | `readOnly` | `boolean` | No | Whether the select is read-only | | `required` | `boolean` | No | Whether the select is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-activedescendant]` | The id the active descendant of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested selects | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **HiddenSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-state]` | "checked" | "unchecked" | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SelectApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-placement]` | The placement of the trigger | | `[data-placeholder-shown]` | Present when placeholder is shown | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected | | `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the select. | | `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user | | `defaultValue` | `string[]` | No | The initial default value of the select when rendered. Use when you don't need to control the value of the select. | | `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item. **Note:** this is only applicable for single selection | | `disabled` | `boolean` | No | Whether the select is disabled | | `form` | `string` | No | The associate form of the underlying select. | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string control: string trigger: string clearTrigger: string label: string hiddenSelect: string positioner: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the select. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `invalid` | `boolean` | No | Whether the select is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `multiple` | `boolean` | No | Whether to allow multiple selection | | `name` | `string` | No | The `name` attribute of the underlying select. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `open` | `boolean` | No | Whether the select menu is open | | `positioning` | `PositioningOptions` | No | The positioning options of the menu. | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the select is read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the select is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-activedescendant]` | The id the active descendant of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested selects | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSelectReturn]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **HiddenSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSelectItemContext]>` | Yes | | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | | `ref` | `Element` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `item` | `NonNullable` | No | | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-state]` | "checked" | "unchecked" | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSelectReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `ref` | `Element` | No | | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-placement]` | The placement of the trigger | | `[data-placeholder-shown]` | Present when placeholder is shown | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | | | `ref` | `Element` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focused` | `boolean` | Whether the select is focused | | `open` | `boolean` | Whether the select is open | | `empty` | `boolean` | Whether the select value is empty | | `highlightedValue` | `string` | The value of the highlighted item | | `highlightedItem` | `V` | The highlighted item | | `setHighlightValue` | `(value: string) => void` | Function to highlight a value | | `clearHighlightValue` | `VoidFunction` | Function to clear the highlighted value | | `selectedItems` | `V[]` | The selected items | | `hasSelectedItems` | `boolean` | Whether there's a selected option | | `value` | `string[]` | The selected item keys | | `valueAsString` | `string` | The string representation of the selected items | | `selectValue` | `(value: string) => void` | Function to select a value | | `selectAll` | `VoidFunction` | Function to select all values | | `setValue` | `(value: string[]) => void` | Function to set the value of the select | | `clearValue` | `(value?: string) => void` | Function to clear the value of the select. If a value is provided, it will only clear that value, otherwise, it will clear all values. | | `focus` | `VoidFunction` | Function to focus on the select input | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a select item | | `setOpen` | `(open: boolean) => void` | Function to open or close the select | | `collection` | `ListCollection` | Function to toggle the select | | `reposition` | `(options?: Partial) => void` | Function to set the positioning options of the select | | `multiple` | `boolean` | Whether the select allows multiple selections | | `disabled` | `boolean` | Whether the select is disabled | ## Accessibility Complies with the [Listbox WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/listbox/). ### Keyboard Support **`Space`** Description: When focus is on trigger, opens the select and focuses the first selected item.
                    When focus is on the content, selects the highlighted item.
                    **`Enter`** Description: When focus is on trigger, opens the select and focuses the first selected item.
                    When focus is on content, selects the focused item.
                    **`ArrowDown`** Description: When focus is on trigger, opens the select.
                    When focus is on content, moves focus to the next item.
                    **`ArrowUp`** Description: When focus is on trigger, opens the select.
                    When focus is on content, moves focus to the previous item.
                    **`Esc`** Description: Closes the select and moves focus to trigger. **`A-Z + a-z`** Description: When focus is on trigger, selects the item whose label starts with the typed character.
                    When focus is on the listbox, moves focus to the next item with a label that starts with the typed character.
                    --- # Select (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ], }) export const Basic = () => { return ( Framework
                    Frameworks {frameworks.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ], }) export const Basic = () => { return ( Framework
                    Frameworks {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework
                    Frameworks {#each frameworks.items as item} {item.label} {/each}
                    ``` ### Controlled Use the `value` and `onValueChange` props to control the selected items. **Example: controlled** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/select.module.css' interface Item { label: string value: string disabled?: boolean | undefined } export const Controlled = () => { const [value, setValue] = useState([]) const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte', disabled: true }, ], }) const handleValueChange = (details: Select.ValueChangeDetails) => { setValue(details.value) } return ( Framework
                    Frameworks {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' interface Item { label: string value: string disabled?: boolean } export const Controlled = () => { const [value, setValue] = createSignal([]) const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte', disabled: true }, ], }) const handleValueChange = (details: Select.ValueChangeDetails) => { setValue(details.value) } return ( Framework
                    Frameworks {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework
                    Frameworks {#each collection.items as item (item.value)} {item.label} {/each}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection, useSelect } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ], }) export const RootProvider = () => { const select = useSelect({ collection: frameworks }) return ( <> selected: {JSON.stringify(select.value)} Framework
                    Frameworks {frameworks.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection, useSelect } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ], }) export const RootProvider = () => { const select = useSelect({ collection: frameworks }) return ( <> selected: {JSON.stringify(select().value)} Framework
                    Frameworks {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Framework
                    Frameworks {#each frameworks.items as item} {item.label} {/each}
                    ``` ### Multiple To enable `multiple` item selection: **Example: multiple** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte', disabled: true }, ], }) export const Multiple = () => { return ( Framework
                    Frameworks {frameworks.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte', disabled: true }, ], }) export const Multiple = () => { return ( Framework
                    Frameworks {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework
                    Frameworks {#each frameworks.items as item (item.value)} {item.label} {/each}
                    ``` ### 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. **Example: grouping** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react', type: 'JS' }, { label: 'Solid', value: 'solid', type: 'JS' }, { label: 'Vue', value: 'vue', type: 'JS' }, { label: 'Panda', value: 'panda', type: 'CSS' }, { label: 'Tailwind', value: 'tailwind', type: 'CSS' }, ], groupBy: (item) => item.type, }) export const Grouping = () => { return ( Framework
                    {frameworks.group().map(([type, group]) => ( {type} {group.map((item) => ( {item.label} ))} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react', type: 'JS' }, { label: 'Solid', value: 'solid', type: 'JS' }, { label: 'Vue', value: 'vue', type: 'JS' }, { label: 'Panda', value: 'panda', type: 'CSS' }, { label: 'Tailwind', value: 'tailwind', type: 'CSS' }, ], groupBy: (item) => item.type, }) export const Grouping = () => { return ( Framework
                    {([type, group]) => ( {type} {(item) => ( {item.label} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework
                    {#each frameworks.group() as [type, group]} {type} {#each group as item (item.value)} {item.label} {/each} {/each}
                    ``` ### Field Use `Field` to manage form state, ARIA labels, helper text, and error text. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/select.module.css' export const WithField = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'] }) return ( Label {collection.items.map((item) => ( {item} ))} Additional Info Error Info ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index } from 'solid-js/web' import field from 'styles/field.module.css' import styles from 'styles/select.module.css' export const WithField = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'] }) return ( Label {(item) => ( {item()} )} Additional Info Error Info ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each collection.items as item} {item} {/each} Additional Info Error Info ``` ### Form Usage Here's an example of integrating the `Select` component with a form library. **Example: form-library** #### React ```tsx import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import { Controller, type SubmitHandler, useForm } from 'react-hook-form' import button from 'styles/button.module.css' import styles from 'styles/select.module.css' interface Inputs { framework: string } export const FormLibrary = () => { const { control, handleSubmit } = useForm({ defaultValues: { framework: 'React' }, }) const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) const onSubmit: SubmitHandler = (data) => { window.alert(JSON.stringify(data)) } return (
                    ( field.onChange(e.value[0])} name={field.name} onInteractOutside={() => field.onBlur()} > Framework
                    Frameworks {collection.items.map((item) => ( {item} ))}
                    )} /> ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { createForm, getValue, setValue } from '@modular-forms/solid' import { createMemo } from 'solid-js' import { Index, Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ], }) export const FormLibrary = () => { const [formStore, { Form, Field }] = createForm({ initialValues: { value: 'solid' }, }) const value = createMemo(() => getValue(formStore, 'value')) return ( <>
                    Value is {value()}
                    { window.alert(JSON.stringify(data)) }} > {(field, props) => ( setValue(formStore, field.name, e.value[0])} > Framework
                    Frameworks {(item) => ( {item().label} )}
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Value is {formData.framework}
                    { e.preventDefault() form.handleSubmit() }} > {#snippet children(field)} {@const state = field.state} 0} name={field.name} onValueChange={(details) => { field.handleChange(details.value[0]) }} > Framework
                    Frameworks {#each frameworks.items as item} {item.label} {/each}
                    {/snippet}
                    ``` ### Async Loading Here's an example of how to load the items asynchronously when the select is opened. **Example: async** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/select.module.css' function loadData() { return new Promise((resolve) => { setTimeout(() => resolve(['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Ember']), 500) }) } export const Async = () => { const [items, setItems] = useState(null) const [loading, setLoading] = useState(false) const [error, setError] = useState(null) const collection = createListCollection({ items: items || [], }) const handleOpenChange = (details: Select.OpenChangeDetails) => { if (details.open && items == null) { setLoading(true) setError(null) loadData() .then((data) => setItems(data)) .catch((err) => setError(err)) .finally(() => setLoading(false)) } } return ( Framework {loading ? (
                    Loading...
                    ) : error ? (
                    Error: {error.message}
                    ) : ( collection.items.map((item) => ( {item} )) )}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, Match, Switch, createMemo, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/select.module.css' function loadData() { return new Promise((resolve) => { setTimeout(() => resolve(['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Ember']), 500) }) } export const Async = () => { const [items, setItems] = createSignal(null) const [loading, setLoading] = createSignal(false) const [error, setError] = createSignal(null) const collection = createMemo(() => createListCollection({ items: items() || [], }), ) const handleOpenChange = (details: Select.OpenChangeDetails) => { if (details.open && items() === null) { setLoading(true) setError(null) loadData() .then((data) => setItems(data)) .catch((err) => setError(err)) .finally(() => setLoading(false)) } } return ( Framework
                    Loading...
                    Error: {error()?.message}
                    {(item) => ( {item()} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#if loading}
                    Loading...
                    {:else if error}
                    Error: {error.message}
                    {:else} {#each collection.items as item} {item} {/each} {/if}
                    ``` ### Lazy Mount Use `lazyMount` and `unmountOnExit` to control when content is mounted, improving performance. **Example: lazy-mount** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/select.module.css' export const LazyMount = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Alpine'], }) return ( Framework Clear Frameworks {collection.items.map((item) => ( {item} ))} ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' export const LazyMount = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Alpine'], }) return ( Framework Clear Frameworks {(item) => ( {item()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework Clear Frameworks {#each collection.items as item} {item} {/each} ``` ### Select on Highlight Here's an example of automatically selecting items when they are highlighted (hovered or navigated to with keyboard). **Example: select-on-highlight** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection, useSelect } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/select.module.css' export const SelectOnHighlight = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) const select = useSelect({ collection, onHighlightChange({ highlightedValue }) { if (highlightedValue) { select.selectValue(highlightedValue) } }, }) return ( Framework Clear Frameworks {collection.items.map((item) => ( {item} ))} ) } ``` #### Solid ```tsx import { Select, createListCollection, useSelect } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' export const SelectOnHighlight = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) const select = useSelect({ collection, onHighlightChange({ highlightedValue }) { if (highlightedValue) { select().selectValue(highlightedValue) } }, }) return ( Framework Clear Frameworks {(item) => ( {item()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework Clear Frameworks {#each frameworks.items as item} {item.label} {/each} ``` ### Max Selection Here's an example of limiting the number of items that can be selected in a multiple select. **Example: max-selected** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/select.module.css' const items = ['React', 'Solid', 'Vue', 'Svelte'] const MAX_SELECTION = 2 const hasReachedMax = (value: string[]) => value.length >= MAX_SELECTION export const MaxSelected = () => { const [value, setValue] = useState([]) const collection = createListCollection({ items: items.map((item) => ({ label: item, value: item, disabled: hasReachedMax(value) && !value.includes(item), })), }) const handleValueChange = (details: Select.ValueChangeDetails) => { if (hasReachedMax(value) && details.value.length > value.length) return setValue(details.value) } return ( Framework Frameworks {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { Index, createMemo, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const items = ['React', 'Solid', 'Vue', 'Svelte'] const MAX_SELECTION = 2 const hasReachedMax = (value: string[]) => value.length >= MAX_SELECTION export const MaxSelected = () => { const [value, setValue] = createSignal([]) const collection = createMemo(() => createListCollection({ items: items.map((item) => ({ label: item, value: item, disabled: hasReachedMax(value()) && !value().includes(item), })), }), ) const handleValueChange = (details: Select.ValueChangeDetails) => { if (hasReachedMax(value()) && details.value.length > value().length) return setValue(details.value) } return ( Framework Frameworks {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework Frameworks {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Select All Use `selectAll()` from the select context to select all items at once. **Example: select-all** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/select.module.css' import button from 'styles/button.module.css' const SelectAllButton = () => { return ( {(api) => ( )} ) } export const SelectAll = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'] }) return ( Framework Clear {collection.items.map((item) => ( {item} ))} ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' import button from 'styles/button.module.css' const SelectAllButton = () => { return ( {(api) => ( )} ) } export const SelectAll = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'] }) return ( Framework Clear {(item) => ( {item()} )} ) } ``` #### Vue ```vue ``` ### 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. **Example: overflow** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/select.module.css' export const Overflow = () => { const collection = createListCollection({ items: [ 'Name 1', 'Name 2', 'Name 3', 'Name 4', 'Name 5', 'Name 6', 'Name 7', 'Name 8', 'Name 9', 'Name 10', 'Name 11', 'Name 12', 'Name 13', 'Name 14', ], }) return ( Framework Clear Names {collection.items.map((item) => ( {item} ))} ) } ``` ## Guides ### Type Safety The `Select.RootComponent` type enables you to create typed wrapper components that maintain full type safety for collection items. ```tsx const Select: ArkSelect.RootComponent = (props) => { return {/* ... */} } ``` Use the wrapper with full type inference on `onValueChange` and other callbacks: ```tsx const App = () => { const collection = createListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, ], }) return ( ) } ``` ### Nested Usage When using the Select component within a `Popover` or `Dialog`, avoid rendering its content within a `Portal` or `Teleport`. This ensures the Select's content stays within the Popover/Dialog's DOM hierarchy rather than being portalled to the document body, maintaining proper interaction and accessibility behavior. ### Hidden Select The `Select.HiddenSelect` component renders a native HTML `` element exists in the DOM - **Browser auto-fill**: Browsers can properly auto-fill the select based on previously submitted form data - **Progressive enhancement**: Forms remain functional even if JavaScript fails to load ```tsx {/* Other Select components */} ``` The hidden select automatically syncs with the Select component's value, ensuring form data is always up-to-date. ### Empty State You can create an empty state component that displays when there are no items in the collection. Use the `useSelectContext` hook to check the collection size: ```tsx const SelectEmpty = (props: React.ComponentProps<'div'>) => { const select = useSelectContext() if (select.collection.size === 0) { return
                    } return null } ``` Then use it within your Select content: ```tsx No items to display {/* Your items */} ``` ### Available Size The following css variables are exposed to the `Select.Positioner` which you can use to style the `Select.Content` ```css /* width of the select trigger */ --reference-width: ; /* width of the available viewport */ --available-width: ; /* height of the available viewport */ --available-height: ; ``` For example, if you want to make sure the maximum height doesn't exceed the available height, you can use the following: ```css [data-scope='select'][data-part='content'] { max-height: calc(var(--available-height) - 100px); } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected | | `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the select. | | `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user | | `defaultValue` | `string[]` | No | The initial default value of the select when rendered. Use when you don't need to control the value of the select. | | `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item. **Note:** this is only applicable for single selection | | `disabled` | `boolean` | No | Whether the select is disabled | | `form` | `string` | No | The associate form of the underlying select. | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string control: string trigger: string clearTrigger: string label: string hiddenSelect: string positioner: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the select. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `invalid` | `boolean` | No | Whether the select is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `multiple` | `boolean` | No | Whether to allow multiple selection | | `name` | `string` | No | The `name` attribute of the underlying select. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `open` | `boolean` | No | Whether the select menu is open | | `positioning` | `PositioningOptions` | No | The positioning options of the menu. | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the select is read-only | | `required` | `boolean` | No | Whether the select is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-activedescendant]` | The id the active descendant of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested selects | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **HiddenSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-state]` | "checked" | "unchecked" | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSelectReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-placement]` | The placement of the trigger | | `[data-placeholder-shown]` | Present when placeholder is shown | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is selected. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected | | `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the select. | | `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user | | `defaultValue` | `string[]` | No | The initial default value of the select when rendered. Use when you don't need to control the value of the select. | | `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item. **Note:** this is only applicable for single selection | | `disabled` | `boolean` | No | Whether the select is disabled | | `form` | `string` | No | The associate form of the underlying select. | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string control: string trigger: string clearTrigger: string label: string hiddenSelect: string positioner: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the select. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `invalid` | `boolean` | No | Whether the select is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `multiple` | `boolean` | No | Whether to allow multiple selection | | `name` | `string` | No | The `name` attribute of the underlying select. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `open` | `boolean` | No | Whether the select menu is open | | `positioning` | `PositioningOptions` | No | The positioning options of the menu. | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the select is read-only | | `required` | `boolean` | No | Whether the select is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-activedescendant]` | The id the active descendant of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested selects | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **HiddenSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-state]` | "checked" | "unchecked" | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSelectReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-placement]` | The placement of the trigger | | `[data-placeholder-shown]` | Present when placeholder is shown | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is selected. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected | | `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the select. | | `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user | | `defaultValue` | `string[]` | No | The initial default value of the select when rendered. Use when you don't need to control the value of the select. | | `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item. **Note:** this is only applicable for single selection | | `disabled` | `boolean` | No | Whether the select is disabled | | `form` | `string` | No | The associate form of the underlying select. | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string control: string trigger: string clearTrigger: string label: string hiddenSelect: string positioner: string item(id: string | number): string itemGroup(id: string | number): string itemGroupLabel(id: string | number): string }>` | No | The ids of the elements in the select. Useful for composition. | | `invalid` | `boolean` | No | Whether the select is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `modelValue` | `string[]` | No | The model value of the select | | `multiple` | `boolean` | No | Whether to allow multiple selection | | `name` | `string` | No | The `name` attribute of the underlying select. | | `open` | `boolean` | No | Whether the select menu is open | | `positioning` | `PositioningOptions` | No | The positioning options of the menu. | | `readOnly` | `boolean` | No | Whether the select is read-only | | `required` | `boolean` | No | Whether the select is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-activedescendant]` | The id the active descendant of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested selects | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **HiddenSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-state]` | "checked" | "unchecked" | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SelectApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-placement]` | The placement of the trigger | | `[data-placeholder-shown]` | Present when placeholder is shown | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected | | `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the select. | | `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user | | `defaultValue` | `string[]` | No | The initial default value of the select when rendered. Use when you don't need to control the value of the select. | | `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item. **Note:** this is only applicable for single selection | | `disabled` | `boolean` | No | Whether the select is disabled | | `form` | `string` | No | The associate form of the underlying select. | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string control: string trigger: string clearTrigger: string label: string hiddenSelect: string positioner: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the select. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `invalid` | `boolean` | No | Whether the select is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `multiple` | `boolean` | No | Whether to allow multiple selection | | `name` | `string` | No | The `name` attribute of the underlying select. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `open` | `boolean` | No | Whether the select menu is open | | `positioning` | `PositioningOptions` | No | The positioning options of the menu. | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the select is read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the select is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-activedescendant]` | The id the active descendant of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested selects | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSelectReturn]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **HiddenSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSelectItemContext]>` | Yes | | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | | `ref` | `Element` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `item` | `NonNullable` | No | | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-state]` | "checked" | "unchecked" | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSelectReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `ref` | `Element` | No | | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-placement]` | The placement of the trigger | | `[data-placeholder-shown]` | Present when placeholder is shown | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | | | `ref` | `Element` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focused` | `boolean` | Whether the select is focused | | `open` | `boolean` | Whether the select is open | | `empty` | `boolean` | Whether the select value is empty | | `highlightedValue` | `string` | The value of the highlighted item | | `highlightedItem` | `V` | The highlighted item | | `setHighlightValue` | `(value: string) => void` | Function to highlight a value | | `clearHighlightValue` | `VoidFunction` | Function to clear the highlighted value | | `selectedItems` | `V[]` | The selected items | | `hasSelectedItems` | `boolean` | Whether there's a selected option | | `value` | `string[]` | The selected item keys | | `valueAsString` | `string` | The string representation of the selected items | | `selectValue` | `(value: string) => void` | Function to select a value | | `selectAll` | `VoidFunction` | Function to select all values | | `setValue` | `(value: string[]) => void` | Function to set the value of the select | | `clearValue` | `(value?: string) => void` | Function to clear the value of the select. If a value is provided, it will only clear that value, otherwise, it will clear all values. | | `focus` | `VoidFunction` | Function to focus on the select input | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a select item | | `setOpen` | `(open: boolean) => void` | Function to open or close the select | | `collection` | `ListCollection` | Function to toggle the select | | `reposition` | `(options?: Partial) => void` | Function to set the positioning options of the select | | `multiple` | `boolean` | Whether the select allows multiple selections | | `disabled` | `boolean` | Whether the select is disabled | ## Accessibility Complies with the [Listbox WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/listbox/). ### Keyboard Support **`Space`** Description: When focus is on trigger, opens the select and focuses the first selected item.
                    When focus is on the content, selects the highlighted item.
                    **`Enter`** Description: When focus is on trigger, opens the select and focuses the first selected item.
                    When focus is on content, selects the focused item.
                    **`ArrowDown`** Description: When focus is on trigger, opens the select.
                    When focus is on content, moves focus to the next item.
                    **`ArrowUp`** Description: When focus is on trigger, opens the select.
                    When focus is on content, moves focus to the previous item.
                    **`Esc`** Description: Closes the select and moves focus to trigger. **`A-Z + a-z`** Description: When focus is on trigger, selects the item whose label starts with the typed character.
                    When focus is on the listbox, moves focus to the next item with a label that starts with the typed character.
                    --- # Select (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ], }) export const Basic = () => { return ( Framework
                    Frameworks {frameworks.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ], }) export const Basic = () => { return ( Framework
                    Frameworks {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework
                    Frameworks {#each frameworks.items as item} {item.label} {/each}
                    ``` ### Controlled Use the `value` and `onValueChange` props to control the selected items. **Example: controlled** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/select.module.css' interface Item { label: string value: string disabled?: boolean | undefined } export const Controlled = () => { const [value, setValue] = useState([]) const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte', disabled: true }, ], }) const handleValueChange = (details: Select.ValueChangeDetails) => { setValue(details.value) } return ( Framework
                    Frameworks {collection.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' interface Item { label: string value: string disabled?: boolean } export const Controlled = () => { const [value, setValue] = createSignal([]) const collection = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte', disabled: true }, ], }) const handleValueChange = (details: Select.ValueChangeDetails) => { setValue(details.value) } return ( Framework
                    Frameworks {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework
                    Frameworks {#each collection.items as item (item.value)} {item.label} {/each}
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection, useSelect } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ], }) export const RootProvider = () => { const select = useSelect({ collection: frameworks }) return ( <> selected: {JSON.stringify(select.value)} Framework
                    Frameworks {frameworks.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection, useSelect } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ], }) export const RootProvider = () => { const select = useSelect({ collection: frameworks }) return ( <> selected: {JSON.stringify(select().value)} Framework
                    Frameworks {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Framework
                    Frameworks {#each frameworks.items as item} {item.label} {/each}
                    ``` ### Multiple To enable `multiple` item selection: **Example: multiple** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte', disabled: true }, ], }) export const Multiple = () => { return ( Framework
                    Frameworks {frameworks.items.map((item) => ( {item.label} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte', disabled: true }, ], }) export const Multiple = () => { return ( Framework
                    Frameworks {(item) => ( {item().label} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework
                    Frameworks {#each frameworks.items as item (item.value)} {item.label} {/each}
                    ``` ### 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. **Example: grouping** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react', type: 'JS' }, { label: 'Solid', value: 'solid', type: 'JS' }, { label: 'Vue', value: 'vue', type: 'JS' }, { label: 'Panda', value: 'panda', type: 'CSS' }, { label: 'Tailwind', value: 'tailwind', type: 'CSS' }, ], groupBy: (item) => item.type, }) export const Grouping = () => { return ( Framework
                    {frameworks.group().map(([type, group]) => ( {type} {group.map((item) => ( {item.label} ))} ))}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { For, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react', type: 'JS' }, { label: 'Solid', value: 'solid', type: 'JS' }, { label: 'Vue', value: 'vue', type: 'JS' }, { label: 'Panda', value: 'panda', type: 'CSS' }, { label: 'Tailwind', value: 'tailwind', type: 'CSS' }, ], groupBy: (item) => item.type, }) export const Grouping = () => { return ( Framework
                    {([type, group]) => ( {type} {(item) => ( {item.label} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework
                    {#each frameworks.group() as [type, group]} {type} {#each group as item (item.value)} {item.label} {/each} {/each}
                    ``` ### Field Use `Field` to manage form state, ARIA labels, helper text, and error text. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/select.module.css' export const WithField = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'] }) return ( Label {collection.items.map((item) => ( {item} ))} Additional Info Error Info ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index } from 'solid-js/web' import field from 'styles/field.module.css' import styles from 'styles/select.module.css' export const WithField = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'] }) return ( Label {(item) => ( {item()} )} Additional Info Error Info ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label {#each collection.items as item} {item} {/each} Additional Info Error Info ``` ### Form Usage Here's an example of integrating the `Select` component with a form library. **Example: form-library** #### React ```tsx import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import { Controller, type SubmitHandler, useForm } from 'react-hook-form' import button from 'styles/button.module.css' import styles from 'styles/select.module.css' interface Inputs { framework: string } export const FormLibrary = () => { const { control, handleSubmit } = useForm({ defaultValues: { framework: 'React' }, }) const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) const onSubmit: SubmitHandler = (data) => { window.alert(JSON.stringify(data)) } return (
                    ( field.onChange(e.value[0])} name={field.name} onInteractOutside={() => field.onBlur()} > Framework
                    Frameworks {collection.items.map((item) => ( {item} ))}
                    )} /> ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { createForm, getValue, setValue } from '@modular-forms/solid' import { createMemo } from 'solid-js' import { Index, Portal } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/select.module.css' const frameworks = createListCollection({ items: [ { label: 'React', value: 'react' }, { label: 'Solid', value: 'solid' }, { label: 'Vue', value: 'vue' }, ], }) export const FormLibrary = () => { const [formStore, { Form, Field }] = createForm({ initialValues: { value: 'solid' }, }) const value = createMemo(() => getValue(formStore, 'value')) return ( <>
                    Value is {value()}
                    { window.alert(JSON.stringify(data)) }} > {(field, props) => ( setValue(formStore, field.name, e.value[0])} > Framework
                    Frameworks {(item) => ( {item().label} )}
                    )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Value is {formData.framework}
                    { e.preventDefault() form.handleSubmit() }} > {#snippet children(field)} {@const state = field.state} 0} name={field.name} onValueChange={(details) => { field.handleChange(details.value[0]) }} > Framework
                    Frameworks {#each frameworks.items as item} {item.label} {/each}
                    {/snippet}
                    ``` ### Async Loading Here's an example of how to load the items asynchronously when the select is opened. **Example: async** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/select.module.css' function loadData() { return new Promise((resolve) => { setTimeout(() => resolve(['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Ember']), 500) }) } export const Async = () => { const [items, setItems] = useState(null) const [loading, setLoading] = useState(false) const [error, setError] = useState(null) const collection = createListCollection({ items: items || [], }) const handleOpenChange = (details: Select.OpenChangeDetails) => { if (details.open && items == null) { setLoading(true) setError(null) loadData() .then((data) => setItems(data)) .catch((err) => setError(err)) .finally(() => setLoading(false)) } } return ( Framework {loading ? (
                    Loading...
                    ) : error ? (
                    Error: {error.message}
                    ) : ( collection.items.map((item) => ( {item} )) )}
                    ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, Match, Switch, createMemo, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/select.module.css' function loadData() { return new Promise((resolve) => { setTimeout(() => resolve(['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Ember']), 500) }) } export const Async = () => { const [items, setItems] = createSignal(null) const [loading, setLoading] = createSignal(false) const [error, setError] = createSignal(null) const collection = createMemo(() => createListCollection({ items: items() || [], }), ) const handleOpenChange = (details: Select.OpenChangeDetails) => { if (details.open && items() === null) { setLoading(true) setError(null) loadData() .then((data) => setItems(data)) .catch((err) => setError(err)) .finally(() => setLoading(false)) } } return ( Framework
                    Loading...
                    Error: {error()?.message}
                    {(item) => ( {item()} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework {#if loading}
                    Loading...
                    {:else if error}
                    Error: {error.message}
                    {:else} {#each collection.items as item} {item} {/each} {/if}
                    ``` ### Lazy Mount Use `lazyMount` and `unmountOnExit` to control when content is mounted, improving performance. **Example: lazy-mount** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/select.module.css' export const LazyMount = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Alpine'], }) return ( Framework Clear Frameworks {collection.items.map((item) => ( {item} ))} ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' export const LazyMount = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Alpine'], }) return ( Framework Clear Frameworks {(item) => ( {item()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework Clear Frameworks {#each collection.items as item} {item} {/each} ``` ### Select on Highlight Here's an example of automatically selecting items when they are highlighted (hovered or navigated to with keyboard). **Example: select-on-highlight** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection, useSelect } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/select.module.css' export const SelectOnHighlight = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) const select = useSelect({ collection, onHighlightChange({ highlightedValue }) { if (highlightedValue) { select.selectValue(highlightedValue) } }, }) return ( Framework Clear Frameworks {collection.items.map((item) => ( {item} ))} ) } ``` #### Solid ```tsx import { Select, createListCollection, useSelect } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' export const SelectOnHighlight = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'], }) const select = useSelect({ collection, onHighlightChange({ highlightedValue }) { if (highlightedValue) { select().selectValue(highlightedValue) } }, }) return ( Framework Clear Frameworks {(item) => ( {item()} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework Clear Frameworks {#each frameworks.items as item} {item.label} {/each} ``` ### Max Selection Here's an example of limiting the number of items that can be selected in a multiple select. **Example: max-selected** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/select.module.css' const items = ['React', 'Solid', 'Vue', 'Svelte'] const MAX_SELECTION = 2 const hasReachedMax = (value: string[]) => value.length >= MAX_SELECTION export const MaxSelected = () => { const [value, setValue] = useState([]) const collection = createListCollection({ items: items.map((item) => ({ label: item, value: item, disabled: hasReachedMax(value) && !value.includes(item), })), }) const handleValueChange = (details: Select.ValueChangeDetails) => { if (hasReachedMax(value) && details.value.length > value.length) return setValue(details.value) } return ( Framework Frameworks {collection.items.map((item) => ( {item.label} ))} ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon, XIcon } from 'lucide-solid' import { Index, createMemo, createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/select.module.css' const items = ['React', 'Solid', 'Vue', 'Svelte'] const MAX_SELECTION = 2 const hasReachedMax = (value: string[]) => value.length >= MAX_SELECTION export const MaxSelected = () => { const [value, setValue] = createSignal([]) const collection = createMemo(() => createListCollection({ items: items.map((item) => ({ label: item, value: item, disabled: hasReachedMax(value()) && !value().includes(item), })), }), ) const handleValueChange = (details: Select.ValueChangeDetails) => { if (hasReachedMax(value()) && details.value.length > value().length) return setValue(details.value) } return ( Framework Frameworks {(item) => ( {item().label} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Framework Frameworks {#each collection.items as item (item.value)} {item.label} {/each} ``` ### Select All Use `selectAll()` from the select context to select all items at once. **Example: select-all** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/select.module.css' import button from 'styles/button.module.css' const SelectAllButton = () => { return ( {(api) => ( )} ) } export const SelectAll = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'] }) return ( Framework Clear {collection.items.map((item) => ( {item} ))} ) } ``` #### Solid ```tsx import { Select, createListCollection } from '@ark-ui/solid/select' import { ChevronsUpDownIcon } from 'lucide-solid' import { Index, Portal } from 'solid-js/web' import styles from 'styles/select.module.css' import button from 'styles/button.module.css' const SelectAllButton = () => { return ( {(api) => ( )} ) } export const SelectAll = () => { const collection = createListCollection({ items: ['React', 'Solid', 'Vue', 'Svelte'] }) return ( Framework Clear {(item) => ( {item()} )} ) } ``` #### Vue ```vue ``` ### 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. **Example: overflow** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Select, createListCollection } from '@ark-ui/react/select' import { ChevronsUpDownIcon } from 'lucide-react' import styles from 'styles/select.module.css' export const Overflow = () => { const collection = createListCollection({ items: [ 'Name 1', 'Name 2', 'Name 3', 'Name 4', 'Name 5', 'Name 6', 'Name 7', 'Name 8', 'Name 9', 'Name 10', 'Name 11', 'Name 12', 'Name 13', 'Name 14', ], }) return ( Framework Clear Names {collection.items.map((item) => ( {item} ))} ) } ``` ## Guides ### Type Safety The `Select.RootComponent` type enables you to create typed wrapper components that maintain full type safety for collection items. ```tsx const Select: ArkSelect.RootComponent = (props) => { return {/* ... */} } ``` Use the wrapper with full type inference on `onValueChange` and other callbacks: ```tsx const App = () => { const collection = createListCollection({ initialItems: [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, ], }) return ( ) } ``` ### Nested Usage When using the Select component within a `Popover` or `Dialog`, avoid rendering its content within a `Portal` or `Teleport`. This ensures the Select's content stays within the Popover/Dialog's DOM hierarchy rather than being portalled to the document body, maintaining proper interaction and accessibility behavior. ### Hidden Select The `Select.HiddenSelect` component renders a native HTML `` element exists in the DOM - **Browser auto-fill**: Browsers can properly auto-fill the select based on previously submitted form data - **Progressive enhancement**: Forms remain functional even if JavaScript fails to load ```tsx {/* Other Select components */} ``` The hidden select automatically syncs with the Select component's value, ensuring form data is always up-to-date. ### Empty State You can create an empty state component that displays when there are no items in the collection. Use the `useSelectContext` hook to check the collection size: ```tsx const SelectEmpty = (props: React.ComponentProps<'div'>) => { const select = useSelectContext() if (select.collection.size === 0) { return
                    } return null } ``` Then use it within your Select content: ```tsx No items to display {/* Your items */} ``` ### Available Size The following css variables are exposed to the `Select.Positioner` which you can use to style the `Select.Content` ```css /* width of the select trigger */ --reference-width: ; /* width of the available viewport */ --available-width: ; /* height of the available viewport */ --available-height: ; ``` For example, if you want to make sure the maximum height doesn't exceed the available height, you can use the following: ```css [data-scope='select'][data-part='content'] { max-height: calc(var(--available-height) - 100px); } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected | | `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the select. | | `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user | | `defaultValue` | `string[]` | No | The initial default value of the select when rendered. Use when you don't need to control the value of the select. | | `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item. **Note:** this is only applicable for single selection | | `disabled` | `boolean` | No | Whether the select is disabled | | `form` | `string` | No | The associate form of the underlying select. | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string control: string trigger: string clearTrigger: string label: string hiddenSelect: string positioner: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the select. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `invalid` | `boolean` | No | Whether the select is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `multiple` | `boolean` | No | Whether to allow multiple selection | | `name` | `string` | No | The `name` attribute of the underlying select. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `open` | `boolean` | No | Whether the select menu is open | | `positioning` | `PositioningOptions` | No | The positioning options of the menu. | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the select is read-only | | `required` | `boolean` | No | Whether the select is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-activedescendant]` | The id the active descendant of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested selects | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **HiddenSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-state]` | "checked" | "unchecked" | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSelectReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-placement]` | The placement of the trigger | | `[data-placeholder-shown]` | Present when placeholder is shown | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is selected. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected | | `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the select. | | `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user | | `defaultValue` | `string[]` | No | The initial default value of the select when rendered. Use when you don't need to control the value of the select. | | `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item. **Note:** this is only applicable for single selection | | `disabled` | `boolean` | No | Whether the select is disabled | | `form` | `string` | No | The associate form of the underlying select. | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string control: string trigger: string clearTrigger: string label: string hiddenSelect: string positioner: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the select. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `invalid` | `boolean` | No | Whether the select is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `multiple` | `boolean` | No | Whether to allow multiple selection | | `name` | `string` | No | The `name` attribute of the underlying select. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `open` | `boolean` | No | Whether the select menu is open | | `positioning` | `PositioningOptions` | No | The positioning options of the menu. | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the select is read-only | | `required` | `boolean` | No | Whether the select is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-activedescendant]` | The id the active descendant of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested selects | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **HiddenSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'select'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-state]` | "checked" | "unchecked" | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSelectReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-placement]` | The placement of the trigger | | `[data-placeholder-shown]` | Present when placeholder is shown | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | Text to display when no value is selected. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected | | `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the select. | | `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user | | `defaultValue` | `string[]` | No | The initial default value of the select when rendered. Use when you don't need to control the value of the select. | | `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item. **Note:** this is only applicable for single selection | | `disabled` | `boolean` | No | Whether the select is disabled | | `form` | `string` | No | The associate form of the underlying select. | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string control: string trigger: string clearTrigger: string label: string hiddenSelect: string positioner: string item(id: string | number): string itemGroup(id: string | number): string itemGroupLabel(id: string | number): string }>` | No | The ids of the elements in the select. Useful for composition. | | `invalid` | `boolean` | No | Whether the select is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `modelValue` | `string[]` | No | The model value of the select | | `multiple` | `boolean` | No | Whether to allow multiple selection | | `name` | `string` | No | The `name` attribute of the underlying select. | | `open` | `boolean` | No | Whether the select menu is open | | `positioning` | `PositioningOptions` | No | The positioning options of the menu. | | `readOnly` | `boolean` | No | Whether the select is read-only | | `required` | `boolean` | No | Whether the select is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-activedescendant]` | The id the active descendant of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested selects | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **HiddenSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `item` | `any` | No | The item to render | | `persistFocus` | `boolean` | No | Whether hovering outside should clear the highlighted state | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-state]` | "checked" | "unchecked" | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SelectApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-placement]` | The placement of the trigger | | `[data-placeholder-shown]` | Present when placeholder is shown | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `ListCollection` | Yes | The collection of items | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `closeOnSelect` | `boolean` | No | Whether the select should close after an item is selected | | `composite` | `boolean` | No | Whether the select is a composed with other composite widgets like tabs or combobox | | `defaultHighlightedValue` | `string` | No | The initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the select. | | `defaultOpen` | `boolean` | No | Whether the select's open state is controlled by the user | | `defaultValue` | `string[]` | No | The initial default value of the select when rendered. Use when you don't need to control the value of the select. | | `deselectable` | `boolean` | No | Whether the value can be cleared by clicking the selected item. **Note:** this is only applicable for single selection | | `disabled` | `boolean` | No | Whether the select is disabled | | `form` | `string` | No | The associate form of the underlying select. | | `highlightedValue` | `string` | No | The controlled key of the highlighted item | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string content: string control: string trigger: string clearTrigger: string label: string hiddenSelect: string positioner: string item: (id: string | number) => string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>` | No | The ids of the elements in the select. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `invalid` | `boolean` | No | Whether the select is invalid | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether to loop the keyboard navigation through the options | | `multiple` | `boolean` | No | Whether to allow multiple selection | | `name` | `string` | No | The `name` attribute of the underlying select. | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | The callback fired when the highlighted item changes. | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the popup is opened | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onSelect` | `(details: SelectionDetails) => void` | No | Function called when an item is selected | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the selected item changes. | | `open` | `boolean` | No | Whether the select menu is open | | `positioning` | `PositioningOptions` | No | The positioning options of the menu. | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `readOnly` | `boolean` | No | Whether the select is read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the select is required | | `scrollToIndexFn` | `(details: ScrollToIndexDetails) => void` | No | Function to scroll to a specific index | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled keys of the selected items | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | clear-trigger | | `[data-invalid]` | Present when invalid | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | listbox | | `[data-has-nested]` | listbox | | `[data-placement]` | The placement of the content | | `[data-activedescendant]` | The id the active descendant of the content | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested selects | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSelectReturn]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | control | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | **HiddenSelect Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'select'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSelectItemContext]>` | Yes | | **ItemGroupLabel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `id` | `string` | No | | | `ref` | `Element` | No | | **ItemGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-group | | `[data-disabled]` | Present when disabled | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-indicator | | `[data-state]` | "checked" | "unchecked" | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `item` | `NonNullable` | No | | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-state]` | "checked" | "unchecked" | | `[data-highlighted]` | Present when highlighted | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | item-text | | `[data-state]` | "checked" | "unchecked" | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSelectReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `ref` | `Element` | No | | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-placement]` | The placement of the trigger | | `[data-placeholder-shown]` | Present when placeholder is shown | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `placeholder` | `string` | No | | | `ref` | `Element` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | select | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focused` | `boolean` | Whether the select is focused | | `open` | `boolean` | Whether the select is open | | `empty` | `boolean` | Whether the select value is empty | | `highlightedValue` | `string` | The value of the highlighted item | | `highlightedItem` | `V` | The highlighted item | | `setHighlightValue` | `(value: string) => void` | Function to highlight a value | | `clearHighlightValue` | `VoidFunction` | Function to clear the highlighted value | | `selectedItems` | `V[]` | The selected items | | `hasSelectedItems` | `boolean` | Whether there's a selected option | | `value` | `string[]` | The selected item keys | | `valueAsString` | `string` | The string representation of the selected items | | `selectValue` | `(value: string) => void` | Function to select a value | | `selectAll` | `VoidFunction` | Function to select all values | | `setValue` | `(value: string[]) => void` | Function to set the value of the select | | `clearValue` | `(value?: string) => void` | Function to clear the value of the select. If a value is provided, it will only clear that value, otherwise, it will clear all values. | | `focus` | `VoidFunction` | Function to focus on the select input | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a select item | | `setOpen` | `(open: boolean) => void` | Function to open or close the select | | `collection` | `ListCollection` | Function to toggle the select | | `reposition` | `(options?: Partial) => void` | Function to set the positioning options of the select | | `multiple` | `boolean` | Whether the select allows multiple selections | | `disabled` | `boolean` | Whether the select is disabled | ## Accessibility Complies with the [Listbox WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/listbox/). ### Keyboard Support **`Space`** Description: When focus is on trigger, opens the select and focuses the first selected item.
                    When focus is on the content, selects the highlighted item.
                    **`Enter`** Description: When focus is on trigger, opens the select and focuses the first selected item.
                    When focus is on content, selects the focused item.
                    **`ArrowDown`** Description: When focus is on trigger, opens the select.
                    When focus is on content, moves focus to the next item.
                    **`ArrowUp`** Description: When focus is on trigger, opens the select.
                    When focus is on content, moves focus to the previous item.
                    **`Esc`** Description: Closes the select and moves focus to trigger. **`A-Z + a-z`** Description: When focus is on trigger, selects the item whose label starts with the typed character.
                    When focus is on the listbox, moves focus to the next item with a label that starts with the typed character.
                    --- # Signature Pad (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { SignaturePad } from '@ark-ui/react/signature-pad' import { RotateCcwIcon } from 'lucide-react' import styles from 'styles/signature-pad.module.css' export const Basic = () => ( Sign below ) ``` #### Solid ```tsx import { SignaturePad } from '@ark-ui/solid/signature-pad' import { RotateCcwIcon } from 'lucide-solid' import styles from 'styles/signature-pad.module.css' export const Basic = () => ( Sign below ) ``` #### Vue ```vue ``` #### Svelte ```svelte Sign below ``` ### 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. **Example: image-preview** #### React ```tsx import { SignaturePad } from '@ark-ui/react/signature-pad' import { RotateCcwIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/signature-pad.module.css' export const ImagePreview = () => { const [imageUrl, setImageUrl] = useState('') return (
                    details.getDataUrl('image/png').then((url) => setImageUrl(url))} > Sign below
                    Image Preview {imageUrl && Signature}
                    ) } ``` #### Solid ```tsx import { SignaturePad } from '@ark-ui/solid/signature-pad' import { RotateCcwIcon } from 'lucide-solid' import { Show, createSignal } from 'solid-js' import styles from 'styles/signature-pad.module.css' export const ImagePreview = () => { const [imageUrl, setImageUrl] = createSignal('') return (
                    details.getDataUrl('image/png').then((url) => setImageUrl(url))} > Sign below
                    Image Preview Signature
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    details.getDataUrl('image/png').then((url) => (imageUrl = url))} > Sign below
                    Image Preview {#if imageUrl} Signature {/if}
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { SignaturePad } from '@ark-ui/react/signature-pad' import { RotateCcwIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/signature-pad.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { SignaturePad } from '@ark-ui/solid/signature-pad' import { RotateCcwIcon } from 'lucide-solid' import field from 'styles/field.module.css' import styles from 'styles/signature-pad.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Additional Info Error Info ``` ### 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. **Example: root-provider** #### React ```tsx import { SignaturePad, useSignaturePad } from '@ark-ui/react/signature-pad' import { RotateCcwIcon } from 'lucide-react' import styles from 'styles/signature-pad.module.css' export const RootProvider = () => { const signaturePad = useSignaturePad() return (
                    no of paths: {signaturePad.paths.length} Sign below
                    ) } ``` #### Solid ```tsx import { SignaturePad, useSignaturePad } from '@ark-ui/solid/signature-pad' import { RotateCcwIcon } from 'lucide-solid' import styles from 'styles/signature-pad.module.css' export const RootProvider = () => { const signaturePad = useSignaturePad() return (
                    no of paths: {signaturePad().paths.length} Sign below
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    no of paths: {signaturePad().paths.length} Sign below
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPaths` | `string[]` | No | The default paths of the signature pad. Use when you don't need to control the paths of the signature pad. | | `disabled` | `boolean` | No | Whether the signature pad is disabled. | | `drawing` | `DrawingOptions` | No | The drawing options. | | `ids` | `Partial<{ root: string; control: string; hiddenInput: string; label: string }>` | No | The ids of the signature pad elements. Useful for composition. | | `name` | `string` | No | The name of the signature pad. Useful for form submission. | | `onDraw` | `(details: DrawDetails) => void` | No | Callback when the signature pad is drawing. | | `onDrawEnd` | `(details: DrawEndDetails) => void` | No | Callback when the signature pad is done drawing. | | `paths` | `string[]` | No | The controlled paths of the signature pad. | | `readOnly` | `boolean` | No | Whether the signature pad is read-only. | | `required` | `boolean` | No | Whether the signature pad is required. | | `translations` | `IntlTranslations` | No | The translations of the signature pad. Useful for internationalization. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Guide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Guide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | guide | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSignaturePadReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Segment Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPaths` | `string[]` | No | The default paths of the signature pad. Use when you don't need to control the paths of the signature pad. | | `disabled` | `boolean` | No | Whether the signature pad is disabled. | | `drawing` | `DrawingOptions` | No | The drawing options. | | `ids` | `Partial<{ root: string; control: string; hiddenInput: string; label: string }>` | No | The ids of the signature pad elements. Useful for composition. | | `name` | `string` | No | The name of the signature pad. Useful for form submission. | | `onDraw` | `(details: DrawDetails) => void` | No | Callback when the signature pad is drawing. | | `onDrawEnd` | `(details: DrawEndDetails) => void` | No | Callback when the signature pad is done drawing. | | `paths` | `string[]` | No | The controlled paths of the signature pad. | | `readOnly` | `boolean` | No | Whether the signature pad is read-only. | | `required` | `boolean` | No | Whether the signature pad is required. | | `translations` | `IntlTranslations` | No | The translations of the signature pad. Useful for internationalization. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Guide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Guide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | guide | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSignaturePadReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Segment Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'svg'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPaths` | `string[]` | No | The default paths of the signature pad. | | `disabled` | `boolean` | No | Whether the signature pad is disabled. | | `drawing` | `DrawingOptions` | No | The drawing options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; hiddenInput: string; label: string }>` | No | The ids of the signature pad elements. Useful for composition. | | `name` | `string` | No | The name of the signature pad. Useful for form submission. | | `readOnly` | `boolean` | No | Whether the signature pad is read-only. | | `required` | `boolean` | No | Whether the signature pad is required. | | `translations` | `IntlTranslations` | No | The translations of the signature pad. Useful for internationalization. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Guide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Guide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | guide | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SignaturePadApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Segment Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPaths` | `string[]` | No | The default paths of the signature pad. Use when you don't need to control the paths of the signature pad. | | `disabled` | `boolean` | No | Whether the signature pad is disabled. | | `drawing` | `DrawingOptions` | No | The drawing options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; hiddenInput: string; label: string }>` | No | The ids of the signature pad elements. Useful for composition. | | `name` | `string` | No | The name of the signature pad. Useful for form submission. | | `onDraw` | `(details: DrawDetails) => void` | No | Callback when the signature pad is drawing. | | `onDrawEnd` | `(details: DrawEndDetails) => void` | No | Callback when the signature pad is done drawing. | | `paths` | `string[]` | No | The controlled paths of the signature pad. | | `readOnly` | `boolean` | No | Whether the signature pad is read-only. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the signature pad is required. | | `translations` | `IntlTranslations` | No | The translations of the signature pad. Useful for internationalization. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSignaturePadContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Guide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Guide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | guide | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSignaturePadReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Segment Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'svg'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `empty` | `boolean` | Whether the signature pad is empty. | | `drawing` | `boolean` | Whether the user is currently drawing. | | `currentPath` | `string` | The current path being drawn. | | `paths` | `string[]` | The paths of the signature pad. | | `getDataUrl` | `(type: DataUrlType, quality?: number) => Promise` | Returns the data URL of the signature pad. | | `clear` | `VoidFunction` | Clears the signature pad. | --- # Signature Pad (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { SignaturePad } from '@ark-ui/react/signature-pad' import { RotateCcwIcon } from 'lucide-react' import styles from 'styles/signature-pad.module.css' export const Basic = () => ( Sign below ) ``` #### Solid ```tsx import { SignaturePad } from '@ark-ui/solid/signature-pad' import { RotateCcwIcon } from 'lucide-solid' import styles from 'styles/signature-pad.module.css' export const Basic = () => ( Sign below ) ``` #### Vue ```vue ``` #### Svelte ```svelte Sign below ``` ### 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. **Example: image-preview** #### React ```tsx import { SignaturePad } from '@ark-ui/react/signature-pad' import { RotateCcwIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/signature-pad.module.css' export const ImagePreview = () => { const [imageUrl, setImageUrl] = useState('') return (
                    details.getDataUrl('image/png').then((url) => setImageUrl(url))} > Sign below
                    Image Preview {imageUrl && Signature}
                    ) } ``` #### Solid ```tsx import { SignaturePad } from '@ark-ui/solid/signature-pad' import { RotateCcwIcon } from 'lucide-solid' import { Show, createSignal } from 'solid-js' import styles from 'styles/signature-pad.module.css' export const ImagePreview = () => { const [imageUrl, setImageUrl] = createSignal('') return (
                    details.getDataUrl('image/png').then((url) => setImageUrl(url))} > Sign below
                    Image Preview Signature
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    details.getDataUrl('image/png').then((url) => (imageUrl = url))} > Sign below
                    Image Preview {#if imageUrl} Signature {/if}
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { SignaturePad } from '@ark-ui/react/signature-pad' import { RotateCcwIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/signature-pad.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { SignaturePad } from '@ark-ui/solid/signature-pad' import { RotateCcwIcon } from 'lucide-solid' import field from 'styles/field.module.css' import styles from 'styles/signature-pad.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Additional Info Error Info ``` ### 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. **Example: root-provider** #### React ```tsx import { SignaturePad, useSignaturePad } from '@ark-ui/react/signature-pad' import { RotateCcwIcon } from 'lucide-react' import styles from 'styles/signature-pad.module.css' export const RootProvider = () => { const signaturePad = useSignaturePad() return (
                    no of paths: {signaturePad.paths.length} Sign below
                    ) } ``` #### Solid ```tsx import { SignaturePad, useSignaturePad } from '@ark-ui/solid/signature-pad' import { RotateCcwIcon } from 'lucide-solid' import styles from 'styles/signature-pad.module.css' export const RootProvider = () => { const signaturePad = useSignaturePad() return (
                    no of paths: {signaturePad().paths.length} Sign below
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    no of paths: {signaturePad().paths.length} Sign below
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPaths` | `string[]` | No | The default paths of the signature pad. Use when you don't need to control the paths of the signature pad. | | `disabled` | `boolean` | No | Whether the signature pad is disabled. | | `drawing` | `DrawingOptions` | No | The drawing options. | | `ids` | `Partial<{ root: string; control: string; hiddenInput: string; label: string }>` | No | The ids of the signature pad elements. Useful for composition. | | `name` | `string` | No | The name of the signature pad. Useful for form submission. | | `onDraw` | `(details: DrawDetails) => void` | No | Callback when the signature pad is drawing. | | `onDrawEnd` | `(details: DrawEndDetails) => void` | No | Callback when the signature pad is done drawing. | | `paths` | `string[]` | No | The controlled paths of the signature pad. | | `readOnly` | `boolean` | No | Whether the signature pad is read-only. | | `required` | `boolean` | No | Whether the signature pad is required. | | `translations` | `IntlTranslations` | No | The translations of the signature pad. Useful for internationalization. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Guide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Guide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | guide | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSignaturePadReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Segment Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPaths` | `string[]` | No | The default paths of the signature pad. Use when you don't need to control the paths of the signature pad. | | `disabled` | `boolean` | No | Whether the signature pad is disabled. | | `drawing` | `DrawingOptions` | No | The drawing options. | | `ids` | `Partial<{ root: string; control: string; hiddenInput: string; label: string }>` | No | The ids of the signature pad elements. Useful for composition. | | `name` | `string` | No | The name of the signature pad. Useful for form submission. | | `onDraw` | `(details: DrawDetails) => void` | No | Callback when the signature pad is drawing. | | `onDrawEnd` | `(details: DrawEndDetails) => void` | No | Callback when the signature pad is done drawing. | | `paths` | `string[]` | No | The controlled paths of the signature pad. | | `readOnly` | `boolean` | No | Whether the signature pad is read-only. | | `required` | `boolean` | No | Whether the signature pad is required. | | `translations` | `IntlTranslations` | No | The translations of the signature pad. Useful for internationalization. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Guide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Guide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | guide | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSignaturePadReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Segment Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'svg'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPaths` | `string[]` | No | The default paths of the signature pad. | | `disabled` | `boolean` | No | Whether the signature pad is disabled. | | `drawing` | `DrawingOptions` | No | The drawing options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; hiddenInput: string; label: string }>` | No | The ids of the signature pad elements. Useful for composition. | | `name` | `string` | No | The name of the signature pad. Useful for form submission. | | `readOnly` | `boolean` | No | Whether the signature pad is read-only. | | `required` | `boolean` | No | Whether the signature pad is required. | | `translations` | `IntlTranslations` | No | The translations of the signature pad. Useful for internationalization. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Guide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Guide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | guide | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SignaturePadApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Segment Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPaths` | `string[]` | No | The default paths of the signature pad. Use when you don't need to control the paths of the signature pad. | | `disabled` | `boolean` | No | Whether the signature pad is disabled. | | `drawing` | `DrawingOptions` | No | The drawing options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; hiddenInput: string; label: string }>` | No | The ids of the signature pad elements. Useful for composition. | | `name` | `string` | No | The name of the signature pad. Useful for form submission. | | `onDraw` | `(details: DrawDetails) => void` | No | Callback when the signature pad is drawing. | | `onDrawEnd` | `(details: DrawEndDetails) => void` | No | Callback when the signature pad is done drawing. | | `paths` | `string[]` | No | The controlled paths of the signature pad. | | `readOnly` | `boolean` | No | Whether the signature pad is read-only. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the signature pad is required. | | `translations` | `IntlTranslations` | No | The translations of the signature pad. Useful for internationalization. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSignaturePadContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Guide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Guide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | guide | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSignaturePadReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Segment Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'svg'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `empty` | `boolean` | Whether the signature pad is empty. | | `drawing` | `boolean` | Whether the user is currently drawing. | | `currentPath` | `string` | The current path being drawn. | | `paths` | `string[]` | The paths of the signature pad. | | `getDataUrl` | `(type: DataUrlType, quality?: number) => Promise` | Returns the data URL of the signature pad. | | `clear` | `VoidFunction` | Clears the signature pad. | --- # Signature Pad (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { SignaturePad } from '@ark-ui/react/signature-pad' import { RotateCcwIcon } from 'lucide-react' import styles from 'styles/signature-pad.module.css' export const Basic = () => ( Sign below ) ``` #### Solid ```tsx import { SignaturePad } from '@ark-ui/solid/signature-pad' import { RotateCcwIcon } from 'lucide-solid' import styles from 'styles/signature-pad.module.css' export const Basic = () => ( Sign below ) ``` #### Vue ```vue ``` #### Svelte ```svelte Sign below ``` ### 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. **Example: image-preview** #### React ```tsx import { SignaturePad } from '@ark-ui/react/signature-pad' import { RotateCcwIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/signature-pad.module.css' export const ImagePreview = () => { const [imageUrl, setImageUrl] = useState('') return (
                    details.getDataUrl('image/png').then((url) => setImageUrl(url))} > Sign below
                    Image Preview {imageUrl && Signature}
                    ) } ``` #### Solid ```tsx import { SignaturePad } from '@ark-ui/solid/signature-pad' import { RotateCcwIcon } from 'lucide-solid' import { Show, createSignal } from 'solid-js' import styles from 'styles/signature-pad.module.css' export const ImagePreview = () => { const [imageUrl, setImageUrl] = createSignal('') return (
                    details.getDataUrl('image/png').then((url) => setImageUrl(url))} > Sign below
                    Image Preview Signature
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    details.getDataUrl('image/png').then((url) => (imageUrl = url))} > Sign below
                    Image Preview {#if imageUrl} Signature {/if}
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { SignaturePad } from '@ark-ui/react/signature-pad' import { RotateCcwIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/signature-pad.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { SignaturePad } from '@ark-ui/solid/signature-pad' import { RotateCcwIcon } from 'lucide-solid' import field from 'styles/field.module.css' import styles from 'styles/signature-pad.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Additional Info Error Info ``` ### 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. **Example: root-provider** #### React ```tsx import { SignaturePad, useSignaturePad } from '@ark-ui/react/signature-pad' import { RotateCcwIcon } from 'lucide-react' import styles from 'styles/signature-pad.module.css' export const RootProvider = () => { const signaturePad = useSignaturePad() return (
                    no of paths: {signaturePad.paths.length} Sign below
                    ) } ``` #### Solid ```tsx import { SignaturePad, useSignaturePad } from '@ark-ui/solid/signature-pad' import { RotateCcwIcon } from 'lucide-solid' import styles from 'styles/signature-pad.module.css' export const RootProvider = () => { const signaturePad = useSignaturePad() return (
                    no of paths: {signaturePad().paths.length} Sign below
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    no of paths: {signaturePad().paths.length} Sign below
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPaths` | `string[]` | No | The default paths of the signature pad. Use when you don't need to control the paths of the signature pad. | | `disabled` | `boolean` | No | Whether the signature pad is disabled. | | `drawing` | `DrawingOptions` | No | The drawing options. | | `ids` | `Partial<{ root: string; control: string; hiddenInput: string; label: string }>` | No | The ids of the signature pad elements. Useful for composition. | | `name` | `string` | No | The name of the signature pad. Useful for form submission. | | `onDraw` | `(details: DrawDetails) => void` | No | Callback when the signature pad is drawing. | | `onDrawEnd` | `(details: DrawEndDetails) => void` | No | Callback when the signature pad is done drawing. | | `paths` | `string[]` | No | The controlled paths of the signature pad. | | `readOnly` | `boolean` | No | Whether the signature pad is read-only. | | `required` | `boolean` | No | Whether the signature pad is required. | | `translations` | `IntlTranslations` | No | The translations of the signature pad. Useful for internationalization. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Guide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Guide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | guide | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSignaturePadReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Segment Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPaths` | `string[]` | No | The default paths of the signature pad. Use when you don't need to control the paths of the signature pad. | | `disabled` | `boolean` | No | Whether the signature pad is disabled. | | `drawing` | `DrawingOptions` | No | The drawing options. | | `ids` | `Partial<{ root: string; control: string; hiddenInput: string; label: string }>` | No | The ids of the signature pad elements. Useful for composition. | | `name` | `string` | No | The name of the signature pad. Useful for form submission. | | `onDraw` | `(details: DrawDetails) => void` | No | Callback when the signature pad is drawing. | | `onDrawEnd` | `(details: DrawEndDetails) => void` | No | Callback when the signature pad is done drawing. | | `paths` | `string[]` | No | The controlled paths of the signature pad. | | `readOnly` | `boolean` | No | Whether the signature pad is read-only. | | `required` | `boolean` | No | Whether the signature pad is required. | | `translations` | `IntlTranslations` | No | The translations of the signature pad. Useful for internationalization. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Guide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Guide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | guide | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSignaturePadReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Segment Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'svg'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPaths` | `string[]` | No | The default paths of the signature pad. | | `disabled` | `boolean` | No | Whether the signature pad is disabled. | | `drawing` | `DrawingOptions` | No | The drawing options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; hiddenInput: string; label: string }>` | No | The ids of the signature pad elements. Useful for composition. | | `name` | `string` | No | The name of the signature pad. Useful for form submission. | | `readOnly` | `boolean` | No | Whether the signature pad is read-only. | | `required` | `boolean` | No | Whether the signature pad is required. | | `translations` | `IntlTranslations` | No | The translations of the signature pad. Useful for internationalization. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Guide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Guide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | guide | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SignaturePadApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Segment Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPaths` | `string[]` | No | The default paths of the signature pad. Use when you don't need to control the paths of the signature pad. | | `disabled` | `boolean` | No | Whether the signature pad is disabled. | | `drawing` | `DrawingOptions` | No | The drawing options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; hiddenInput: string; label: string }>` | No | The ids of the signature pad elements. Useful for composition. | | `name` | `string` | No | The name of the signature pad. Useful for form submission. | | `onDraw` | `(details: DrawDetails) => void` | No | Callback when the signature pad is drawing. | | `onDrawEnd` | `(details: DrawEndDetails) => void` | No | Callback when the signature pad is done drawing. | | `paths` | `string[]` | No | The controlled paths of the signature pad. | | `readOnly` | `boolean` | No | Whether the signature pad is read-only. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the signature pad is required. | | `translations` | `IntlTranslations` | No | The translations of the signature pad. Useful for internationalization. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSignaturePadContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Guide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Guide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | guide | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSignaturePadReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Segment Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'svg'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `empty` | `boolean` | Whether the signature pad is empty. | | `drawing` | `boolean` | Whether the user is currently drawing. | | `currentPath` | `string` | The current path being drawn. | | `paths` | `string[]` | The paths of the signature pad. | | `getDataUrl` | `(type: DataUrlType, quality?: number) => Promise` | Returns the data URL of the signature pad. | | `clear` | `VoidFunction` | Clears the signature pad. | --- # Signature Pad (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { SignaturePad } from '@ark-ui/react/signature-pad' import { RotateCcwIcon } from 'lucide-react' import styles from 'styles/signature-pad.module.css' export const Basic = () => ( Sign below ) ``` #### Solid ```tsx import { SignaturePad } from '@ark-ui/solid/signature-pad' import { RotateCcwIcon } from 'lucide-solid' import styles from 'styles/signature-pad.module.css' export const Basic = () => ( Sign below ) ``` #### Vue ```vue ``` #### Svelte ```svelte Sign below ``` ### 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. **Example: image-preview** #### React ```tsx import { SignaturePad } from '@ark-ui/react/signature-pad' import { RotateCcwIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/signature-pad.module.css' export const ImagePreview = () => { const [imageUrl, setImageUrl] = useState('') return (
                    details.getDataUrl('image/png').then((url) => setImageUrl(url))} > Sign below
                    Image Preview {imageUrl && Signature}
                    ) } ``` #### Solid ```tsx import { SignaturePad } from '@ark-ui/solid/signature-pad' import { RotateCcwIcon } from 'lucide-solid' import { Show, createSignal } from 'solid-js' import styles from 'styles/signature-pad.module.css' export const ImagePreview = () => { const [imageUrl, setImageUrl] = createSignal('') return (
                    details.getDataUrl('image/png').then((url) => setImageUrl(url))} > Sign below
                    Image Preview Signature
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    details.getDataUrl('image/png').then((url) => (imageUrl = url))} > Sign below
                    Image Preview {#if imageUrl} Signature {/if}
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { SignaturePad } from '@ark-ui/react/signature-pad' import { RotateCcwIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/signature-pad.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { SignaturePad } from '@ark-ui/solid/signature-pad' import { RotateCcwIcon } from 'lucide-solid' import field from 'styles/field.module.css' import styles from 'styles/signature-pad.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Additional Info Error Info ``` ### 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. **Example: root-provider** #### React ```tsx import { SignaturePad, useSignaturePad } from '@ark-ui/react/signature-pad' import { RotateCcwIcon } from 'lucide-react' import styles from 'styles/signature-pad.module.css' export const RootProvider = () => { const signaturePad = useSignaturePad() return (
                    no of paths: {signaturePad.paths.length} Sign below
                    ) } ``` #### Solid ```tsx import { SignaturePad, useSignaturePad } from '@ark-ui/solid/signature-pad' import { RotateCcwIcon } from 'lucide-solid' import styles from 'styles/signature-pad.module.css' export const RootProvider = () => { const signaturePad = useSignaturePad() return (
                    no of paths: {signaturePad().paths.length} Sign below
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    no of paths: {signaturePad().paths.length} Sign below
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPaths` | `string[]` | No | The default paths of the signature pad. Use when you don't need to control the paths of the signature pad. | | `disabled` | `boolean` | No | Whether the signature pad is disabled. | | `drawing` | `DrawingOptions` | No | The drawing options. | | `ids` | `Partial<{ root: string; control: string; hiddenInput: string; label: string }>` | No | The ids of the signature pad elements. Useful for composition. | | `name` | `string` | No | The name of the signature pad. Useful for form submission. | | `onDraw` | `(details: DrawDetails) => void` | No | Callback when the signature pad is drawing. | | `onDrawEnd` | `(details: DrawEndDetails) => void` | No | Callback when the signature pad is done drawing. | | `paths` | `string[]` | No | The controlled paths of the signature pad. | | `readOnly` | `boolean` | No | Whether the signature pad is read-only. | | `required` | `boolean` | No | Whether the signature pad is required. | | `translations` | `IntlTranslations` | No | The translations of the signature pad. Useful for internationalization. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Guide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Guide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | guide | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSignaturePadReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Segment Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPaths` | `string[]` | No | The default paths of the signature pad. Use when you don't need to control the paths of the signature pad. | | `disabled` | `boolean` | No | Whether the signature pad is disabled. | | `drawing` | `DrawingOptions` | No | The drawing options. | | `ids` | `Partial<{ root: string; control: string; hiddenInput: string; label: string }>` | No | The ids of the signature pad elements. Useful for composition. | | `name` | `string` | No | The name of the signature pad. Useful for form submission. | | `onDraw` | `(details: DrawDetails) => void` | No | Callback when the signature pad is drawing. | | `onDrawEnd` | `(details: DrawEndDetails) => void` | No | Callback when the signature pad is done drawing. | | `paths` | `string[]` | No | The controlled paths of the signature pad. | | `readOnly` | `boolean` | No | Whether the signature pad is read-only. | | `required` | `boolean` | No | Whether the signature pad is required. | | `translations` | `IntlTranslations` | No | The translations of the signature pad. Useful for internationalization. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Guide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Guide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | guide | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSignaturePadReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Segment Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'svg'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPaths` | `string[]` | No | The default paths of the signature pad. | | `disabled` | `boolean` | No | Whether the signature pad is disabled. | | `drawing` | `DrawingOptions` | No | The drawing options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; hiddenInput: string; label: string }>` | No | The ids of the signature pad elements. Useful for composition. | | `name` | `string` | No | The name of the signature pad. Useful for form submission. | | `readOnly` | `boolean` | No | Whether the signature pad is read-only. | | `required` | `boolean` | No | Whether the signature pad is required. | | `translations` | `IntlTranslations` | No | The translations of the signature pad. Useful for internationalization. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Guide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Guide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | guide | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SignaturePadApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Segment Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPaths` | `string[]` | No | The default paths of the signature pad. Use when you don't need to control the paths of the signature pad. | | `disabled` | `boolean` | No | Whether the signature pad is disabled. | | `drawing` | `DrawingOptions` | No | The drawing options. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; control: string; hiddenInput: string; label: string }>` | No | The ids of the signature pad elements. Useful for composition. | | `name` | `string` | No | The name of the signature pad. Useful for form submission. | | `onDraw` | `(details: DrawDetails) => void` | No | Callback when the signature pad is drawing. | | `onDrawEnd` | `(details: DrawEndDetails) => void` | No | Callback when the signature pad is done drawing. | | `paths` | `string[]` | No | The controlled paths of the signature pad. | | `readOnly` | `boolean` | No | Whether the signature pad is read-only. | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the signature pad is required. | | `translations` | `IntlTranslations` | No | The translations of the signature pad. Useful for internationalization. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSignaturePadContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | **Guide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Guide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | guide | | `[data-disabled]` | Present when disabled | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | signature-pad | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSignaturePadReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Segment Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'svg'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `empty` | `boolean` | Whether the signature pad is empty. | | `drawing` | `boolean` | Whether the user is currently drawing. | | `currentPath` | `string` | The current path being drawn. | | `paths` | `string[]` | The paths of the signature pad. | | `getDataUrl` | `(type: DataUrlType, quality?: number) => Promise` | Returns the data URL of the signature pad. | | `clear` | `VoidFunction` | Clears the signature pad. | --- # Slider (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const Basic = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const Basic = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### Range You can add multiple thumbs to the slider by adding multiple `Slider.Thumb` **Example: range** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const Range = () => { return ( Label ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const Range = () => { return ( Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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. **Example: with-marks** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const WithMarks = () => { return (
                    Label
                    {[0, 25, 50, 75, 100].map((value) => ( {value} ))}
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import { For } from 'solid-js' import styles from 'styles/slider.module.css' export const WithMarks = () => { return (
                    Label
                    {(value) => ( {value} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    {#each marks as value} {value} {/each}
                    ``` ### 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: **Example: min-max** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const MinMax = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const MinMax = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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`: **Example: step** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const Step = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const Step = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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. **Example: on-event** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const OnEvent = () => { return ( console.log('onValueChange', details.value)} onValueChangeEnd={(details) => console.log('onValueChangeEnd', details.value)} className={styles.Root} >
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const OnEvent = () => { return ( console.log('onValueChange', details.value)} onValueChangeEnd={(details) => console.log('onValueChangeEnd', details.value)} class={styles.Root} >
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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 **Example: vertical** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const Vertical = () => { return ( Label ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const Vertical = () => { return ( Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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`. **Example: center-origin** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const CenterOrigin = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const CenterOrigin = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Slider, useSlider } from '@ark-ui/react/slider' import button from 'styles/button.module.css' import styles from 'styles/slider.module.css' export const RootProvider = () => { const slider = useSlider() return ( <> Label ) } ``` #### Solid ```tsx import { Slider, useSlider } from '@ark-ui/solid/slider' import button from 'styles/button.module.css' import styles from 'styles/slider.module.css' export const RootProvider = () => { const slider = useSlider() return ( <> Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### Dragging Indicator Use the `Slider.DraggingIndicator` component inside `Slider.Thumb` to show a visual indicator while the thumb is being dragged. **Example: dragging-indicator** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const DraggingIndicator = () => { return ( Label ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const DraggingIndicator = () => { return ( Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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. **Example: thumb-overlap** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const ThumbOverlap = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const ThumbOverlap = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string[]` | No | The aria-label of each slider thumb. Useful for providing an accessible name to the slider | | `aria-labelledby` | `string[]` | No | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number[]` | No | The initial value of the slider when rendered. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `getAriaValueText` | `(details: ValueTextDetails) => string` | No | Function that returns a human readable value for the slider thumb | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: (index: number) => string hiddenInput: (index: number) => string control: string track: string range: string label: string valueText: string marker: (index: number) => string }>` | No | The ids of the elements in the slider. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid | | `max` | `number` | No | The maximum value of the slider | | `min` | `number` | No | The minimum value of the slider | | `minStepsBetweenThumbs` | `number` | No | The minimum permitted steps between multiple thumbs. `minStepsBetweenThumbs` * `step` should reflect the gap between the thumbs. - `step: 1` and `minStepsBetweenThumbs: 10` => gap is `10` - `step: 10` and `minStepsBetweenThumbs: 2` => gap is `20` | | `name` | `string` | No | The name associated with each slider thumb (when used in a form) | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the slider's focused index changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value of the slider changes | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Function invoked when the slider value change is done | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the slider | | `origin` | `'center' | 'start' | 'end'` | No | The origin of the slider range. The track is filled from the origin to the thumb for single values. - "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) - "end": Useful when the value represents an offset from the end | | `readOnly` | `boolean` | No | Whether the slider is read-only | | `step` | `number` | No | The step value of the slider | | `thumbAlignment` | `'center' | 'contain'` | No | The alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. | | `thumbSize` | `{ width: number; height: number }` | No | The slider thumbs dimensions | | `value` | `number[]` | No | The controlled value of the slider | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the slider | | `[data-dragging]` | Present when in the dragging state | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slider-thumb-width` | The thumb width of the slider | | `--slider-thumb-height` | The thumb height of the slider | | `--slider-thumb-transform` | The thumb transform of the slider | | `--slider-range-start` | The range start of the slider | | `--slider-range-end` | The range end of the slider | | `--translate-x` | The horizontal translation value | | `--translate-y` | The vertical translation value | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | control | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the control | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **DraggingIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DraggingIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | dragging-indicator | | `[data-orientation]` | The orientation of the draggingindicator | | `[data-state]` | "open" | "closed" | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the label | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **MarkerGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker-group | | `[data-orientation]` | The orientation of the markergroup | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker | | `[data-orientation]` | The orientation of the marker | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-state]` | | **Range Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Range Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | range | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the range | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSliderReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `name` | `string` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | thumb | | `[data-index]` | The index of the item | | `[data-name]` | | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the thumb | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | **Track Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Track Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | track | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-orientation]` | The orientation of the track | | `[data-focus]` | Present when focused | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the valuetext | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string[]` | No | The aria-label of each slider thumb. Useful for providing an accessible name to the slider | | `aria-labelledby` | `string[]` | No | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number[]` | No | The initial value of the slider when rendered. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `getAriaValueText` | `(details: ValueTextDetails) => string` | No | Function that returns a human readable value for the slider thumb | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: (index: number) => string hiddenInput: (index: number) => string control: string track: string range: string label: string valueText: string marker: (index: number) => string }>` | No | The ids of the elements in the slider. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid | | `max` | `number` | No | The maximum value of the slider | | `min` | `number` | No | The minimum value of the slider | | `minStepsBetweenThumbs` | `number` | No | The minimum permitted steps between multiple thumbs. `minStepsBetweenThumbs` * `step` should reflect the gap between the thumbs. - `step: 1` and `minStepsBetweenThumbs: 10` => gap is `10` - `step: 10` and `minStepsBetweenThumbs: 2` => gap is `20` | | `name` | `string` | No | The name associated with each slider thumb (when used in a form) | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the slider's focused index changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value of the slider changes | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Function invoked when the slider value change is done | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the slider | | `origin` | `'start' | 'center' | 'end'` | No | The origin of the slider range. The track is filled from the origin to the thumb for single values. - "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) - "end": Useful when the value represents an offset from the end | | `readOnly` | `boolean` | No | Whether the slider is read-only | | `step` | `number` | No | The step value of the slider | | `thumbAlignment` | `'center' | 'contain'` | No | The alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. | | `thumbSize` | `{ width: number; height: number }` | No | The slider thumbs dimensions | | `value` | `number[]` | No | The controlled value of the slider | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the slider | | `[data-dragging]` | Present when in the dragging state | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slider-thumb-width` | The thumb width of the slider | | `--slider-thumb-height` | The thumb height of the slider | | `--slider-thumb-transform` | The thumb transform of the slider | | `--slider-range-start` | The range start of the slider | | `--slider-range-end` | The range end of the slider | | `--translate-x` | The horizontal translation value | | `--translate-y` | The vertical translation value | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | control | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the control | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **DraggingIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DraggingIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | dragging-indicator | | `[data-orientation]` | The orientation of the draggingindicator | | `[data-state]` | "open" | "closed" | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the label | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **MarkerGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker-group | | `[data-orientation]` | The orientation of the markergroup | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | | | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker | | `[data-orientation]` | The orientation of the marker | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-state]` | | **Range Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Range Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | range | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the range | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSliderReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `name` | `string` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | thumb | | `[data-index]` | The index of the item | | `[data-name]` | | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the thumb | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | **Track Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Track Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | track | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-orientation]` | The orientation of the track | | `[data-focus]` | Present when focused | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the valuetext | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string[]` | No | The aria-label of each slider thumb. Useful for providing an accessible name to the slider | | `aria-labelledby` | `string[]` | No | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number[]` | No | The initial value of the slider when rendered. Use when you don't need to control the value of the slider. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the slider is disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `getAriaValueText` | `(details: ValueTextDetails) => string` | No | Function that returns a human readable value for the slider thumb | | `getRootNode` | `() => ShadowRoot | Node | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb(index: number): string hiddenInput(index: number): string control: string track: string range: string label: string valueText: string marker(index: number): string }>` | No | The ids of the elements in the slider. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid | | `max` | `number` | No | The maximum value of the slider | | `min` | `number` | No | The minimum value of the slider | | `minStepsBetweenThumbs` | `number` | No | The minimum permitted steps between multiple thumbs. | | `modelValue` | `number[]` | No | The v-model value of the slider | | `name` | `string` | No | The name associated with each slider thumb (when used in a form) | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the slider | | `origin` | `'start' | 'center'` | No | The origin of the slider range - "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) | | `readOnly` | `boolean` | No | Whether the slider is read-only | | `step` | `number` | No | The step value of the slider | | `thumbAlignment` | `'center' | 'contain'` | No | The alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. | | `thumbSize` | `{ width: number; height: number }` | No | The slider thumbs dimensions | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the slider | | `[data-dragging]` | Present when in the dragging state | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slider-thumb-width` | The thumb width of the slider | | `--slider-thumb-height` | The thumb height of the slider | | `--slider-thumb-transform` | The thumb transform of the slider | | `--slider-range-start` | The range start of the slider | | `--slider-range-end` | The range end of the slider | | `--translate-x` | The horizontal translation value | | `--translate-y` | The vertical translation value | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | control | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the control | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **DraggingIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DraggingIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | dragging-indicator | | `[data-orientation]` | The orientation of the draggingindicator | | `[data-state]` | "open" | "closed" | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the label | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **MarkerGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker-group | | `[data-orientation]` | The orientation of the markergroup | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker | | `[data-orientation]` | The orientation of the marker | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-state]` | | **Range Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Range Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | range | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the range | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SliderApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `name` | `string` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | thumb | | `[data-index]` | The index of the item | | `[data-name]` | | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the thumb | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | **Track Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Track Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | track | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-orientation]` | The orientation of the track | | `[data-focus]` | Present when focused | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the valuetext | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string[]` | No | The aria-label of each slider thumb. Useful for providing an accessible name to the slider | | `aria-labelledby` | `string[]` | No | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number[]` | No | The initial value of the slider when rendered. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `getAriaValueText` | `(details: ValueTextDetails) => string` | No | Function that returns a human readable value for the slider thumb | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: (index: number) => string hiddenInput: (index: number) => string control: string track: string range: string label: string valueText: string marker: (index: number) => string }>` | No | The ids of the elements in the slider. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid | | `max` | `number` | No | The maximum value of the slider | | `min` | `number` | No | The minimum value of the slider | | `minStepsBetweenThumbs` | `number` | No | The minimum permitted steps between multiple thumbs. `minStepsBetweenThumbs` * `step` should reflect the gap between the thumbs. - `step: 1` and `minStepsBetweenThumbs: 10` => gap is `10` - `step: 10` and `minStepsBetweenThumbs: 2` => gap is `20` | | `name` | `string` | No | The name associated with each slider thumb (when used in a form) | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the slider's focused index changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value of the slider changes | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Function invoked when the slider value change is done | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the slider | | `origin` | `'start' | 'center' | 'end'` | No | The origin of the slider range. The track is filled from the origin to the thumb for single values. - "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) - "end": Useful when the value represents an offset from the end | | `readOnly` | `boolean` | No | Whether the slider is read-only | | `ref` | `Element` | No | | | `step` | `number` | No | The step value of the slider | | `thumbAlignment` | `'center' | 'contain'` | No | The alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. | | `thumbSize` | `{ width: number; height: number }` | No | The slider thumbs dimensions | | `value` | `number[]` | No | The controlled value of the slider | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the slider | | `[data-dragging]` | Present when in the dragging state | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slider-thumb-width` | The thumb width of the slider | | `--slider-thumb-height` | The thumb height of the slider | | `--slider-thumb-transform` | The thumb transform of the slider | | `--slider-range-start` | The range start of the slider | | `--slider-range-end` | The range end of the slider | | `--translate-x` | The horizontal translation value | | `--translate-y` | The vertical translation value | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSliderContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | control | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the control | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **DraggingIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **DraggingIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | dragging-indicator | | `[data-orientation]` | The orientation of the draggingindicator | | `[data-state]` | "open" | "closed" | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the label | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **MarkerGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker-group | | `[data-orientation]` | The orientation of the markergroup | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker | | `[data-orientation]` | The orientation of the marker | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-state]` | | **Range Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Range Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | range | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the range | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSliderReturn` | Yes | | | `ref` | `Element` | No | | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `name` | `string` | No | | | `ref` | `Element` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | thumb | | `[data-index]` | The index of the item | | `[data-name]` | | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the thumb | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | **Track Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Track Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | track | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-orientation]` | The orientation of the track | | `[data-focus]` | Present when focused | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the valuetext | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `number[]` | The value of the slider. | | `dragging` | `boolean` | Whether the slider is being dragged. | | `focused` | `boolean` | Whether the slider is focused. | | `setValue` | `(value: number[]) => void` | Function to set the value of the slider. | | `getThumbValue` | `(index: number) => number` | Returns the value of the thumb at the given index. | | `setThumbValue` | `(index: number, value: number) => void` | Sets the value of the thumb at the given index. | | `getValuePercent` | `(value: number) => number` | Returns the percent of the thumb at the given index. | | `getPercentValue` | `(percent: number) => number` | Returns the value of the thumb at the given percent. | | `getThumbPercent` | `(index: number) => number` | Returns the percent of the thumb at the given index. | | `setThumbPercent` | `(index: number, percent: number) => void` | Sets the percent of the thumb at the given index. | | `getThumbMin` | `(index: number) => number` | Returns the min value of the thumb at the given index. | | `getThumbMax` | `(index: number) => number` | Returns the max value of the thumb at the given index. | | `increment` | `(index: number) => void` | Function to increment the value of the slider at the given index. | | `decrement` | `(index: number) => void` | Function to decrement the value of the slider at the given index. | | `focus` | `VoidFunction` | Function to focus the slider. This focuses the first thumb. | ## Accessibility Complies with the [Slider WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/slider/). ### Keyboard Support **`ArrowRight`** Description: Increments the slider based on defined step **`ArrowLeft`** Description: Decrements the slider based on defined step **`ArrowUp`** Description: Increases the value by the step amount. **`ArrowDown`** Description: Decreases the value by the step amount. **`PageUp`** Description: Increases the value by a larger step **`PageDown`** Description: Decreases the value by a larger step **`Shift + ArrowUp`** Description: Increases the value by a larger step **`Shift + ArrowDown`** Description: Decreases the value by a larger step **`Home`** Description: Sets the value to its minimum. **`End`** Description: Sets the value to its maximum. --- # Slider (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const Basic = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const Basic = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### Range You can add multiple thumbs to the slider by adding multiple `Slider.Thumb` **Example: range** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const Range = () => { return ( Label ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const Range = () => { return ( Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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. **Example: with-marks** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const WithMarks = () => { return (
                    Label
                    {[0, 25, 50, 75, 100].map((value) => ( {value} ))}
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import { For } from 'solid-js' import styles from 'styles/slider.module.css' export const WithMarks = () => { return (
                    Label
                    {(value) => ( {value} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    {#each marks as value} {value} {/each}
                    ``` ### 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: **Example: min-max** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const MinMax = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const MinMax = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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`: **Example: step** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const Step = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const Step = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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. **Example: on-event** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const OnEvent = () => { return ( console.log('onValueChange', details.value)} onValueChangeEnd={(details) => console.log('onValueChangeEnd', details.value)} className={styles.Root} >
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const OnEvent = () => { return ( console.log('onValueChange', details.value)} onValueChangeEnd={(details) => console.log('onValueChangeEnd', details.value)} class={styles.Root} >
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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 **Example: vertical** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const Vertical = () => { return ( Label ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const Vertical = () => { return ( Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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`. **Example: center-origin** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const CenterOrigin = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const CenterOrigin = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Slider, useSlider } from '@ark-ui/react/slider' import button from 'styles/button.module.css' import styles from 'styles/slider.module.css' export const RootProvider = () => { const slider = useSlider() return ( <> Label ) } ``` #### Solid ```tsx import { Slider, useSlider } from '@ark-ui/solid/slider' import button from 'styles/button.module.css' import styles from 'styles/slider.module.css' export const RootProvider = () => { const slider = useSlider() return ( <> Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### Dragging Indicator Use the `Slider.DraggingIndicator` component inside `Slider.Thumb` to show a visual indicator while the thumb is being dragged. **Example: dragging-indicator** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const DraggingIndicator = () => { return ( Label ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const DraggingIndicator = () => { return ( Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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. **Example: thumb-overlap** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const ThumbOverlap = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const ThumbOverlap = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string[]` | No | The aria-label of each slider thumb. Useful for providing an accessible name to the slider | | `aria-labelledby` | `string[]` | No | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number[]` | No | The initial value of the slider when rendered. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `getAriaValueText` | `(details: ValueTextDetails) => string` | No | Function that returns a human readable value for the slider thumb | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: (index: number) => string hiddenInput: (index: number) => string control: string track: string range: string label: string valueText: string marker: (index: number) => string }>` | No | The ids of the elements in the slider. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid | | `max` | `number` | No | The maximum value of the slider | | `min` | `number` | No | The minimum value of the slider | | `minStepsBetweenThumbs` | `number` | No | The minimum permitted steps between multiple thumbs. `minStepsBetweenThumbs` * `step` should reflect the gap between the thumbs. - `step: 1` and `minStepsBetweenThumbs: 10` => gap is `10` - `step: 10` and `minStepsBetweenThumbs: 2` => gap is `20` | | `name` | `string` | No | The name associated with each slider thumb (when used in a form) | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the slider's focused index changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value of the slider changes | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Function invoked when the slider value change is done | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the slider | | `origin` | `'center' | 'start' | 'end'` | No | The origin of the slider range. The track is filled from the origin to the thumb for single values. - "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) - "end": Useful when the value represents an offset from the end | | `readOnly` | `boolean` | No | Whether the slider is read-only | | `step` | `number` | No | The step value of the slider | | `thumbAlignment` | `'center' | 'contain'` | No | The alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. | | `thumbSize` | `{ width: number; height: number }` | No | The slider thumbs dimensions | | `value` | `number[]` | No | The controlled value of the slider | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the slider | | `[data-dragging]` | Present when in the dragging state | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slider-thumb-width` | The thumb width of the slider | | `--slider-thumb-height` | The thumb height of the slider | | `--slider-thumb-transform` | The thumb transform of the slider | | `--slider-range-start` | The range start of the slider | | `--slider-range-end` | The range end of the slider | | `--translate-x` | The horizontal translation value | | `--translate-y` | The vertical translation value | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | control | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the control | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **DraggingIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DraggingIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | dragging-indicator | | `[data-orientation]` | The orientation of the draggingindicator | | `[data-state]` | "open" | "closed" | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the label | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **MarkerGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker-group | | `[data-orientation]` | The orientation of the markergroup | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker | | `[data-orientation]` | The orientation of the marker | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-state]` | | **Range Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Range Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | range | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the range | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSliderReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `name` | `string` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | thumb | | `[data-index]` | The index of the item | | `[data-name]` | | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the thumb | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | **Track Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Track Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | track | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-orientation]` | The orientation of the track | | `[data-focus]` | Present when focused | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the valuetext | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string[]` | No | The aria-label of each slider thumb. Useful for providing an accessible name to the slider | | `aria-labelledby` | `string[]` | No | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number[]` | No | The initial value of the slider when rendered. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `getAriaValueText` | `(details: ValueTextDetails) => string` | No | Function that returns a human readable value for the slider thumb | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: (index: number) => string hiddenInput: (index: number) => string control: string track: string range: string label: string valueText: string marker: (index: number) => string }>` | No | The ids of the elements in the slider. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid | | `max` | `number` | No | The maximum value of the slider | | `min` | `number` | No | The minimum value of the slider | | `minStepsBetweenThumbs` | `number` | No | The minimum permitted steps between multiple thumbs. `minStepsBetweenThumbs` * `step` should reflect the gap between the thumbs. - `step: 1` and `minStepsBetweenThumbs: 10` => gap is `10` - `step: 10` and `minStepsBetweenThumbs: 2` => gap is `20` | | `name` | `string` | No | The name associated with each slider thumb (when used in a form) | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the slider's focused index changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value of the slider changes | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Function invoked when the slider value change is done | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the slider | | `origin` | `'start' | 'center' | 'end'` | No | The origin of the slider range. The track is filled from the origin to the thumb for single values. - "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) - "end": Useful when the value represents an offset from the end | | `readOnly` | `boolean` | No | Whether the slider is read-only | | `step` | `number` | No | The step value of the slider | | `thumbAlignment` | `'center' | 'contain'` | No | The alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. | | `thumbSize` | `{ width: number; height: number }` | No | The slider thumbs dimensions | | `value` | `number[]` | No | The controlled value of the slider | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the slider | | `[data-dragging]` | Present when in the dragging state | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slider-thumb-width` | The thumb width of the slider | | `--slider-thumb-height` | The thumb height of the slider | | `--slider-thumb-transform` | The thumb transform of the slider | | `--slider-range-start` | The range start of the slider | | `--slider-range-end` | The range end of the slider | | `--translate-x` | The horizontal translation value | | `--translate-y` | The vertical translation value | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | control | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the control | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **DraggingIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DraggingIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | dragging-indicator | | `[data-orientation]` | The orientation of the draggingindicator | | `[data-state]` | "open" | "closed" | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the label | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **MarkerGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker-group | | `[data-orientation]` | The orientation of the markergroup | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | | | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker | | `[data-orientation]` | The orientation of the marker | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-state]` | | **Range Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Range Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | range | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the range | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSliderReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `name` | `string` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | thumb | | `[data-index]` | The index of the item | | `[data-name]` | | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the thumb | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | **Track Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Track Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | track | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-orientation]` | The orientation of the track | | `[data-focus]` | Present when focused | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the valuetext | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string[]` | No | The aria-label of each slider thumb. Useful for providing an accessible name to the slider | | `aria-labelledby` | `string[]` | No | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number[]` | No | The initial value of the slider when rendered. Use when you don't need to control the value of the slider. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the slider is disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `getAriaValueText` | `(details: ValueTextDetails) => string` | No | Function that returns a human readable value for the slider thumb | | `getRootNode` | `() => ShadowRoot | Node | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb(index: number): string hiddenInput(index: number): string control: string track: string range: string label: string valueText: string marker(index: number): string }>` | No | The ids of the elements in the slider. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid | | `max` | `number` | No | The maximum value of the slider | | `min` | `number` | No | The minimum value of the slider | | `minStepsBetweenThumbs` | `number` | No | The minimum permitted steps between multiple thumbs. | | `modelValue` | `number[]` | No | The v-model value of the slider | | `name` | `string` | No | The name associated with each slider thumb (when used in a form) | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the slider | | `origin` | `'start' | 'center'` | No | The origin of the slider range - "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) | | `readOnly` | `boolean` | No | Whether the slider is read-only | | `step` | `number` | No | The step value of the slider | | `thumbAlignment` | `'center' | 'contain'` | No | The alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. | | `thumbSize` | `{ width: number; height: number }` | No | The slider thumbs dimensions | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the slider | | `[data-dragging]` | Present when in the dragging state | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slider-thumb-width` | The thumb width of the slider | | `--slider-thumb-height` | The thumb height of the slider | | `--slider-thumb-transform` | The thumb transform of the slider | | `--slider-range-start` | The range start of the slider | | `--slider-range-end` | The range end of the slider | | `--translate-x` | The horizontal translation value | | `--translate-y` | The vertical translation value | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | control | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the control | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **DraggingIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DraggingIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | dragging-indicator | | `[data-orientation]` | The orientation of the draggingindicator | | `[data-state]` | "open" | "closed" | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the label | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **MarkerGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker-group | | `[data-orientation]` | The orientation of the markergroup | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker | | `[data-orientation]` | The orientation of the marker | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-state]` | | **Range Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Range Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | range | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the range | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SliderApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `name` | `string` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | thumb | | `[data-index]` | The index of the item | | `[data-name]` | | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the thumb | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | **Track Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Track Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | track | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-orientation]` | The orientation of the track | | `[data-focus]` | Present when focused | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the valuetext | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string[]` | No | The aria-label of each slider thumb. Useful for providing an accessible name to the slider | | `aria-labelledby` | `string[]` | No | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number[]` | No | The initial value of the slider when rendered. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `getAriaValueText` | `(details: ValueTextDetails) => string` | No | Function that returns a human readable value for the slider thumb | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: (index: number) => string hiddenInput: (index: number) => string control: string track: string range: string label: string valueText: string marker: (index: number) => string }>` | No | The ids of the elements in the slider. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid | | `max` | `number` | No | The maximum value of the slider | | `min` | `number` | No | The minimum value of the slider | | `minStepsBetweenThumbs` | `number` | No | The minimum permitted steps between multiple thumbs. `minStepsBetweenThumbs` * `step` should reflect the gap between the thumbs. - `step: 1` and `minStepsBetweenThumbs: 10` => gap is `10` - `step: 10` and `minStepsBetweenThumbs: 2` => gap is `20` | | `name` | `string` | No | The name associated with each slider thumb (when used in a form) | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the slider's focused index changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value of the slider changes | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Function invoked when the slider value change is done | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the slider | | `origin` | `'start' | 'center' | 'end'` | No | The origin of the slider range. The track is filled from the origin to the thumb for single values. - "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) - "end": Useful when the value represents an offset from the end | | `readOnly` | `boolean` | No | Whether the slider is read-only | | `ref` | `Element` | No | | | `step` | `number` | No | The step value of the slider | | `thumbAlignment` | `'center' | 'contain'` | No | The alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. | | `thumbSize` | `{ width: number; height: number }` | No | The slider thumbs dimensions | | `value` | `number[]` | No | The controlled value of the slider | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the slider | | `[data-dragging]` | Present when in the dragging state | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slider-thumb-width` | The thumb width of the slider | | `--slider-thumb-height` | The thumb height of the slider | | `--slider-thumb-transform` | The thumb transform of the slider | | `--slider-range-start` | The range start of the slider | | `--slider-range-end` | The range end of the slider | | `--translate-x` | The horizontal translation value | | `--translate-y` | The vertical translation value | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSliderContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | control | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the control | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **DraggingIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **DraggingIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | dragging-indicator | | `[data-orientation]` | The orientation of the draggingindicator | | `[data-state]` | "open" | "closed" | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the label | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **MarkerGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker-group | | `[data-orientation]` | The orientation of the markergroup | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker | | `[data-orientation]` | The orientation of the marker | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-state]` | | **Range Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Range Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | range | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the range | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSliderReturn` | Yes | | | `ref` | `Element` | No | | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `name` | `string` | No | | | `ref` | `Element` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | thumb | | `[data-index]` | The index of the item | | `[data-name]` | | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the thumb | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | **Track Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Track Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | track | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-orientation]` | The orientation of the track | | `[data-focus]` | Present when focused | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the valuetext | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `number[]` | The value of the slider. | | `dragging` | `boolean` | Whether the slider is being dragged. | | `focused` | `boolean` | Whether the slider is focused. | | `setValue` | `(value: number[]) => void` | Function to set the value of the slider. | | `getThumbValue` | `(index: number) => number` | Returns the value of the thumb at the given index. | | `setThumbValue` | `(index: number, value: number) => void` | Sets the value of the thumb at the given index. | | `getValuePercent` | `(value: number) => number` | Returns the percent of the thumb at the given index. | | `getPercentValue` | `(percent: number) => number` | Returns the value of the thumb at the given percent. | | `getThumbPercent` | `(index: number) => number` | Returns the percent of the thumb at the given index. | | `setThumbPercent` | `(index: number, percent: number) => void` | Sets the percent of the thumb at the given index. | | `getThumbMin` | `(index: number) => number` | Returns the min value of the thumb at the given index. | | `getThumbMax` | `(index: number) => number` | Returns the max value of the thumb at the given index. | | `increment` | `(index: number) => void` | Function to increment the value of the slider at the given index. | | `decrement` | `(index: number) => void` | Function to decrement the value of the slider at the given index. | | `focus` | `VoidFunction` | Function to focus the slider. This focuses the first thumb. | ## Accessibility Complies with the [Slider WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/slider/). ### Keyboard Support **`ArrowRight`** Description: Increments the slider based on defined step **`ArrowLeft`** Description: Decrements the slider based on defined step **`ArrowUp`** Description: Increases the value by the step amount. **`ArrowDown`** Description: Decreases the value by the step amount. **`PageUp`** Description: Increases the value by a larger step **`PageDown`** Description: Decreases the value by a larger step **`Shift + ArrowUp`** Description: Increases the value by a larger step **`Shift + ArrowDown`** Description: Decreases the value by a larger step **`Home`** Description: Sets the value to its minimum. **`End`** Description: Sets the value to its maximum. --- # Slider (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const Basic = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const Basic = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### Range You can add multiple thumbs to the slider by adding multiple `Slider.Thumb` **Example: range** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const Range = () => { return ( Label ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const Range = () => { return ( Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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. **Example: with-marks** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const WithMarks = () => { return (
                    Label
                    {[0, 25, 50, 75, 100].map((value) => ( {value} ))}
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import { For } from 'solid-js' import styles from 'styles/slider.module.css' export const WithMarks = () => { return (
                    Label
                    {(value) => ( {value} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    {#each marks as value} {value} {/each}
                    ``` ### 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: **Example: min-max** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const MinMax = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const MinMax = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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`: **Example: step** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const Step = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const Step = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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. **Example: on-event** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const OnEvent = () => { return ( console.log('onValueChange', details.value)} onValueChangeEnd={(details) => console.log('onValueChangeEnd', details.value)} className={styles.Root} >
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const OnEvent = () => { return ( console.log('onValueChange', details.value)} onValueChangeEnd={(details) => console.log('onValueChangeEnd', details.value)} class={styles.Root} >
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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 **Example: vertical** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const Vertical = () => { return ( Label ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const Vertical = () => { return ( Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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`. **Example: center-origin** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const CenterOrigin = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const CenterOrigin = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Slider, useSlider } from '@ark-ui/react/slider' import button from 'styles/button.module.css' import styles from 'styles/slider.module.css' export const RootProvider = () => { const slider = useSlider() return ( <> Label ) } ``` #### Solid ```tsx import { Slider, useSlider } from '@ark-ui/solid/slider' import button from 'styles/button.module.css' import styles from 'styles/slider.module.css' export const RootProvider = () => { const slider = useSlider() return ( <> Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### Dragging Indicator Use the `Slider.DraggingIndicator` component inside `Slider.Thumb` to show a visual indicator while the thumb is being dragged. **Example: dragging-indicator** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const DraggingIndicator = () => { return ( Label ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const DraggingIndicator = () => { return ( Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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. **Example: thumb-overlap** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const ThumbOverlap = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const ThumbOverlap = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string[]` | No | The aria-label of each slider thumb. Useful for providing an accessible name to the slider | | `aria-labelledby` | `string[]` | No | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number[]` | No | The initial value of the slider when rendered. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `getAriaValueText` | `(details: ValueTextDetails) => string` | No | Function that returns a human readable value for the slider thumb | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: (index: number) => string hiddenInput: (index: number) => string control: string track: string range: string label: string valueText: string marker: (index: number) => string }>` | No | The ids of the elements in the slider. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid | | `max` | `number` | No | The maximum value of the slider | | `min` | `number` | No | The minimum value of the slider | | `minStepsBetweenThumbs` | `number` | No | The minimum permitted steps between multiple thumbs. `minStepsBetweenThumbs` * `step` should reflect the gap between the thumbs. - `step: 1` and `minStepsBetweenThumbs: 10` => gap is `10` - `step: 10` and `minStepsBetweenThumbs: 2` => gap is `20` | | `name` | `string` | No | The name associated with each slider thumb (when used in a form) | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the slider's focused index changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value of the slider changes | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Function invoked when the slider value change is done | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the slider | | `origin` | `'center' | 'start' | 'end'` | No | The origin of the slider range. The track is filled from the origin to the thumb for single values. - "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) - "end": Useful when the value represents an offset from the end | | `readOnly` | `boolean` | No | Whether the slider is read-only | | `step` | `number` | No | The step value of the slider | | `thumbAlignment` | `'center' | 'contain'` | No | The alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. | | `thumbSize` | `{ width: number; height: number }` | No | The slider thumbs dimensions | | `value` | `number[]` | No | The controlled value of the slider | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the slider | | `[data-dragging]` | Present when in the dragging state | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slider-thumb-width` | The thumb width of the slider | | `--slider-thumb-height` | The thumb height of the slider | | `--slider-thumb-transform` | The thumb transform of the slider | | `--slider-range-start` | The range start of the slider | | `--slider-range-end` | The range end of the slider | | `--translate-x` | The horizontal translation value | | `--translate-y` | The vertical translation value | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | control | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the control | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **DraggingIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DraggingIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | dragging-indicator | | `[data-orientation]` | The orientation of the draggingindicator | | `[data-state]` | "open" | "closed" | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the label | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **MarkerGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker-group | | `[data-orientation]` | The orientation of the markergroup | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker | | `[data-orientation]` | The orientation of the marker | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-state]` | | **Range Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Range Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | range | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the range | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSliderReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `name` | `string` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | thumb | | `[data-index]` | The index of the item | | `[data-name]` | | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the thumb | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | **Track Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Track Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | track | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-orientation]` | The orientation of the track | | `[data-focus]` | Present when focused | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the valuetext | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string[]` | No | The aria-label of each slider thumb. Useful for providing an accessible name to the slider | | `aria-labelledby` | `string[]` | No | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number[]` | No | The initial value of the slider when rendered. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `getAriaValueText` | `(details: ValueTextDetails) => string` | No | Function that returns a human readable value for the slider thumb | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: (index: number) => string hiddenInput: (index: number) => string control: string track: string range: string label: string valueText: string marker: (index: number) => string }>` | No | The ids of the elements in the slider. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid | | `max` | `number` | No | The maximum value of the slider | | `min` | `number` | No | The minimum value of the slider | | `minStepsBetweenThumbs` | `number` | No | The minimum permitted steps between multiple thumbs. `minStepsBetweenThumbs` * `step` should reflect the gap between the thumbs. - `step: 1` and `minStepsBetweenThumbs: 10` => gap is `10` - `step: 10` and `minStepsBetweenThumbs: 2` => gap is `20` | | `name` | `string` | No | The name associated with each slider thumb (when used in a form) | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the slider's focused index changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value of the slider changes | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Function invoked when the slider value change is done | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the slider | | `origin` | `'start' | 'center' | 'end'` | No | The origin of the slider range. The track is filled from the origin to the thumb for single values. - "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) - "end": Useful when the value represents an offset from the end | | `readOnly` | `boolean` | No | Whether the slider is read-only | | `step` | `number` | No | The step value of the slider | | `thumbAlignment` | `'center' | 'contain'` | No | The alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. | | `thumbSize` | `{ width: number; height: number }` | No | The slider thumbs dimensions | | `value` | `number[]` | No | The controlled value of the slider | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the slider | | `[data-dragging]` | Present when in the dragging state | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slider-thumb-width` | The thumb width of the slider | | `--slider-thumb-height` | The thumb height of the slider | | `--slider-thumb-transform` | The thumb transform of the slider | | `--slider-range-start` | The range start of the slider | | `--slider-range-end` | The range end of the slider | | `--translate-x` | The horizontal translation value | | `--translate-y` | The vertical translation value | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | control | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the control | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **DraggingIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DraggingIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | dragging-indicator | | `[data-orientation]` | The orientation of the draggingindicator | | `[data-state]` | "open" | "closed" | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the label | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **MarkerGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker-group | | `[data-orientation]` | The orientation of the markergroup | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | | | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker | | `[data-orientation]` | The orientation of the marker | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-state]` | | **Range Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Range Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | range | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the range | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSliderReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `name` | `string` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | thumb | | `[data-index]` | The index of the item | | `[data-name]` | | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the thumb | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | **Track Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Track Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | track | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-orientation]` | The orientation of the track | | `[data-focus]` | Present when focused | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the valuetext | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string[]` | No | The aria-label of each slider thumb. Useful for providing an accessible name to the slider | | `aria-labelledby` | `string[]` | No | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number[]` | No | The initial value of the slider when rendered. Use when you don't need to control the value of the slider. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the slider is disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `getAriaValueText` | `(details: ValueTextDetails) => string` | No | Function that returns a human readable value for the slider thumb | | `getRootNode` | `() => ShadowRoot | Node | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb(index: number): string hiddenInput(index: number): string control: string track: string range: string label: string valueText: string marker(index: number): string }>` | No | The ids of the elements in the slider. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid | | `max` | `number` | No | The maximum value of the slider | | `min` | `number` | No | The minimum value of the slider | | `minStepsBetweenThumbs` | `number` | No | The minimum permitted steps between multiple thumbs. | | `modelValue` | `number[]` | No | The v-model value of the slider | | `name` | `string` | No | The name associated with each slider thumb (when used in a form) | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the slider | | `origin` | `'start' | 'center'` | No | The origin of the slider range - "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) | | `readOnly` | `boolean` | No | Whether the slider is read-only | | `step` | `number` | No | The step value of the slider | | `thumbAlignment` | `'center' | 'contain'` | No | The alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. | | `thumbSize` | `{ width: number; height: number }` | No | The slider thumbs dimensions | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the slider | | `[data-dragging]` | Present when in the dragging state | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slider-thumb-width` | The thumb width of the slider | | `--slider-thumb-height` | The thumb height of the slider | | `--slider-thumb-transform` | The thumb transform of the slider | | `--slider-range-start` | The range start of the slider | | `--slider-range-end` | The range end of the slider | | `--translate-x` | The horizontal translation value | | `--translate-y` | The vertical translation value | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | control | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the control | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **DraggingIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DraggingIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | dragging-indicator | | `[data-orientation]` | The orientation of the draggingindicator | | `[data-state]` | "open" | "closed" | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the label | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **MarkerGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker-group | | `[data-orientation]` | The orientation of the markergroup | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker | | `[data-orientation]` | The orientation of the marker | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-state]` | | **Range Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Range Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | range | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the range | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SliderApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `name` | `string` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | thumb | | `[data-index]` | The index of the item | | `[data-name]` | | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the thumb | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | **Track Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Track Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | track | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-orientation]` | The orientation of the track | | `[data-focus]` | Present when focused | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the valuetext | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string[]` | No | The aria-label of each slider thumb. Useful for providing an accessible name to the slider | | `aria-labelledby` | `string[]` | No | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number[]` | No | The initial value of the slider when rendered. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `getAriaValueText` | `(details: ValueTextDetails) => string` | No | Function that returns a human readable value for the slider thumb | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: (index: number) => string hiddenInput: (index: number) => string control: string track: string range: string label: string valueText: string marker: (index: number) => string }>` | No | The ids of the elements in the slider. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid | | `max` | `number` | No | The maximum value of the slider | | `min` | `number` | No | The minimum value of the slider | | `minStepsBetweenThumbs` | `number` | No | The minimum permitted steps between multiple thumbs. `minStepsBetweenThumbs` * `step` should reflect the gap between the thumbs. - `step: 1` and `minStepsBetweenThumbs: 10` => gap is `10` - `step: 10` and `minStepsBetweenThumbs: 2` => gap is `20` | | `name` | `string` | No | The name associated with each slider thumb (when used in a form) | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the slider's focused index changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value of the slider changes | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Function invoked when the slider value change is done | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the slider | | `origin` | `'start' | 'center' | 'end'` | No | The origin of the slider range. The track is filled from the origin to the thumb for single values. - "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) - "end": Useful when the value represents an offset from the end | | `readOnly` | `boolean` | No | Whether the slider is read-only | | `ref` | `Element` | No | | | `step` | `number` | No | The step value of the slider | | `thumbAlignment` | `'center' | 'contain'` | No | The alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. | | `thumbSize` | `{ width: number; height: number }` | No | The slider thumbs dimensions | | `value` | `number[]` | No | The controlled value of the slider | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the slider | | `[data-dragging]` | Present when in the dragging state | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slider-thumb-width` | The thumb width of the slider | | `--slider-thumb-height` | The thumb height of the slider | | `--slider-thumb-transform` | The thumb transform of the slider | | `--slider-range-start` | The range start of the slider | | `--slider-range-end` | The range end of the slider | | `--translate-x` | The horizontal translation value | | `--translate-y` | The vertical translation value | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSliderContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | control | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the control | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **DraggingIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **DraggingIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | dragging-indicator | | `[data-orientation]` | The orientation of the draggingindicator | | `[data-state]` | "open" | "closed" | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the label | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **MarkerGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker-group | | `[data-orientation]` | The orientation of the markergroup | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker | | `[data-orientation]` | The orientation of the marker | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-state]` | | **Range Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Range Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | range | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the range | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSliderReturn` | Yes | | | `ref` | `Element` | No | | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `name` | `string` | No | | | `ref` | `Element` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | thumb | | `[data-index]` | The index of the item | | `[data-name]` | | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the thumb | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | **Track Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Track Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | track | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-orientation]` | The orientation of the track | | `[data-focus]` | Present when focused | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the valuetext | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `number[]` | The value of the slider. | | `dragging` | `boolean` | Whether the slider is being dragged. | | `focused` | `boolean` | Whether the slider is focused. | | `setValue` | `(value: number[]) => void` | Function to set the value of the slider. | | `getThumbValue` | `(index: number) => number` | Returns the value of the thumb at the given index. | | `setThumbValue` | `(index: number, value: number) => void` | Sets the value of the thumb at the given index. | | `getValuePercent` | `(value: number) => number` | Returns the percent of the thumb at the given index. | | `getPercentValue` | `(percent: number) => number` | Returns the value of the thumb at the given percent. | | `getThumbPercent` | `(index: number) => number` | Returns the percent of the thumb at the given index. | | `setThumbPercent` | `(index: number, percent: number) => void` | Sets the percent of the thumb at the given index. | | `getThumbMin` | `(index: number) => number` | Returns the min value of the thumb at the given index. | | `getThumbMax` | `(index: number) => number` | Returns the max value of the thumb at the given index. | | `increment` | `(index: number) => void` | Function to increment the value of the slider at the given index. | | `decrement` | `(index: number) => void` | Function to decrement the value of the slider at the given index. | | `focus` | `VoidFunction` | Function to focus the slider. This focuses the first thumb. | ## Accessibility Complies with the [Slider WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/slider/). ### Keyboard Support **`ArrowRight`** Description: Increments the slider based on defined step **`ArrowLeft`** Description: Decrements the slider based on defined step **`ArrowUp`** Description: Increases the value by the step amount. **`ArrowDown`** Description: Decreases the value by the step amount. **`PageUp`** Description: Increases the value by a larger step **`PageDown`** Description: Decreases the value by a larger step **`Shift + ArrowUp`** Description: Increases the value by a larger step **`Shift + ArrowDown`** Description: Decreases the value by a larger step **`Home`** Description: Sets the value to its minimum. **`End`** Description: Sets the value to its maximum. --- # Slider (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const Basic = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const Basic = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### Range You can add multiple thumbs to the slider by adding multiple `Slider.Thumb` **Example: range** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const Range = () => { return ( Label ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const Range = () => { return ( Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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. **Example: with-marks** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const WithMarks = () => { return (
                    Label
                    {[0, 25, 50, 75, 100].map((value) => ( {value} ))}
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import { For } from 'solid-js' import styles from 'styles/slider.module.css' export const WithMarks = () => { return (
                    Label
                    {(value) => ( {value} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    {#each marks as value} {value} {/each}
                    ``` ### 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: **Example: min-max** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const MinMax = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const MinMax = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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`: **Example: step** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const Step = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const Step = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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. **Example: on-event** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const OnEvent = () => { return ( console.log('onValueChange', details.value)} onValueChangeEnd={(details) => console.log('onValueChangeEnd', details.value)} className={styles.Root} >
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const OnEvent = () => { return ( console.log('onValueChange', details.value)} onValueChangeEnd={(details) => console.log('onValueChangeEnd', details.value)} class={styles.Root} >
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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 **Example: vertical** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const Vertical = () => { return ( Label ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const Vertical = () => { return ( Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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`. **Example: center-origin** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const CenterOrigin = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const CenterOrigin = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Slider, useSlider } from '@ark-ui/react/slider' import button from 'styles/button.module.css' import styles from 'styles/slider.module.css' export const RootProvider = () => { const slider = useSlider() return ( <> Label ) } ``` #### Solid ```tsx import { Slider, useSlider } from '@ark-ui/solid/slider' import button from 'styles/button.module.css' import styles from 'styles/slider.module.css' export const RootProvider = () => { const slider = useSlider() return ( <> Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### Dragging Indicator Use the `Slider.DraggingIndicator` component inside `Slider.Thumb` to show a visual indicator while the thumb is being dragged. **Example: dragging-indicator** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const DraggingIndicator = () => { return ( Label ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const DraggingIndicator = () => { return ( Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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. **Example: thumb-overlap** #### React ```tsx import { Slider } from '@ark-ui/react/slider' import styles from 'styles/slider.module.css' export const ThumbOverlap = () => { return (
                    Label
                    ) } ``` #### Solid ```tsx import { Slider } from '@ark-ui/solid/slider' import styles from 'styles/slider.module.css' export const ThumbOverlap = () => { return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string[]` | No | The aria-label of each slider thumb. Useful for providing an accessible name to the slider | | `aria-labelledby` | `string[]` | No | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number[]` | No | The initial value of the slider when rendered. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `getAriaValueText` | `(details: ValueTextDetails) => string` | No | Function that returns a human readable value for the slider thumb | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: (index: number) => string hiddenInput: (index: number) => string control: string track: string range: string label: string valueText: string marker: (index: number) => string }>` | No | The ids of the elements in the slider. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid | | `max` | `number` | No | The maximum value of the slider | | `min` | `number` | No | The minimum value of the slider | | `minStepsBetweenThumbs` | `number` | No | The minimum permitted steps between multiple thumbs. `minStepsBetweenThumbs` * `step` should reflect the gap between the thumbs. - `step: 1` and `minStepsBetweenThumbs: 10` => gap is `10` - `step: 10` and `minStepsBetweenThumbs: 2` => gap is `20` | | `name` | `string` | No | The name associated with each slider thumb (when used in a form) | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the slider's focused index changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value of the slider changes | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Function invoked when the slider value change is done | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the slider | | `origin` | `'center' | 'start' | 'end'` | No | The origin of the slider range. The track is filled from the origin to the thumb for single values. - "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) - "end": Useful when the value represents an offset from the end | | `readOnly` | `boolean` | No | Whether the slider is read-only | | `step` | `number` | No | The step value of the slider | | `thumbAlignment` | `'center' | 'contain'` | No | The alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. | | `thumbSize` | `{ width: number; height: number }` | No | The slider thumbs dimensions | | `value` | `number[]` | No | The controlled value of the slider | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the slider | | `[data-dragging]` | Present when in the dragging state | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slider-thumb-width` | The thumb width of the slider | | `--slider-thumb-height` | The thumb height of the slider | | `--slider-thumb-transform` | The thumb transform of the slider | | `--slider-range-start` | The range start of the slider | | `--slider-range-end` | The range end of the slider | | `--translate-x` | The horizontal translation value | | `--translate-y` | The vertical translation value | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | control | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the control | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **DraggingIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DraggingIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | dragging-indicator | | `[data-orientation]` | The orientation of the draggingindicator | | `[data-state]` | "open" | "closed" | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the label | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **MarkerGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker-group | | `[data-orientation]` | The orientation of the markergroup | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker | | `[data-orientation]` | The orientation of the marker | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-state]` | | **Range Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Range Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | range | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the range | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSliderReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `name` | `string` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | thumb | | `[data-index]` | The index of the item | | `[data-name]` | | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the thumb | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | **Track Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Track Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | track | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-orientation]` | The orientation of the track | | `[data-focus]` | Present when focused | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the valuetext | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string[]` | No | The aria-label of each slider thumb. Useful for providing an accessible name to the slider | | `aria-labelledby` | `string[]` | No | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number[]` | No | The initial value of the slider when rendered. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `getAriaValueText` | `(details: ValueTextDetails) => string` | No | Function that returns a human readable value for the slider thumb | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: (index: number) => string hiddenInput: (index: number) => string control: string track: string range: string label: string valueText: string marker: (index: number) => string }>` | No | The ids of the elements in the slider. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid | | `max` | `number` | No | The maximum value of the slider | | `min` | `number` | No | The minimum value of the slider | | `minStepsBetweenThumbs` | `number` | No | The minimum permitted steps between multiple thumbs. `minStepsBetweenThumbs` * `step` should reflect the gap between the thumbs. - `step: 1` and `minStepsBetweenThumbs: 10` => gap is `10` - `step: 10` and `minStepsBetweenThumbs: 2` => gap is `20` | | `name` | `string` | No | The name associated with each slider thumb (when used in a form) | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the slider's focused index changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value of the slider changes | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Function invoked when the slider value change is done | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the slider | | `origin` | `'start' | 'center' | 'end'` | No | The origin of the slider range. The track is filled from the origin to the thumb for single values. - "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) - "end": Useful when the value represents an offset from the end | | `readOnly` | `boolean` | No | Whether the slider is read-only | | `step` | `number` | No | The step value of the slider | | `thumbAlignment` | `'center' | 'contain'` | No | The alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. | | `thumbSize` | `{ width: number; height: number }` | No | The slider thumbs dimensions | | `value` | `number[]` | No | The controlled value of the slider | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the slider | | `[data-dragging]` | Present when in the dragging state | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slider-thumb-width` | The thumb width of the slider | | `--slider-thumb-height` | The thumb height of the slider | | `--slider-thumb-transform` | The thumb transform of the slider | | `--slider-range-start` | The range start of the slider | | `--slider-range-end` | The range end of the slider | | `--translate-x` | The horizontal translation value | | `--translate-y` | The vertical translation value | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | control | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the control | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **DraggingIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DraggingIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | dragging-indicator | | `[data-orientation]` | The orientation of the draggingindicator | | `[data-state]` | "open" | "closed" | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the label | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **MarkerGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker-group | | `[data-orientation]` | The orientation of the markergroup | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | | | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker | | `[data-orientation]` | The orientation of the marker | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-state]` | | **Range Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Range Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | range | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the range | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSliderReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `name` | `string` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | thumb | | `[data-index]` | The index of the item | | `[data-name]` | | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the thumb | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | **Track Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Track Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | track | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-orientation]` | The orientation of the track | | `[data-focus]` | Present when focused | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the valuetext | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string[]` | No | The aria-label of each slider thumb. Useful for providing an accessible name to the slider | | `aria-labelledby` | `string[]` | No | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number[]` | No | The initial value of the slider when rendered. Use when you don't need to control the value of the slider. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `disabled` | `boolean` | No | Whether the slider is disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `getAriaValueText` | `(details: ValueTextDetails) => string` | No | Function that returns a human readable value for the slider thumb | | `getRootNode` | `() => ShadowRoot | Node | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb(index: number): string hiddenInput(index: number): string control: string track: string range: string label: string valueText: string marker(index: number): string }>` | No | The ids of the elements in the slider. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid | | `max` | `number` | No | The maximum value of the slider | | `min` | `number` | No | The minimum value of the slider | | `minStepsBetweenThumbs` | `number` | No | The minimum permitted steps between multiple thumbs. | | `modelValue` | `number[]` | No | The v-model value of the slider | | `name` | `string` | No | The name associated with each slider thumb (when used in a form) | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the slider | | `origin` | `'start' | 'center'` | No | The origin of the slider range - "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) | | `readOnly` | `boolean` | No | Whether the slider is read-only | | `step` | `number` | No | The step value of the slider | | `thumbAlignment` | `'center' | 'contain'` | No | The alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. | | `thumbSize` | `{ width: number; height: number }` | No | The slider thumbs dimensions | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the slider | | `[data-dragging]` | Present when in the dragging state | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slider-thumb-width` | The thumb width of the slider | | `--slider-thumb-height` | The thumb height of the slider | | `--slider-thumb-transform` | The thumb transform of the slider | | `--slider-range-start` | The range start of the slider | | `--slider-range-end` | The range end of the slider | | `--translate-x` | The horizontal translation value | | `--translate-y` | The vertical translation value | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | control | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the control | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **DraggingIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **DraggingIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | dragging-indicator | | `[data-orientation]` | The orientation of the draggingindicator | | `[data-state]` | "open" | "closed" | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the label | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **MarkerGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker-group | | `[data-orientation]` | The orientation of the markergroup | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker | | `[data-orientation]` | The orientation of the marker | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-state]` | | **Range Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Range Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | range | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the range | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SliderApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `name` | `string` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | thumb | | `[data-index]` | The index of the item | | `[data-name]` | | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the thumb | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | **Track Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Track Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | track | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-orientation]` | The orientation of the track | | `[data-focus]` | Present when focused | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the valuetext | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string[]` | No | The aria-label of each slider thumb. Useful for providing an accessible name to the slider | | `aria-labelledby` | `string[]` | No | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `number[]` | No | The initial value of the slider when rendered. Use when you don't need to control the value of the slider. | | `disabled` | `boolean` | No | Whether the slider is disabled | | `form` | `string` | No | The associate form of the underlying input element. | | `getAriaValueText` | `(details: ValueTextDetails) => string` | No | Function that returns a human readable value for the slider thumb | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string thumb: (index: number) => string hiddenInput: (index: number) => string control: string track: string range: string label: string valueText: string marker: (index: number) => string }>` | No | The ids of the elements in the slider. Useful for composition. | | `invalid` | `boolean` | No | Whether the slider is invalid | | `max` | `number` | No | The maximum value of the slider | | `min` | `number` | No | The minimum value of the slider | | `minStepsBetweenThumbs` | `number` | No | The minimum permitted steps between multiple thumbs. `minStepsBetweenThumbs` * `step` should reflect the gap between the thumbs. - `step: 1` and `minStepsBetweenThumbs: 10` => gap is `10` - `step: 10` and `minStepsBetweenThumbs: 2` => gap is `20` | | `name` | `string` | No | The name associated with each slider thumb (when used in a form) | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Function invoked when the slider's focused index changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function invoked when the value of the slider changes | | `onValueChangeEnd` | `(details: ValueChangeDetails) => void` | No | Function invoked when the slider value change is done | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the slider | | `origin` | `'start' | 'center' | 'end'` | No | The origin of the slider range. The track is filled from the origin to the thumb for single values. - "start": Useful when the value represents an absolute value - "center": Useful when the value represents an offset (relative) - "end": Useful when the value represents an offset from the end | | `readOnly` | `boolean` | No | Whether the slider is read-only | | `ref` | `Element` | No | | | `step` | `number` | No | The step value of the slider | | `thumbAlignment` | `'center' | 'contain'` | No | The alignment of the slider thumb relative to the track - `center`: the thumb will extend beyond the bounds of the slider track. - `contain`: the thumb will be contained within the bounds of the track. | | `thumbSize` | `{ width: number; height: number }` | No | The slider thumbs dimensions | | `value` | `number[]` | No | The controlled value of the slider | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the slider | | `[data-dragging]` | Present when in the dragging state | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--slider-thumb-width` | The thumb width of the slider | | `--slider-thumb-height` | The thumb height of the slider | | `--slider-thumb-transform` | The thumb transform of the slider | | `--slider-range-start` | The range start of the slider | | `--slider-range-end` | The range end of the slider | | `--translate-x` | The horizontal translation value | | `--translate-y` | The vertical translation value | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSliderContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | control | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the control | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **DraggingIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **DraggingIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | dragging-indicator | | `[data-orientation]` | The orientation of the draggingindicator | | `[data-state]` | "open" | "closed" | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the label | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | **MarkerGroup Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **MarkerGroup Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker-group | | `[data-orientation]` | The orientation of the markergroup | **Marker Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Marker Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | marker | | `[data-orientation]` | The orientation of the marker | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-state]` | | **Range Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Range Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | range | | `[data-dragging]` | Present when in the dragging state | | `[data-focus]` | Present when focused | | `[data-invalid]` | Present when invalid | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the range | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSliderReturn` | Yes | | | `ref` | `Element` | No | | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `name` | `string` | No | | | `ref` | `Element` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | thumb | | `[data-index]` | The index of the item | | `[data-name]` | | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the thumb | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | **Track Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Track Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | track | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-dragging]` | Present when in the dragging state | | `[data-orientation]` | The orientation of the track | | `[data-focus]` | Present when focused | **ValueText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ValueText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | slider | | `[data-part]` | value-text | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the valuetext | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `number[]` | The value of the slider. | | `dragging` | `boolean` | Whether the slider is being dragged. | | `focused` | `boolean` | Whether the slider is focused. | | `setValue` | `(value: number[]) => void` | Function to set the value of the slider. | | `getThumbValue` | `(index: number) => number` | Returns the value of the thumb at the given index. | | `setThumbValue` | `(index: number, value: number) => void` | Sets the value of the thumb at the given index. | | `getValuePercent` | `(value: number) => number` | Returns the percent of the thumb at the given index. | | `getPercentValue` | `(percent: number) => number` | Returns the value of the thumb at the given percent. | | `getThumbPercent` | `(index: number) => number` | Returns the percent of the thumb at the given index. | | `setThumbPercent` | `(index: number, percent: number) => void` | Sets the percent of the thumb at the given index. | | `getThumbMin` | `(index: number) => number` | Returns the min value of the thumb at the given index. | | `getThumbMax` | `(index: number) => number` | Returns the max value of the thumb at the given index. | | `increment` | `(index: number) => void` | Function to increment the value of the slider at the given index. | | `decrement` | `(index: number) => void` | Function to decrement the value of the slider at the given index. | | `focus` | `VoidFunction` | Function to focus the slider. This focuses the first thumb. | ## Accessibility Complies with the [Slider WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/slider/). ### Keyboard Support **`ArrowRight`** Description: Increments the slider based on defined step **`ArrowLeft`** Description: Decrements the slider based on defined step **`ArrowUp`** Description: Increases the value by the step amount. **`ArrowDown`** Description: Decreases the value by the step amount. **`PageUp`** Description: Increases the value by a larger step **`PageDown`** Description: Decreases the value by a larger step **`Shift + ArrowUp`** Description: Increases the value by a larger step **`Shift + ArrowDown`** Description: Decreases the value by a larger step **`Home`** Description: Sets the value to its minimum. **`End`** Description: Sets the value to its maximum. --- # Splitter (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const Basic = () => ( A B ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const Basic = () => ( A B ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B ``` ### Context The Splitter component allows you to pass a function as a child to gain direct access to its API. This provides more control and allows you to modify the size of the panels programmatically: **Example: context** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import button from 'styles/button.module.css' import styles from 'styles/splitter.module.css' export const Context = () => ( {(splitter) => ( <> )} ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import button from 'styles/button.module.css' import styles from 'styles/splitter.module.css' export const Context = () => ( {(splitter) => ( <> )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(splitter)} {/snippet} ``` ### Vertical By default, the Splitter component is horizontal. If you need a vertical splitter, use the `orientation` prop: **Example: vertical** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const Vertical = () => ( A B ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const Vertical = () => ( A B ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B ``` ### 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. **Example: collapsible** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const Collapsible = () => ( A B ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const Collapsible = () => ( A B ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B ``` ### Multiple Panels Here's an example of how to use the `Splitter` component with multiple panels. **Example: multiple-panels** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const MultiplePanels = () => ( A B C ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const MultiplePanels = () => ( A B C ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B C ``` ### 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. **Example: root-provider** #### React ```tsx import { Splitter, useSplitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const RootProvider = () => { const splitter = useSplitter({ defaultSize: [50, 50], panels: [{ id: 'a' }, { id: 'b' }], }) return (
                    current size: {JSON.stringify(splitter.getSizes())} A B
                    ) } ``` #### Solid ```tsx import { Splitter, useSplitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const RootProvider = () => { const splitter = useSplitter({ defaultSize: [50, 50], panels: [{ id: 'a' }, { id: 'b' }], }) return (
                    current size: {JSON.stringify(splitter().getSizes())} A B
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    current size: {JSON.stringify(splitter().getSizes())} A B
                    ``` ### Resize Indicator Use the `Splitter.ResizeTriggerIndicator` component to show a visual indicator on the resize handle. **Example: resize-indicator** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const ResizeIndicator = () => ( A B ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const ResizeIndicator = () => ( A B ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B ``` ### 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. **Example: dynamic-collapsible** #### React ```tsx /** biome-ignore-all lint/correctness/useExhaustiveDependencies: intentional */ import { Splitter, useSplitter } from '@ark-ui/react/splitter' import { useLayoutEffect, useRef, useState } from 'react' import styles from 'styles/splitter.module.css' export const DynamicCollapsible = () => { const [rootSize, setRootSize] = useState(null) const ref = useRef(null) useLayoutEffect(() => { const handleResize = () => setRootSize(ref.current?.offsetWidth ?? null) handleResize() window.addEventListener('resize', handleResize) return () => window.removeEventListener('resize', handleResize) }, []) const isBelowMd = rootSize != null && rootSize < 600 useLayoutEffect(() => { if (isBelowMd) splitter.collapsePanel('a') else splitter.expandPanel('a') }, [isBelowMd]) const splitter = useSplitter({ panels: [{ id: 'a', collapsible: isBelowMd, collapsedSize: 5, minSize: 20, maxSize: 40 }, { id: 'b' }], defaultSize: [15, 85], }) return ( A B ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `panels` | `PanelData[]` | Yes | The size constraints of the panels. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultSize` | `number[]` | No | The initial size of the panels when rendered. Use when you don't need to control the size of the panels. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string resizeTrigger: (id: string) => string label: (id: string) => string panel: (id: string | number) => string }>` | No | The ids of the elements in the splitter. Useful for composition. | | `keyboardResizeBy` | `number` | No | The number of pixels to resize the panel by when the keyboard is used. | | `nonce` | `string` | No | The nonce for the injected splitter cursor stylesheet. | | `onCollapse` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is collapsed. | | `onExpand` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is expanded. | | `onResize` | `(details: ResizeDetails) => void` | No | Function called when the splitter is resized. | | `onResizeEnd` | `(details: ResizeEndDetails) => void` | No | Function called when the splitter resize ends. | | `onResizeStart` | `() => void` | No | Function called when the splitter resize starts. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the splitter. Can be `horizontal` or `vertical` | | `size` | `number[]` | No | The controlled size data of the panels | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | root | | `[data-orientation]` | The orientation of the splitter | | `[data-dragging]` | Present when in the dragging state | **Panel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Panel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | panel | | `[data-orientation]` | The orientation of the panel | | `[data-dragging]` | Present when in the dragging state | | `[data-id]` | | | `[data-index]` | The index of the item | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | ``${string}:${string}`` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | resize-trigger | | `[data-id]` | | | `[data-orientation]` | The orientation of the resizetrigger | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSplitterReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `panels` | `PanelData[]` | Yes | The size constraints of the panels. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultSize` | `number[]` | No | The initial size of the panels when rendered. Use when you don't need to control the size of the panels. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string resizeTrigger: (id: string) => string label: (id: string) => string panel: (id: string | number) => string }>` | No | The ids of the elements in the splitter. Useful for composition. | | `keyboardResizeBy` | `number` | No | The number of pixels to resize the panel by when the keyboard is used. | | `nonce` | `string` | No | The nonce for the injected splitter cursor stylesheet. | | `onCollapse` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is collapsed. | | `onExpand` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is expanded. | | `onResize` | `(details: ResizeDetails) => void` | No | Function called when the splitter is resized. | | `onResizeEnd` | `(details: ResizeEndDetails) => void` | No | Function called when the splitter resize ends. | | `onResizeStart` | `() => void` | No | Function called when the splitter resize starts. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the splitter. Can be `horizontal` or `vertical` | | `size` | `number[]` | No | The controlled size data of the panels | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | root | | `[data-orientation]` | The orientation of the splitter | | `[data-dragging]` | Present when in the dragging state | **Panel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Panel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | panel | | `[data-orientation]` | The orientation of the panel | | `[data-dragging]` | Present when in the dragging state | | `[data-id]` | | | `[data-index]` | The index of the item | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | ``${string}:${string}`` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | resize-trigger | | `[data-id]` | | | `[data-orientation]` | The orientation of the resizetrigger | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSplitterReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `panels` | `PanelData[]` | Yes | The size constraints of the panels. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultSize` | `number[]` | No | The initial size of the panels when rendered. Use when you don't need to control the size of the panels. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string resizeTrigger(id: string): string label(id: string): string panel(id: string | number): string }>` | No | The ids of the elements in the splitter. Useful for composition. | | `keyboardResizeBy` | `number` | No | The number of pixels to resize the panel by when the keyboard is used. | | `nonce` | `string` | No | The nonce for the injected splitter cursor stylesheet. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the splitter. Can be `horizontal` or `vertical` | | `size` | `number[]` | No | The controlled size data of the panels | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | root | | `[data-orientation]` | The orientation of the splitter | | `[data-dragging]` | Present when in the dragging state | **Panel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Panel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | panel | | `[data-orientation]` | The orientation of the panel | | `[data-dragging]` | Present when in the dragging state | | `[data-id]` | | | `[data-index]` | The index of the item | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | ``${string}:${string}`` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | resize-trigger | | `[data-id]` | | | `[data-orientation]` | The orientation of the resizetrigger | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SplitterApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `panels` | `PanelData[]` | Yes | The size constraints of the panels. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultSize` | `number[]` | No | The initial size of the panels when rendered. Use when you don't need to control the size of the panels. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string resizeTrigger: (id: string) => string label: (id: string) => string panel: (id: string | number) => string }>` | No | The ids of the elements in the splitter. Useful for composition. | | `keyboardResizeBy` | `number` | No | The number of pixels to resize the panel by when the keyboard is used. | | `nonce` | `string` | No | The nonce for the injected splitter cursor stylesheet. | | `onCollapse` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is collapsed. | | `onExpand` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is expanded. | | `onResize` | `(details: ResizeDetails) => void` | No | Function called when the splitter is resized. | | `onResizeEnd` | `(details: ResizeEndDetails) => void` | No | Function called when the splitter resize ends. | | `onResizeStart` | `() => void` | No | Function called when the splitter resize starts. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the splitter. Can be `horizontal` or `vertical` | | `ref` | `Element` | No | | | `size` | `number[]` | No | The controlled size data of the panels | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | root | | `[data-orientation]` | The orientation of the splitter | | `[data-dragging]` | Present when in the dragging state | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSplitterContext]>` | Yes | | **Panel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Panel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | panel | | `[data-orientation]` | The orientation of the panel | | `[data-dragging]` | Present when in the dragging state | | `[data-id]` | | | `[data-index]` | The index of the item | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | ``${string}:${string}`` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `ref` | `Element` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | resize-trigger | | `[data-id]` | | | `[data-orientation]` | The orientation of the resizetrigger | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSplitterReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `dragging` | `boolean` | Whether the splitter is currently being resized. | | `orientation` | `"horizontal" | "vertical"` | The orientation of the splitter. | | `getSizes` | `() => number[]` | Returns the current sizes of the panels. | | `setSizes` | `(size: number[]) => void` | Sets the sizes of the panels. | | `getItems` | `() => SplitterItem[]` | Returns the items of the splitter. | | `getPanels` | `() => PanelData[]` | Returns the panels of the splitter. | | `getPanelById` | `(id: string) => PanelData` | Returns the panel with the specified id. | | `getPanelSize` | `(id: string) => number` | Returns the size of the specified panel. | | `isPanelCollapsed` | `(id: string) => boolean` | Returns whether the specified panel is collapsed. | | `isPanelExpanded` | `(id: string) => boolean` | Returns whether the specified panel is expanded. | | `collapsePanel` | `(id: string) => void` | Collapses the specified panel. | | `expandPanel` | `(id: string, minSize?: number) => void` | Expands the specified panel. | | `resizePanel` | `(id: string, unsafePanelSize: number) => void` | Resizes the specified panel. | | `getLayout` | `() => string` | Returns the layout of the splitter. | | `resetSizes` | `VoidFunction` | Resets the splitter to its initial state. | | `getResizeTriggerState` | `(props: ResizeTriggerProps) => ResizeTriggerState` | Returns the state of the resize trigger. | ## Accessibility Complies with the [Window Splitter WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/). --- # Splitter (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const Basic = () => ( A B ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const Basic = () => ( A B ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B ``` ### Context The Splitter component allows you to pass a function as a child to gain direct access to its API. This provides more control and allows you to modify the size of the panels programmatically: **Example: context** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import button from 'styles/button.module.css' import styles from 'styles/splitter.module.css' export const Context = () => ( {(splitter) => ( <> )} ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import button from 'styles/button.module.css' import styles from 'styles/splitter.module.css' export const Context = () => ( {(splitter) => ( <> )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(splitter)} {/snippet} ``` ### Vertical By default, the Splitter component is horizontal. If you need a vertical splitter, use the `orientation` prop: **Example: vertical** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const Vertical = () => ( A B ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const Vertical = () => ( A B ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B ``` ### 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. **Example: collapsible** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const Collapsible = () => ( A B ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const Collapsible = () => ( A B ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B ``` ### Multiple Panels Here's an example of how to use the `Splitter` component with multiple panels. **Example: multiple-panels** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const MultiplePanels = () => ( A B C ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const MultiplePanels = () => ( A B C ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B C ``` ### 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. **Example: root-provider** #### React ```tsx import { Splitter, useSplitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const RootProvider = () => { const splitter = useSplitter({ defaultSize: [50, 50], panels: [{ id: 'a' }, { id: 'b' }], }) return (
                    current size: {JSON.stringify(splitter.getSizes())} A B
                    ) } ``` #### Solid ```tsx import { Splitter, useSplitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const RootProvider = () => { const splitter = useSplitter({ defaultSize: [50, 50], panels: [{ id: 'a' }, { id: 'b' }], }) return (
                    current size: {JSON.stringify(splitter().getSizes())} A B
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    current size: {JSON.stringify(splitter().getSizes())} A B
                    ``` ### Resize Indicator Use the `Splitter.ResizeTriggerIndicator` component to show a visual indicator on the resize handle. **Example: resize-indicator** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const ResizeIndicator = () => ( A B ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const ResizeIndicator = () => ( A B ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B ``` ### 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. **Example: dynamic-collapsible** #### React ```tsx /** biome-ignore-all lint/correctness/useExhaustiveDependencies: intentional */ import { Splitter, useSplitter } from '@ark-ui/react/splitter' import { useLayoutEffect, useRef, useState } from 'react' import styles from 'styles/splitter.module.css' export const DynamicCollapsible = () => { const [rootSize, setRootSize] = useState(null) const ref = useRef(null) useLayoutEffect(() => { const handleResize = () => setRootSize(ref.current?.offsetWidth ?? null) handleResize() window.addEventListener('resize', handleResize) return () => window.removeEventListener('resize', handleResize) }, []) const isBelowMd = rootSize != null && rootSize < 600 useLayoutEffect(() => { if (isBelowMd) splitter.collapsePanel('a') else splitter.expandPanel('a') }, [isBelowMd]) const splitter = useSplitter({ panels: [{ id: 'a', collapsible: isBelowMd, collapsedSize: 5, minSize: 20, maxSize: 40 }, { id: 'b' }], defaultSize: [15, 85], }) return ( A B ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `panels` | `PanelData[]` | Yes | The size constraints of the panels. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultSize` | `number[]` | No | The initial size of the panels when rendered. Use when you don't need to control the size of the panels. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string resizeTrigger: (id: string) => string label: (id: string) => string panel: (id: string | number) => string }>` | No | The ids of the elements in the splitter. Useful for composition. | | `keyboardResizeBy` | `number` | No | The number of pixels to resize the panel by when the keyboard is used. | | `nonce` | `string` | No | The nonce for the injected splitter cursor stylesheet. | | `onCollapse` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is collapsed. | | `onExpand` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is expanded. | | `onResize` | `(details: ResizeDetails) => void` | No | Function called when the splitter is resized. | | `onResizeEnd` | `(details: ResizeEndDetails) => void` | No | Function called when the splitter resize ends. | | `onResizeStart` | `() => void` | No | Function called when the splitter resize starts. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the splitter. Can be `horizontal` or `vertical` | | `size` | `number[]` | No | The controlled size data of the panels | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | root | | `[data-orientation]` | The orientation of the splitter | | `[data-dragging]` | Present when in the dragging state | **Panel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Panel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | panel | | `[data-orientation]` | The orientation of the panel | | `[data-dragging]` | Present when in the dragging state | | `[data-id]` | | | `[data-index]` | The index of the item | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | ``${string}:${string}`` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | resize-trigger | | `[data-id]` | | | `[data-orientation]` | The orientation of the resizetrigger | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSplitterReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `panels` | `PanelData[]` | Yes | The size constraints of the panels. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultSize` | `number[]` | No | The initial size of the panels when rendered. Use when you don't need to control the size of the panels. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string resizeTrigger: (id: string) => string label: (id: string) => string panel: (id: string | number) => string }>` | No | The ids of the elements in the splitter. Useful for composition. | | `keyboardResizeBy` | `number` | No | The number of pixels to resize the panel by when the keyboard is used. | | `nonce` | `string` | No | The nonce for the injected splitter cursor stylesheet. | | `onCollapse` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is collapsed. | | `onExpand` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is expanded. | | `onResize` | `(details: ResizeDetails) => void` | No | Function called when the splitter is resized. | | `onResizeEnd` | `(details: ResizeEndDetails) => void` | No | Function called when the splitter resize ends. | | `onResizeStart` | `() => void` | No | Function called when the splitter resize starts. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the splitter. Can be `horizontal` or `vertical` | | `size` | `number[]` | No | The controlled size data of the panels | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | root | | `[data-orientation]` | The orientation of the splitter | | `[data-dragging]` | Present when in the dragging state | **Panel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Panel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | panel | | `[data-orientation]` | The orientation of the panel | | `[data-dragging]` | Present when in the dragging state | | `[data-id]` | | | `[data-index]` | The index of the item | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | ``${string}:${string}`` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | resize-trigger | | `[data-id]` | | | `[data-orientation]` | The orientation of the resizetrigger | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSplitterReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `panels` | `PanelData[]` | Yes | The size constraints of the panels. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultSize` | `number[]` | No | The initial size of the panels when rendered. Use when you don't need to control the size of the panels. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string resizeTrigger(id: string): string label(id: string): string panel(id: string | number): string }>` | No | The ids of the elements in the splitter. Useful for composition. | | `keyboardResizeBy` | `number` | No | The number of pixels to resize the panel by when the keyboard is used. | | `nonce` | `string` | No | The nonce for the injected splitter cursor stylesheet. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the splitter. Can be `horizontal` or `vertical` | | `size` | `number[]` | No | The controlled size data of the panels | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | root | | `[data-orientation]` | The orientation of the splitter | | `[data-dragging]` | Present when in the dragging state | **Panel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Panel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | panel | | `[data-orientation]` | The orientation of the panel | | `[data-dragging]` | Present when in the dragging state | | `[data-id]` | | | `[data-index]` | The index of the item | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | ``${string}:${string}`` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | resize-trigger | | `[data-id]` | | | `[data-orientation]` | The orientation of the resizetrigger | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SplitterApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `panels` | `PanelData[]` | Yes | The size constraints of the panels. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultSize` | `number[]` | No | The initial size of the panels when rendered. Use when you don't need to control the size of the panels. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string resizeTrigger: (id: string) => string label: (id: string) => string panel: (id: string | number) => string }>` | No | The ids of the elements in the splitter. Useful for composition. | | `keyboardResizeBy` | `number` | No | The number of pixels to resize the panel by when the keyboard is used. | | `nonce` | `string` | No | The nonce for the injected splitter cursor stylesheet. | | `onCollapse` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is collapsed. | | `onExpand` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is expanded. | | `onResize` | `(details: ResizeDetails) => void` | No | Function called when the splitter is resized. | | `onResizeEnd` | `(details: ResizeEndDetails) => void` | No | Function called when the splitter resize ends. | | `onResizeStart` | `() => void` | No | Function called when the splitter resize starts. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the splitter. Can be `horizontal` or `vertical` | | `ref` | `Element` | No | | | `size` | `number[]` | No | The controlled size data of the panels | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | root | | `[data-orientation]` | The orientation of the splitter | | `[data-dragging]` | Present when in the dragging state | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSplitterContext]>` | Yes | | **Panel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Panel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | panel | | `[data-orientation]` | The orientation of the panel | | `[data-dragging]` | Present when in the dragging state | | `[data-id]` | | | `[data-index]` | The index of the item | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | ``${string}:${string}`` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `ref` | `Element` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | resize-trigger | | `[data-id]` | | | `[data-orientation]` | The orientation of the resizetrigger | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSplitterReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `dragging` | `boolean` | Whether the splitter is currently being resized. | | `orientation` | `"horizontal" | "vertical"` | The orientation of the splitter. | | `getSizes` | `() => number[]` | Returns the current sizes of the panels. | | `setSizes` | `(size: number[]) => void` | Sets the sizes of the panels. | | `getItems` | `() => SplitterItem[]` | Returns the items of the splitter. | | `getPanels` | `() => PanelData[]` | Returns the panels of the splitter. | | `getPanelById` | `(id: string) => PanelData` | Returns the panel with the specified id. | | `getPanelSize` | `(id: string) => number` | Returns the size of the specified panel. | | `isPanelCollapsed` | `(id: string) => boolean` | Returns whether the specified panel is collapsed. | | `isPanelExpanded` | `(id: string) => boolean` | Returns whether the specified panel is expanded. | | `collapsePanel` | `(id: string) => void` | Collapses the specified panel. | | `expandPanel` | `(id: string, minSize?: number) => void` | Expands the specified panel. | | `resizePanel` | `(id: string, unsafePanelSize: number) => void` | Resizes the specified panel. | | `getLayout` | `() => string` | Returns the layout of the splitter. | | `resetSizes` | `VoidFunction` | Resets the splitter to its initial state. | | `getResizeTriggerState` | `(props: ResizeTriggerProps) => ResizeTriggerState` | Returns the state of the resize trigger. | ## Accessibility Complies with the [Window Splitter WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/). --- # Splitter (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const Basic = () => ( A B ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const Basic = () => ( A B ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B ``` ### Context The Splitter component allows you to pass a function as a child to gain direct access to its API. This provides more control and allows you to modify the size of the panels programmatically: **Example: context** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import button from 'styles/button.module.css' import styles from 'styles/splitter.module.css' export const Context = () => ( {(splitter) => ( <> )} ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import button from 'styles/button.module.css' import styles from 'styles/splitter.module.css' export const Context = () => ( {(splitter) => ( <> )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(splitter)} {/snippet} ``` ### Vertical By default, the Splitter component is horizontal. If you need a vertical splitter, use the `orientation` prop: **Example: vertical** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const Vertical = () => ( A B ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const Vertical = () => ( A B ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B ``` ### 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. **Example: collapsible** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const Collapsible = () => ( A B ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const Collapsible = () => ( A B ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B ``` ### Multiple Panels Here's an example of how to use the `Splitter` component with multiple panels. **Example: multiple-panels** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const MultiplePanels = () => ( A B C ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const MultiplePanels = () => ( A B C ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B C ``` ### 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. **Example: root-provider** #### React ```tsx import { Splitter, useSplitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const RootProvider = () => { const splitter = useSplitter({ defaultSize: [50, 50], panels: [{ id: 'a' }, { id: 'b' }], }) return (
                    current size: {JSON.stringify(splitter.getSizes())} A B
                    ) } ``` #### Solid ```tsx import { Splitter, useSplitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const RootProvider = () => { const splitter = useSplitter({ defaultSize: [50, 50], panels: [{ id: 'a' }, { id: 'b' }], }) return (
                    current size: {JSON.stringify(splitter().getSizes())} A B
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    current size: {JSON.stringify(splitter().getSizes())} A B
                    ``` ### Resize Indicator Use the `Splitter.ResizeTriggerIndicator` component to show a visual indicator on the resize handle. **Example: resize-indicator** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const ResizeIndicator = () => ( A B ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const ResizeIndicator = () => ( A B ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B ``` ### 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. **Example: dynamic-collapsible** #### React ```tsx /** biome-ignore-all lint/correctness/useExhaustiveDependencies: intentional */ import { Splitter, useSplitter } from '@ark-ui/react/splitter' import { useLayoutEffect, useRef, useState } from 'react' import styles from 'styles/splitter.module.css' export const DynamicCollapsible = () => { const [rootSize, setRootSize] = useState(null) const ref = useRef(null) useLayoutEffect(() => { const handleResize = () => setRootSize(ref.current?.offsetWidth ?? null) handleResize() window.addEventListener('resize', handleResize) return () => window.removeEventListener('resize', handleResize) }, []) const isBelowMd = rootSize != null && rootSize < 600 useLayoutEffect(() => { if (isBelowMd) splitter.collapsePanel('a') else splitter.expandPanel('a') }, [isBelowMd]) const splitter = useSplitter({ panels: [{ id: 'a', collapsible: isBelowMd, collapsedSize: 5, minSize: 20, maxSize: 40 }, { id: 'b' }], defaultSize: [15, 85], }) return ( A B ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `panels` | `PanelData[]` | Yes | The size constraints of the panels. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultSize` | `number[]` | No | The initial size of the panels when rendered. Use when you don't need to control the size of the panels. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string resizeTrigger: (id: string) => string label: (id: string) => string panel: (id: string | number) => string }>` | No | The ids of the elements in the splitter. Useful for composition. | | `keyboardResizeBy` | `number` | No | The number of pixels to resize the panel by when the keyboard is used. | | `nonce` | `string` | No | The nonce for the injected splitter cursor stylesheet. | | `onCollapse` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is collapsed. | | `onExpand` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is expanded. | | `onResize` | `(details: ResizeDetails) => void` | No | Function called when the splitter is resized. | | `onResizeEnd` | `(details: ResizeEndDetails) => void` | No | Function called when the splitter resize ends. | | `onResizeStart` | `() => void` | No | Function called when the splitter resize starts. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the splitter. Can be `horizontal` or `vertical` | | `size` | `number[]` | No | The controlled size data of the panels | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | root | | `[data-orientation]` | The orientation of the splitter | | `[data-dragging]` | Present when in the dragging state | **Panel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Panel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | panel | | `[data-orientation]` | The orientation of the panel | | `[data-dragging]` | Present when in the dragging state | | `[data-id]` | | | `[data-index]` | The index of the item | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | ``${string}:${string}`` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | resize-trigger | | `[data-id]` | | | `[data-orientation]` | The orientation of the resizetrigger | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSplitterReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `panels` | `PanelData[]` | Yes | The size constraints of the panels. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultSize` | `number[]` | No | The initial size of the panels when rendered. Use when you don't need to control the size of the panels. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string resizeTrigger: (id: string) => string label: (id: string) => string panel: (id: string | number) => string }>` | No | The ids of the elements in the splitter. Useful for composition. | | `keyboardResizeBy` | `number` | No | The number of pixels to resize the panel by when the keyboard is used. | | `nonce` | `string` | No | The nonce for the injected splitter cursor stylesheet. | | `onCollapse` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is collapsed. | | `onExpand` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is expanded. | | `onResize` | `(details: ResizeDetails) => void` | No | Function called when the splitter is resized. | | `onResizeEnd` | `(details: ResizeEndDetails) => void` | No | Function called when the splitter resize ends. | | `onResizeStart` | `() => void` | No | Function called when the splitter resize starts. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the splitter. Can be `horizontal` or `vertical` | | `size` | `number[]` | No | The controlled size data of the panels | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | root | | `[data-orientation]` | The orientation of the splitter | | `[data-dragging]` | Present when in the dragging state | **Panel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Panel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | panel | | `[data-orientation]` | The orientation of the panel | | `[data-dragging]` | Present when in the dragging state | | `[data-id]` | | | `[data-index]` | The index of the item | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | ``${string}:${string}`` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | resize-trigger | | `[data-id]` | | | `[data-orientation]` | The orientation of the resizetrigger | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSplitterReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `panels` | `PanelData[]` | Yes | The size constraints of the panels. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultSize` | `number[]` | No | The initial size of the panels when rendered. Use when you don't need to control the size of the panels. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string resizeTrigger(id: string): string label(id: string): string panel(id: string | number): string }>` | No | The ids of the elements in the splitter. Useful for composition. | | `keyboardResizeBy` | `number` | No | The number of pixels to resize the panel by when the keyboard is used. | | `nonce` | `string` | No | The nonce for the injected splitter cursor stylesheet. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the splitter. Can be `horizontal` or `vertical` | | `size` | `number[]` | No | The controlled size data of the panels | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | root | | `[data-orientation]` | The orientation of the splitter | | `[data-dragging]` | Present when in the dragging state | **Panel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Panel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | panel | | `[data-orientation]` | The orientation of the panel | | `[data-dragging]` | Present when in the dragging state | | `[data-id]` | | | `[data-index]` | The index of the item | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | ``${string}:${string}`` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | resize-trigger | | `[data-id]` | | | `[data-orientation]` | The orientation of the resizetrigger | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SplitterApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `panels` | `PanelData[]` | Yes | The size constraints of the panels. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultSize` | `number[]` | No | The initial size of the panels when rendered. Use when you don't need to control the size of the panels. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string resizeTrigger: (id: string) => string label: (id: string) => string panel: (id: string | number) => string }>` | No | The ids of the elements in the splitter. Useful for composition. | | `keyboardResizeBy` | `number` | No | The number of pixels to resize the panel by when the keyboard is used. | | `nonce` | `string` | No | The nonce for the injected splitter cursor stylesheet. | | `onCollapse` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is collapsed. | | `onExpand` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is expanded. | | `onResize` | `(details: ResizeDetails) => void` | No | Function called when the splitter is resized. | | `onResizeEnd` | `(details: ResizeEndDetails) => void` | No | Function called when the splitter resize ends. | | `onResizeStart` | `() => void` | No | Function called when the splitter resize starts. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the splitter. Can be `horizontal` or `vertical` | | `ref` | `Element` | No | | | `size` | `number[]` | No | The controlled size data of the panels | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | root | | `[data-orientation]` | The orientation of the splitter | | `[data-dragging]` | Present when in the dragging state | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSplitterContext]>` | Yes | | **Panel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Panel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | panel | | `[data-orientation]` | The orientation of the panel | | `[data-dragging]` | Present when in the dragging state | | `[data-id]` | | | `[data-index]` | The index of the item | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | ``${string}:${string}`` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `ref` | `Element` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | resize-trigger | | `[data-id]` | | | `[data-orientation]` | The orientation of the resizetrigger | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSplitterReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `dragging` | `boolean` | Whether the splitter is currently being resized. | | `orientation` | `"horizontal" | "vertical"` | The orientation of the splitter. | | `getSizes` | `() => number[]` | Returns the current sizes of the panels. | | `setSizes` | `(size: number[]) => void` | Sets the sizes of the panels. | | `getItems` | `() => SplitterItem[]` | Returns the items of the splitter. | | `getPanels` | `() => PanelData[]` | Returns the panels of the splitter. | | `getPanelById` | `(id: string) => PanelData` | Returns the panel with the specified id. | | `getPanelSize` | `(id: string) => number` | Returns the size of the specified panel. | | `isPanelCollapsed` | `(id: string) => boolean` | Returns whether the specified panel is collapsed. | | `isPanelExpanded` | `(id: string) => boolean` | Returns whether the specified panel is expanded. | | `collapsePanel` | `(id: string) => void` | Collapses the specified panel. | | `expandPanel` | `(id: string, minSize?: number) => void` | Expands the specified panel. | | `resizePanel` | `(id: string, unsafePanelSize: number) => void` | Resizes the specified panel. | | `getLayout` | `() => string` | Returns the layout of the splitter. | | `resetSizes` | `VoidFunction` | Resets the splitter to its initial state. | | `getResizeTriggerState` | `(props: ResizeTriggerProps) => ResizeTriggerState` | Returns the state of the resize trigger. | ## Accessibility Complies with the [Window Splitter WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/). --- # Splitter (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const Basic = () => ( A B ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const Basic = () => ( A B ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B ``` ### Context The Splitter component allows you to pass a function as a child to gain direct access to its API. This provides more control and allows you to modify the size of the panels programmatically: **Example: context** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import button from 'styles/button.module.css' import styles from 'styles/splitter.module.css' export const Context = () => ( {(splitter) => ( <> )} ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import button from 'styles/button.module.css' import styles from 'styles/splitter.module.css' export const Context = () => ( {(splitter) => ( <> )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(splitter)} {/snippet} ``` ### Vertical By default, the Splitter component is horizontal. If you need a vertical splitter, use the `orientation` prop: **Example: vertical** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const Vertical = () => ( A B ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const Vertical = () => ( A B ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B ``` ### 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. **Example: collapsible** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const Collapsible = () => ( A B ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const Collapsible = () => ( A B ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B ``` ### Multiple Panels Here's an example of how to use the `Splitter` component with multiple panels. **Example: multiple-panels** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const MultiplePanels = () => ( A B C ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const MultiplePanels = () => ( A B C ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B C ``` ### 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. **Example: root-provider** #### React ```tsx import { Splitter, useSplitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const RootProvider = () => { const splitter = useSplitter({ defaultSize: [50, 50], panels: [{ id: 'a' }, { id: 'b' }], }) return (
                    current size: {JSON.stringify(splitter.getSizes())} A B
                    ) } ``` #### Solid ```tsx import { Splitter, useSplitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const RootProvider = () => { const splitter = useSplitter({ defaultSize: [50, 50], panels: [{ id: 'a' }, { id: 'b' }], }) return (
                    current size: {JSON.stringify(splitter().getSizes())} A B
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    current size: {JSON.stringify(splitter().getSizes())} A B
                    ``` ### Resize Indicator Use the `Splitter.ResizeTriggerIndicator` component to show a visual indicator on the resize handle. **Example: resize-indicator** #### React ```tsx import { Splitter } from '@ark-ui/react/splitter' import styles from 'styles/splitter.module.css' export const ResizeIndicator = () => ( A B ) ``` #### Solid ```tsx import { Splitter } from '@ark-ui/solid/splitter' import styles from 'styles/splitter.module.css' export const ResizeIndicator = () => ( A B ) ``` #### Vue ```vue ``` #### Svelte ```svelte A B ``` ### 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. **Example: dynamic-collapsible** #### React ```tsx /** biome-ignore-all lint/correctness/useExhaustiveDependencies: intentional */ import { Splitter, useSplitter } from '@ark-ui/react/splitter' import { useLayoutEffect, useRef, useState } from 'react' import styles from 'styles/splitter.module.css' export const DynamicCollapsible = () => { const [rootSize, setRootSize] = useState(null) const ref = useRef(null) useLayoutEffect(() => { const handleResize = () => setRootSize(ref.current?.offsetWidth ?? null) handleResize() window.addEventListener('resize', handleResize) return () => window.removeEventListener('resize', handleResize) }, []) const isBelowMd = rootSize != null && rootSize < 600 useLayoutEffect(() => { if (isBelowMd) splitter.collapsePanel('a') else splitter.expandPanel('a') }, [isBelowMd]) const splitter = useSplitter({ panels: [{ id: 'a', collapsible: isBelowMd, collapsedSize: 5, minSize: 20, maxSize: 40 }, { id: 'b' }], defaultSize: [15, 85], }) return ( A B ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `panels` | `PanelData[]` | Yes | The size constraints of the panels. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultSize` | `number[]` | No | The initial size of the panels when rendered. Use when you don't need to control the size of the panels. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string resizeTrigger: (id: string) => string label: (id: string) => string panel: (id: string | number) => string }>` | No | The ids of the elements in the splitter. Useful for composition. | | `keyboardResizeBy` | `number` | No | The number of pixels to resize the panel by when the keyboard is used. | | `nonce` | `string` | No | The nonce for the injected splitter cursor stylesheet. | | `onCollapse` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is collapsed. | | `onExpand` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is expanded. | | `onResize` | `(details: ResizeDetails) => void` | No | Function called when the splitter is resized. | | `onResizeEnd` | `(details: ResizeEndDetails) => void` | No | Function called when the splitter resize ends. | | `onResizeStart` | `() => void` | No | Function called when the splitter resize starts. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the splitter. Can be `horizontal` or `vertical` | | `size` | `number[]` | No | The controlled size data of the panels | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | root | | `[data-orientation]` | The orientation of the splitter | | `[data-dragging]` | Present when in the dragging state | **Panel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Panel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | panel | | `[data-orientation]` | The orientation of the panel | | `[data-dragging]` | Present when in the dragging state | | `[data-id]` | | | `[data-index]` | The index of the item | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | ``${string}:${string}`` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | resize-trigger | | `[data-id]` | | | `[data-orientation]` | The orientation of the resizetrigger | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSplitterReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `panels` | `PanelData[]` | Yes | The size constraints of the panels. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultSize` | `number[]` | No | The initial size of the panels when rendered. Use when you don't need to control the size of the panels. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string resizeTrigger: (id: string) => string label: (id: string) => string panel: (id: string | number) => string }>` | No | The ids of the elements in the splitter. Useful for composition. | | `keyboardResizeBy` | `number` | No | The number of pixels to resize the panel by when the keyboard is used. | | `nonce` | `string` | No | The nonce for the injected splitter cursor stylesheet. | | `onCollapse` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is collapsed. | | `onExpand` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is expanded. | | `onResize` | `(details: ResizeDetails) => void` | No | Function called when the splitter is resized. | | `onResizeEnd` | `(details: ResizeEndDetails) => void` | No | Function called when the splitter resize ends. | | `onResizeStart` | `() => void` | No | Function called when the splitter resize starts. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the splitter. Can be `horizontal` or `vertical` | | `size` | `number[]` | No | The controlled size data of the panels | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | root | | `[data-orientation]` | The orientation of the splitter | | `[data-dragging]` | Present when in the dragging state | **Panel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Panel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | panel | | `[data-orientation]` | The orientation of the panel | | `[data-dragging]` | Present when in the dragging state | | `[data-id]` | | | `[data-index]` | The index of the item | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | ``${string}:${string}`` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | resize-trigger | | `[data-id]` | | | `[data-orientation]` | The orientation of the resizetrigger | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSplitterReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `panels` | `PanelData[]` | Yes | The size constraints of the panels. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultSize` | `number[]` | No | The initial size of the panels when rendered. Use when you don't need to control the size of the panels. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string resizeTrigger(id: string): string label(id: string): string panel(id: string | number): string }>` | No | The ids of the elements in the splitter. Useful for composition. | | `keyboardResizeBy` | `number` | No | The number of pixels to resize the panel by when the keyboard is used. | | `nonce` | `string` | No | The nonce for the injected splitter cursor stylesheet. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the splitter. Can be `horizontal` or `vertical` | | `size` | `number[]` | No | The controlled size data of the panels | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | root | | `[data-orientation]` | The orientation of the splitter | | `[data-dragging]` | Present when in the dragging state | **Panel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Panel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | panel | | `[data-orientation]` | The orientation of the panel | | `[data-dragging]` | Present when in the dragging state | | `[data-id]` | | | `[data-index]` | The index of the item | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | ``${string}:${string}`` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | resize-trigger | | `[data-id]` | | | `[data-orientation]` | The orientation of the resizetrigger | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SplitterApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `panels` | `PanelData[]` | Yes | The size constraints of the panels. | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultSize` | `number[]` | No | The initial size of the panels when rendered. Use when you don't need to control the size of the panels. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string resizeTrigger: (id: string) => string label: (id: string) => string panel: (id: string | number) => string }>` | No | The ids of the elements in the splitter. Useful for composition. | | `keyboardResizeBy` | `number` | No | The number of pixels to resize the panel by when the keyboard is used. | | `nonce` | `string` | No | The nonce for the injected splitter cursor stylesheet. | | `onCollapse` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is collapsed. | | `onExpand` | `(details: ExpandCollapseDetails) => void` | No | Function called when a panel is expanded. | | `onResize` | `(details: ResizeDetails) => void` | No | Function called when the splitter is resized. | | `onResizeEnd` | `(details: ResizeEndDetails) => void` | No | Function called when the splitter resize ends. | | `onResizeStart` | `() => void` | No | Function called when the splitter resize starts. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the splitter. Can be `horizontal` or `vertical` | | `ref` | `Element` | No | | | `size` | `number[]` | No | The controlled size data of the panels | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | root | | `[data-orientation]` | The orientation of the splitter | | `[data-dragging]` | Present when in the dragging state | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSplitterContext]>` | Yes | | **Panel Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Panel Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | panel | | `[data-orientation]` | The orientation of the panel | | `[data-dragging]` | Present when in the dragging state | | `[data-id]` | | | `[data-index]` | The index of the item | **ResizeTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | ``${string}:${string}`` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `ref` | `Element` | No | | **ResizeTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | splitter | | `[data-part]` | resize-trigger | | `[data-id]` | | | `[data-orientation]` | The orientation of the resizetrigger | | `[data-focus]` | Present when focused | | `[data-dragging]` | Present when in the dragging state | | `[data-disabled]` | Present when disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSplitterReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `dragging` | `boolean` | Whether the splitter is currently being resized. | | `orientation` | `"horizontal" | "vertical"` | The orientation of the splitter. | | `getSizes` | `() => number[]` | Returns the current sizes of the panels. | | `setSizes` | `(size: number[]) => void` | Sets the sizes of the panels. | | `getItems` | `() => SplitterItem[]` | Returns the items of the splitter. | | `getPanels` | `() => PanelData[]` | Returns the panels of the splitter. | | `getPanelById` | `(id: string) => PanelData` | Returns the panel with the specified id. | | `getPanelSize` | `(id: string) => number` | Returns the size of the specified panel. | | `isPanelCollapsed` | `(id: string) => boolean` | Returns whether the specified panel is collapsed. | | `isPanelExpanded` | `(id: string) => boolean` | Returns whether the specified panel is expanded. | | `collapsePanel` | `(id: string) => void` | Collapses the specified panel. | | `expandPanel` | `(id: string, minSize?: number) => void` | Expands the specified panel. | | `resizePanel` | `(id: string, unsafePanelSize: number) => void` | Resizes the specified panel. | | `getLayout` | `() => string` | Returns the layout of the splitter. | | `resetSizes` | `VoidFunction` | Resets the splitter to its initial state. | | `getResizeTriggerState` | `(props: ResizeTriggerProps) => ResizeTriggerState` | Returns the state of the resize trigger. | ## Accessibility Complies with the [Window Splitter WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/). --- # Steps (REACT) ## Anatomy ```tsx ``` ## Examples ### Basic Here's a basic example of the `Steps` component. ```tsx import { Steps } from '@ark-ui/react/steps' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Basic = () => { return ( {items.map((item, index) => ( {index + 1} {item.title} ))} {items.map((item, index) => ( {item.title} - {item.description} ))} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` ### Controlled Using the `RootProvider` component, you can control the active step by using the `step` prop and handling the `onStepChange` event. **Example: controlled** #### React ```tsx import { Steps } from '@ark-ui/react/steps' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Controlled = () => { const [step, setStep] = useState(0) return (
                    current step: {step + 1} setStep(details.step)} > {items.map((item, index) => ( {index + 1} {item.title} ))} {items.map((item, index) => ( {item.title} - {item.description} ))} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` #### Solid ```tsx import { Steps } from '@ark-ui/solid/steps' import { For, createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Controlled = () => { const [step, setStep] = createSignal(0) return (
                    current step: {step() + 1} setStep(details.step)} > {(item, index) => ( {index() + 1} {item.title} )} {(item, index) => ( {item.title} - {item.description} )} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    current step: {step + 1} {#each items as item, index} {index + 1} {item.title} {/each} {#each items as item, index} {item.title} - {item.description} {/each} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Steps, useSteps } from '@ark-ui/react/steps' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const RootProvider = () => { const steps = useSteps({ count: items.length }) return (
                    current step: {steps.value + 1} {items.map((item, index) => ( {index + 1} {item.title} ))} {items.map((item, index) => ( {item.title} - {item.description} ))} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` #### Solid ```tsx import { Steps, useSteps } from '@ark-ui/solid/steps' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const RootProvider = () => { const steps = useSteps({ count: items.length }) return (
                    current step: {steps().value + 1} {(item, index) => ( {index() + 1} {item.title} )} {(item, index) => ( {item.title} - {item.description} )} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    current step: {steps().value + 1} {#each items as item, index} {index + 1} {item.title} {/each} {#each items as item, index} {item.title} - {item.description} {/each} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ``` ### Vertical Use the `orientation` prop to display the steps vertically. **Example: vertical** #### React ```tsx import { Steps } from '@ark-ui/react/steps' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Vertical = () => { return ( {items.map((item, index) => ( {index + 1} {item.title} ))} {items.map((item, index) => (
                    {item.title} - {item.description}
                    Back Next
                    ))}
                    Steps Complete - Thank you for filling out the form! Back
                    ) } ``` #### Solid ```tsx import { Steps } from '@ark-ui/solid/steps' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Vertical = () => { return ( {(item, index) => ( {index() + 1} {item.title} )} {(item, index) => (
                    {item.title} - {item.description}
                    Back Next
                    )}
                    Steps Complete - Thank you for filling out the form! Back
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item, index} {index + 1} {item.title} {/each} {#each items as item, index}
                    {item.title} - {item.description}
                    Back Next
                    {/each}
                    Steps Complete - Thank you for filling out the form! Back
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | The total number of steps | | `defaultStep` | `number` | No | The initial value of the stepper when rendered. Use when you don't need to control the value of the stepper. | | `ids` | `ElementIds` | No | The custom ids for the stepper elements | | `linear` | `boolean` | No | If `true`, the stepper requires the user to complete the steps in order | | `onStepChange` | `(details: StepChangeDetails) => void` | No | Callback to be called when the value changes | | `onStepComplete` | `VoidFunction` | No | Callback to be called when a step is completed | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the stepper | | `step` | `number` | No | The controlled value of the stepper | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | root | | `[data-orientation]` | The orientation of the steps | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--percent` | The percent value for the Root | **CompletedContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | indicator | | `[data-complete]` | Present when the indicator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | item | | `[data-orientation]` | The orientation of the item | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | list | | `[data-orientation]` | The orientation of the list | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | progress | | `[data-complete]` | Present when the progress value is complete | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseStepsReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | separator | | `[data-orientation]` | The orientation of the separator | | `[data-complete]` | Present when the separator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the trigger | | `[data-complete]` | Present when the trigger value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | The total number of steps | | `defaultStep` | `number` | No | The initial value of the stepper when rendered. Use when you don't need to control the value of the stepper. | | `ids` | `ElementIds` | No | The custom ids for the stepper elements | | `linear` | `boolean` | No | If `true`, the stepper requires the user to complete the steps in order | | `onStepChange` | `(details: StepChangeDetails) => void` | No | Callback to be called when the value changes | | `onStepComplete` | `VoidFunction` | No | Callback to be called when a step is completed | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the stepper | | `step` | `number` | No | The controlled value of the stepper | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | root | | `[data-orientation]` | The orientation of the steps | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--percent` | The percent value for the Root | **CompletedContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | indicator | | `[data-complete]` | Present when the indicator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | item | | `[data-orientation]` | The orientation of the item | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | list | | `[data-orientation]` | The orientation of the list | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | progress | | `[data-complete]` | Present when the progress value is complete | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseStepsReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | separator | | `[data-orientation]` | The orientation of the separator | | `[data-complete]` | Present when the separator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the trigger | | `[data-complete]` | Present when the trigger value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | The total number of steps | | `defaultStep` | `number` | No | The initial value of the stepper when rendered. Use when you don't need to control the value of the stepper. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `ElementIds` | No | The custom ids for the stepper elements | | `linear` | `boolean` | No | If `true`, the stepper requires the user to complete the steps in order | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the stepper | | `step` | `number` | No | The controlled value of the stepper | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | root | | `[data-orientation]` | The orientation of the steps | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--percent` | The percent value for the Root | **CompletedContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | indicator | | `[data-complete]` | Present when the indicator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | item | | `[data-orientation]` | The orientation of the item | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | list | | `[data-orientation]` | The orientation of the list | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | progress | | `[data-complete]` | Present when the progress value is complete | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `StepsApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | separator | | `[data-orientation]` | The orientation of the separator | | `[data-complete]` | Present when the separator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the trigger | | `[data-complete]` | Present when the trigger value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | The total number of steps | | `defaultStep` | `number` | No | The initial value of the stepper when rendered. Use when you don't need to control the value of the stepper. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `ElementIds` | No | The custom ids for the stepper elements | | `linear` | `boolean` | No | If `true`, the stepper requires the user to complete the steps in order | | `onStepChange` | `(details: StepChangeDetails) => void` | No | Callback to be called when the value changes | | `onStepComplete` | `VoidFunction` | No | Callback to be called when a step is completed | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the stepper | | `ref` | `Element` | No | | | `step` | `number` | No | The controlled value of the stepper | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | root | | `[data-orientation]` | The orientation of the steps | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--percent` | The percent value for the Root | **CompletedContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the content | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseStepsContext]>` | Yes | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | indicator | | `[data-complete]` | Present when the indicator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseStepsItemContext]>` | Yes | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | item | | `[data-orientation]` | The orientation of the item | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'ol'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | list | | `[data-orientation]` | The orientation of the list | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Progress Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Progress Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | progress | | `[data-complete]` | Present when the progress value is complete | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseStepsReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Separator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | separator | | `[data-orientation]` | The orientation of the separator | | `[data-complete]` | Present when the separator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the trigger | | `[data-complete]` | Present when the trigger value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `number` | The value of the stepper. | | `percent` | `number` | The percentage of the stepper. | | `count` | `number` | The total number of steps. | | `hasNextStep` | `boolean` | Whether the stepper has a next step. | | `hasPrevStep` | `boolean` | Whether the stepper has a previous step. | | `isCompleted` | `boolean` | Whether the stepper is completed. | | `setStep` | `(step: number) => void` | Function to set the value of the stepper. | | `goToNextStep` | `VoidFunction` | Function to go to the next step. | | `goToPrevStep` | `VoidFunction` | Function to go to the previous step. | | `resetStep` | `VoidFunction` | Function to go to reset the stepper. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of the item at the given index. | --- # Steps (VUE) ## Anatomy ```tsx ``` ## Examples ### Basic Here's a basic example of the `Steps` component. ```vue ``` ### Controlled Using the `RootProvider` component, you can control the active step by using the `step` prop and handling the `onStepChange` event. **Example: controlled** #### React ```tsx import { Steps } from '@ark-ui/react/steps' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Controlled = () => { const [step, setStep] = useState(0) return (
                    current step: {step + 1} setStep(details.step)} > {items.map((item, index) => ( {index + 1} {item.title} ))} {items.map((item, index) => ( {item.title} - {item.description} ))} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` #### Solid ```tsx import { Steps } from '@ark-ui/solid/steps' import { For, createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Controlled = () => { const [step, setStep] = createSignal(0) return (
                    current step: {step() + 1} setStep(details.step)} > {(item, index) => ( {index() + 1} {item.title} )} {(item, index) => ( {item.title} - {item.description} )} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    current step: {step + 1} {#each items as item, index} {index + 1} {item.title} {/each} {#each items as item, index} {item.title} - {item.description} {/each} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Steps, useSteps } from '@ark-ui/react/steps' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const RootProvider = () => { const steps = useSteps({ count: items.length }) return (
                    current step: {steps.value + 1} {items.map((item, index) => ( {index + 1} {item.title} ))} {items.map((item, index) => ( {item.title} - {item.description} ))} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` #### Solid ```tsx import { Steps, useSteps } from '@ark-ui/solid/steps' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const RootProvider = () => { const steps = useSteps({ count: items.length }) return (
                    current step: {steps().value + 1} {(item, index) => ( {index() + 1} {item.title} )} {(item, index) => ( {item.title} - {item.description} )} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    current step: {steps().value + 1} {#each items as item, index} {index + 1} {item.title} {/each} {#each items as item, index} {item.title} - {item.description} {/each} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ``` ### Vertical Use the `orientation` prop to display the steps vertically. **Example: vertical** #### React ```tsx import { Steps } from '@ark-ui/react/steps' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Vertical = () => { return ( {items.map((item, index) => ( {index + 1} {item.title} ))} {items.map((item, index) => (
                    {item.title} - {item.description}
                    Back Next
                    ))}
                    Steps Complete - Thank you for filling out the form! Back
                    ) } ``` #### Solid ```tsx import { Steps } from '@ark-ui/solid/steps' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Vertical = () => { return ( {(item, index) => ( {index() + 1} {item.title} )} {(item, index) => (
                    {item.title} - {item.description}
                    Back Next
                    )}
                    Steps Complete - Thank you for filling out the form! Back
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item, index} {index + 1} {item.title} {/each} {#each items as item, index}
                    {item.title} - {item.description}
                    Back Next
                    {/each}
                    Steps Complete - Thank you for filling out the form! Back
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | The total number of steps | | `defaultStep` | `number` | No | The initial value of the stepper when rendered. Use when you don't need to control the value of the stepper. | | `ids` | `ElementIds` | No | The custom ids for the stepper elements | | `linear` | `boolean` | No | If `true`, the stepper requires the user to complete the steps in order | | `onStepChange` | `(details: StepChangeDetails) => void` | No | Callback to be called when the value changes | | `onStepComplete` | `VoidFunction` | No | Callback to be called when a step is completed | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the stepper | | `step` | `number` | No | The controlled value of the stepper | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | root | | `[data-orientation]` | The orientation of the steps | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--percent` | The percent value for the Root | **CompletedContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | indicator | | `[data-complete]` | Present when the indicator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | item | | `[data-orientation]` | The orientation of the item | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | list | | `[data-orientation]` | The orientation of the list | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | progress | | `[data-complete]` | Present when the progress value is complete | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseStepsReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | separator | | `[data-orientation]` | The orientation of the separator | | `[data-complete]` | Present when the separator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the trigger | | `[data-complete]` | Present when the trigger value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | The total number of steps | | `defaultStep` | `number` | No | The initial value of the stepper when rendered. Use when you don't need to control the value of the stepper. | | `ids` | `ElementIds` | No | The custom ids for the stepper elements | | `linear` | `boolean` | No | If `true`, the stepper requires the user to complete the steps in order | | `onStepChange` | `(details: StepChangeDetails) => void` | No | Callback to be called when the value changes | | `onStepComplete` | `VoidFunction` | No | Callback to be called when a step is completed | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the stepper | | `step` | `number` | No | The controlled value of the stepper | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | root | | `[data-orientation]` | The orientation of the steps | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--percent` | The percent value for the Root | **CompletedContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | indicator | | `[data-complete]` | Present when the indicator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | item | | `[data-orientation]` | The orientation of the item | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | list | | `[data-orientation]` | The orientation of the list | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | progress | | `[data-complete]` | Present when the progress value is complete | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseStepsReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | separator | | `[data-orientation]` | The orientation of the separator | | `[data-complete]` | Present when the separator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the trigger | | `[data-complete]` | Present when the trigger value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | The total number of steps | | `defaultStep` | `number` | No | The initial value of the stepper when rendered. Use when you don't need to control the value of the stepper. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `ElementIds` | No | The custom ids for the stepper elements | | `linear` | `boolean` | No | If `true`, the stepper requires the user to complete the steps in order | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the stepper | | `step` | `number` | No | The controlled value of the stepper | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | root | | `[data-orientation]` | The orientation of the steps | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--percent` | The percent value for the Root | **CompletedContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | indicator | | `[data-complete]` | Present when the indicator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | item | | `[data-orientation]` | The orientation of the item | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | list | | `[data-orientation]` | The orientation of the list | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | progress | | `[data-complete]` | Present when the progress value is complete | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `StepsApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | separator | | `[data-orientation]` | The orientation of the separator | | `[data-complete]` | Present when the separator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the trigger | | `[data-complete]` | Present when the trigger value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | The total number of steps | | `defaultStep` | `number` | No | The initial value of the stepper when rendered. Use when you don't need to control the value of the stepper. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `ElementIds` | No | The custom ids for the stepper elements | | `linear` | `boolean` | No | If `true`, the stepper requires the user to complete the steps in order | | `onStepChange` | `(details: StepChangeDetails) => void` | No | Callback to be called when the value changes | | `onStepComplete` | `VoidFunction` | No | Callback to be called when a step is completed | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the stepper | | `ref` | `Element` | No | | | `step` | `number` | No | The controlled value of the stepper | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | root | | `[data-orientation]` | The orientation of the steps | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--percent` | The percent value for the Root | **CompletedContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the content | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseStepsContext]>` | Yes | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | indicator | | `[data-complete]` | Present when the indicator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseStepsItemContext]>` | Yes | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | item | | `[data-orientation]` | The orientation of the item | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'ol'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | list | | `[data-orientation]` | The orientation of the list | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Progress Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Progress Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | progress | | `[data-complete]` | Present when the progress value is complete | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseStepsReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Separator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | separator | | `[data-orientation]` | The orientation of the separator | | `[data-complete]` | Present when the separator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the trigger | | `[data-complete]` | Present when the trigger value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `number` | The value of the stepper. | | `percent` | `number` | The percentage of the stepper. | | `count` | `number` | The total number of steps. | | `hasNextStep` | `boolean` | Whether the stepper has a next step. | | `hasPrevStep` | `boolean` | Whether the stepper has a previous step. | | `isCompleted` | `boolean` | Whether the stepper is completed. | | `setStep` | `(step: number) => void` | Function to set the value of the stepper. | | `goToNextStep` | `VoidFunction` | Function to go to the next step. | | `goToPrevStep` | `VoidFunction` | Function to go to the previous step. | | `resetStep` | `VoidFunction` | Function to go to reset the stepper. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of the item at the given index. | --- # Steps (SVELTE) ## Anatomy ```tsx ``` ## Examples ### Basic Here's a basic example of the `Steps` component. ```svelte {#each items as item, index} {index + 1} {item.title} {/each} {#each items as item, index} {item.title} - {item.description} {/each} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ``` ### Controlled Using the `RootProvider` component, you can control the active step by using the `step` prop and handling the `onStepChange` event. **Example: controlled** #### React ```tsx import { Steps } from '@ark-ui/react/steps' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Controlled = () => { const [step, setStep] = useState(0) return (
                    current step: {step + 1} setStep(details.step)} > {items.map((item, index) => ( {index + 1} {item.title} ))} {items.map((item, index) => ( {item.title} - {item.description} ))} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` #### Solid ```tsx import { Steps } from '@ark-ui/solid/steps' import { For, createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Controlled = () => { const [step, setStep] = createSignal(0) return (
                    current step: {step() + 1} setStep(details.step)} > {(item, index) => ( {index() + 1} {item.title} )} {(item, index) => ( {item.title} - {item.description} )} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    current step: {step + 1} {#each items as item, index} {index + 1} {item.title} {/each} {#each items as item, index} {item.title} - {item.description} {/each} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Steps, useSteps } from '@ark-ui/react/steps' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const RootProvider = () => { const steps = useSteps({ count: items.length }) return (
                    current step: {steps.value + 1} {items.map((item, index) => ( {index + 1} {item.title} ))} {items.map((item, index) => ( {item.title} - {item.description} ))} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` #### Solid ```tsx import { Steps, useSteps } from '@ark-ui/solid/steps' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const RootProvider = () => { const steps = useSteps({ count: items.length }) return (
                    current step: {steps().value + 1} {(item, index) => ( {index() + 1} {item.title} )} {(item, index) => ( {item.title} - {item.description} )} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    current step: {steps().value + 1} {#each items as item, index} {index + 1} {item.title} {/each} {#each items as item, index} {item.title} - {item.description} {/each} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ``` ### Vertical Use the `orientation` prop to display the steps vertically. **Example: vertical** #### React ```tsx import { Steps } from '@ark-ui/react/steps' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Vertical = () => { return ( {items.map((item, index) => ( {index + 1} {item.title} ))} {items.map((item, index) => (
                    {item.title} - {item.description}
                    Back Next
                    ))}
                    Steps Complete - Thank you for filling out the form! Back
                    ) } ``` #### Solid ```tsx import { Steps } from '@ark-ui/solid/steps' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Vertical = () => { return ( {(item, index) => ( {index() + 1} {item.title} )} {(item, index) => (
                    {item.title} - {item.description}
                    Back Next
                    )}
                    Steps Complete - Thank you for filling out the form! Back
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item, index} {index + 1} {item.title} {/each} {#each items as item, index}
                    {item.title} - {item.description}
                    Back Next
                    {/each}
                    Steps Complete - Thank you for filling out the form! Back
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | The total number of steps | | `defaultStep` | `number` | No | The initial value of the stepper when rendered. Use when you don't need to control the value of the stepper. | | `ids` | `ElementIds` | No | The custom ids for the stepper elements | | `linear` | `boolean` | No | If `true`, the stepper requires the user to complete the steps in order | | `onStepChange` | `(details: StepChangeDetails) => void` | No | Callback to be called when the value changes | | `onStepComplete` | `VoidFunction` | No | Callback to be called when a step is completed | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the stepper | | `step` | `number` | No | The controlled value of the stepper | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | root | | `[data-orientation]` | The orientation of the steps | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--percent` | The percent value for the Root | **CompletedContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | indicator | | `[data-complete]` | Present when the indicator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | item | | `[data-orientation]` | The orientation of the item | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | list | | `[data-orientation]` | The orientation of the list | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | progress | | `[data-complete]` | Present when the progress value is complete | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseStepsReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | separator | | `[data-orientation]` | The orientation of the separator | | `[data-complete]` | Present when the separator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the trigger | | `[data-complete]` | Present when the trigger value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | The total number of steps | | `defaultStep` | `number` | No | The initial value of the stepper when rendered. Use when you don't need to control the value of the stepper. | | `ids` | `ElementIds` | No | The custom ids for the stepper elements | | `linear` | `boolean` | No | If `true`, the stepper requires the user to complete the steps in order | | `onStepChange` | `(details: StepChangeDetails) => void` | No | Callback to be called when the value changes | | `onStepComplete` | `VoidFunction` | No | Callback to be called when a step is completed | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the stepper | | `step` | `number` | No | The controlled value of the stepper | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | root | | `[data-orientation]` | The orientation of the steps | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--percent` | The percent value for the Root | **CompletedContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | indicator | | `[data-complete]` | Present when the indicator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | item | | `[data-orientation]` | The orientation of the item | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | list | | `[data-orientation]` | The orientation of the list | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | progress | | `[data-complete]` | Present when the progress value is complete | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseStepsReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | separator | | `[data-orientation]` | The orientation of the separator | | `[data-complete]` | Present when the separator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the trigger | | `[data-complete]` | Present when the trigger value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | The total number of steps | | `defaultStep` | `number` | No | The initial value of the stepper when rendered. Use when you don't need to control the value of the stepper. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `ElementIds` | No | The custom ids for the stepper elements | | `linear` | `boolean` | No | If `true`, the stepper requires the user to complete the steps in order | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the stepper | | `step` | `number` | No | The controlled value of the stepper | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | root | | `[data-orientation]` | The orientation of the steps | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--percent` | The percent value for the Root | **CompletedContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | indicator | | `[data-complete]` | Present when the indicator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | item | | `[data-orientation]` | The orientation of the item | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | list | | `[data-orientation]` | The orientation of the list | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | progress | | `[data-complete]` | Present when the progress value is complete | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `StepsApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | separator | | `[data-orientation]` | The orientation of the separator | | `[data-complete]` | Present when the separator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the trigger | | `[data-complete]` | Present when the trigger value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | The total number of steps | | `defaultStep` | `number` | No | The initial value of the stepper when rendered. Use when you don't need to control the value of the stepper. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `ElementIds` | No | The custom ids for the stepper elements | | `linear` | `boolean` | No | If `true`, the stepper requires the user to complete the steps in order | | `onStepChange` | `(details: StepChangeDetails) => void` | No | Callback to be called when the value changes | | `onStepComplete` | `VoidFunction` | No | Callback to be called when a step is completed | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the stepper | | `ref` | `Element` | No | | | `step` | `number` | No | The controlled value of the stepper | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | root | | `[data-orientation]` | The orientation of the steps | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--percent` | The percent value for the Root | **CompletedContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the content | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseStepsContext]>` | Yes | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | indicator | | `[data-complete]` | Present when the indicator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseStepsItemContext]>` | Yes | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | item | | `[data-orientation]` | The orientation of the item | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'ol'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | list | | `[data-orientation]` | The orientation of the list | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Progress Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Progress Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | progress | | `[data-complete]` | Present when the progress value is complete | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseStepsReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Separator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | separator | | `[data-orientation]` | The orientation of the separator | | `[data-complete]` | Present when the separator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the trigger | | `[data-complete]` | Present when the trigger value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `number` | The value of the stepper. | | `percent` | `number` | The percentage of the stepper. | | `count` | `number` | The total number of steps. | | `hasNextStep` | `boolean` | Whether the stepper has a next step. | | `hasPrevStep` | `boolean` | Whether the stepper has a previous step. | | `isCompleted` | `boolean` | Whether the stepper is completed. | | `setStep` | `(step: number) => void` | Function to set the value of the stepper. | | `goToNextStep` | `VoidFunction` | Function to go to the next step. | | `goToPrevStep` | `VoidFunction` | Function to go to the previous step. | | `resetStep` | `VoidFunction` | Function to go to reset the stepper. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of the item at the given index. | --- # Steps (SOLID) ## Anatomy ```tsx ``` ## Examples ### Basic Here's a basic example of the `Steps` component. ```tsx import { Steps } from '@ark-ui/solid/steps' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Basic = () => { return ( {(item, index) => ( {index() + 1} {item.title} )} {(item, index) => ( {item.title} - {item.description} )} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` ### Controlled Using the `RootProvider` component, you can control the active step by using the `step` prop and handling the `onStepChange` event. **Example: controlled** #### React ```tsx import { Steps } from '@ark-ui/react/steps' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Controlled = () => { const [step, setStep] = useState(0) return (
                    current step: {step + 1} setStep(details.step)} > {items.map((item, index) => ( {index + 1} {item.title} ))} {items.map((item, index) => ( {item.title} - {item.description} ))} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` #### Solid ```tsx import { Steps } from '@ark-ui/solid/steps' import { For, createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Controlled = () => { const [step, setStep] = createSignal(0) return (
                    current step: {step() + 1} setStep(details.step)} > {(item, index) => ( {index() + 1} {item.title} )} {(item, index) => ( {item.title} - {item.description} )} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    current step: {step + 1} {#each items as item, index} {index + 1} {item.title} {/each} {#each items as item, index} {item.title} - {item.description} {/each} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ``` ### 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. **Example: root-provider** #### React ```tsx import { Steps, useSteps } from '@ark-ui/react/steps' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const RootProvider = () => { const steps = useSteps({ count: items.length }) return (
                    current step: {steps.value + 1} {items.map((item, index) => ( {index + 1} {item.title} ))} {items.map((item, index) => ( {item.title} - {item.description} ))} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` #### Solid ```tsx import { Steps, useSteps } from '@ark-ui/solid/steps' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const RootProvider = () => { const steps = useSteps({ count: items.length }) return (
                    current step: {steps().value + 1} {(item, index) => ( {index() + 1} {item.title} )} {(item, index) => ( {item.title} - {item.description} )} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    current step: {steps().value + 1} {#each items as item, index} {index + 1} {item.title} {/each} {#each items as item, index} {item.title} - {item.description} {/each} Steps Complete - Thank you for filling out the form!
                    Back Next
                    ``` ### Vertical Use the `orientation` prop to display the steps vertically. **Example: vertical** #### React ```tsx import { Steps } from '@ark-ui/react/steps' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Vertical = () => { return ( {items.map((item, index) => ( {index + 1} {item.title} ))} {items.map((item, index) => (
                    {item.title} - {item.description}
                    Back Next
                    ))}
                    Steps Complete - Thank you for filling out the form! Back
                    ) } ``` #### Solid ```tsx import { Steps } from '@ark-ui/solid/steps' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/steps.module.css' const items = [ { value: 'first', title: 'First', description: 'Contact Info' }, { value: 'second', title: 'Second', description: 'Date & Time' }, { value: 'third', title: 'Third', description: 'Select Rooms' }, ] export const Vertical = () => { return ( {(item, index) => ( {index() + 1} {item.title} )} {(item, index) => (
                    {item.title} - {item.description}
                    Back Next
                    )}
                    Steps Complete - Thank you for filling out the form! Back
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#each items as item, index} {index + 1} {item.title} {/each} {#each items as item, index}
                    {item.title} - {item.description}
                    Back Next
                    {/each}
                    Steps Complete - Thank you for filling out the form! Back
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | The total number of steps | | `defaultStep` | `number` | No | The initial value of the stepper when rendered. Use when you don't need to control the value of the stepper. | | `ids` | `ElementIds` | No | The custom ids for the stepper elements | | `linear` | `boolean` | No | If `true`, the stepper requires the user to complete the steps in order | | `onStepChange` | `(details: StepChangeDetails) => void` | No | Callback to be called when the value changes | | `onStepComplete` | `VoidFunction` | No | Callback to be called when a step is completed | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the stepper | | `step` | `number` | No | The controlled value of the stepper | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | root | | `[data-orientation]` | The orientation of the steps | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--percent` | The percent value for the Root | **CompletedContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | indicator | | `[data-complete]` | Present when the indicator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | item | | `[data-orientation]` | The orientation of the item | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | list | | `[data-orientation]` | The orientation of the list | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | progress | | `[data-complete]` | Present when the progress value is complete | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseStepsReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | separator | | `[data-orientation]` | The orientation of the separator | | `[data-complete]` | Present when the separator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the trigger | | `[data-complete]` | Present when the trigger value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | The total number of steps | | `defaultStep` | `number` | No | The initial value of the stepper when rendered. Use when you don't need to control the value of the stepper. | | `ids` | `ElementIds` | No | The custom ids for the stepper elements | | `linear` | `boolean` | No | If `true`, the stepper requires the user to complete the steps in order | | `onStepChange` | `(details: StepChangeDetails) => void` | No | Callback to be called when the value changes | | `onStepComplete` | `VoidFunction` | No | Callback to be called when a step is completed | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the stepper | | `step` | `number` | No | The controlled value of the stepper | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | root | | `[data-orientation]` | The orientation of the steps | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--percent` | The percent value for the Root | **CompletedContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | indicator | | `[data-complete]` | Present when the indicator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | item | | `[data-orientation]` | The orientation of the item | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | list | | `[data-orientation]` | The orientation of the list | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | progress | | `[data-complete]` | Present when the progress value is complete | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseStepsReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | separator | | `[data-orientation]` | The orientation of the separator | | `[data-complete]` | Present when the separator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the trigger | | `[data-complete]` | Present when the trigger value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | The total number of steps | | `defaultStep` | `number` | No | The initial value of the stepper when rendered. Use when you don't need to control the value of the stepper. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `ElementIds` | No | The custom ids for the stepper elements | | `linear` | `boolean` | No | If `true`, the stepper requires the user to complete the steps in order | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the stepper | | `step` | `number` | No | The controlled value of the stepper | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | root | | `[data-orientation]` | The orientation of the steps | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--percent` | The percent value for the Root | **CompletedContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the content | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | indicator | | `[data-complete]` | Present when the indicator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | item | | `[data-orientation]` | The orientation of the item | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | list | | `[data-orientation]` | The orientation of the list | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Progress Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | progress | | `[data-complete]` | Present when the progress value is complete | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `StepsApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | separator | | `[data-orientation]` | The orientation of the separator | | `[data-complete]` | Present when the separator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the trigger | | `[data-complete]` | Present when the trigger value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `count` | `number` | No | The total number of steps | | `defaultStep` | `number` | No | The initial value of the stepper when rendered. Use when you don't need to control the value of the stepper. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `ElementIds` | No | The custom ids for the stepper elements | | `linear` | `boolean` | No | If `true`, the stepper requires the user to complete the steps in order | | `onStepChange` | `(details: StepChangeDetails) => void` | No | Callback to be called when the value changes | | `onStepComplete` | `VoidFunction` | No | Callback to be called when a step is completed | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the stepper | | `ref` | `Element` | No | | | `step` | `number` | No | The controlled value of the stepper | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | root | | `[data-orientation]` | The orientation of the steps | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--percent` | The percent value for the Root | **CompletedContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the content | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseStepsContext]>` | Yes | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | indicator | | `[data-complete]` | Present when the indicator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseStepsItemContext]>` | Yes | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | item | | `[data-orientation]` | The orientation of the item | **List Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'ol'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **List Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | list | | `[data-orientation]` | The orientation of the list | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Progress Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Progress Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | progress | | `[data-complete]` | Present when the progress value is complete | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseStepsReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Separator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | separator | | `[data-orientation]` | The orientation of the separator | | `[data-complete]` | Present when the separator value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | steps | | `[data-part]` | trigger | | `[data-state]` | "open" | "closed" | | `[data-orientation]` | The orientation of the trigger | | `[data-complete]` | Present when the trigger value is complete | | `[data-current]` | Present when current | | `[data-incomplete]` | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `number` | The value of the stepper. | | `percent` | `number` | The percentage of the stepper. | | `count` | `number` | The total number of steps. | | `hasNextStep` | `boolean` | Whether the stepper has a next step. | | `hasPrevStep` | `boolean` | Whether the stepper has a previous step. | | `isCompleted` | `boolean` | Whether the stepper is completed. | | `setStep` | `(step: number) => void` | Function to set the value of the stepper. | | `goToNextStep` | `VoidFunction` | Function to go to the next step. | | `goToPrevStep` | `VoidFunction` | Function to go to the previous step. | | `resetStep` | `VoidFunction` | Function to go to reset the stepper. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of the item at the given index. | --- # Switch (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Switch } from '@ark-ui/react/switch' import styles from 'styles/switch.module.css' export const Basic = () => ( Label ) ``` #### Solid ```tsx import { Switch } from '@ark-ui/solid/switch' import styles from 'styles/switch.module.css' export const Basic = () => ( Label ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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: **Example: controlled** #### React ```tsx import { Switch } from '@ark-ui/react/switch' import { useState } from 'react' import styles from 'styles/switch.module.css' export const Controlled = () => { const [checked, setChecked] = useState(false) return ( setChecked(e.checked)}> Label ) } ``` #### Solid ```tsx import { Switch } from '@ark-ui/solid/switch' import { createSignal } from 'solid-js' import styles from 'styles/switch.module.css' export const Controlled = () => { const [checked, setChecked] = createSignal(false) return ( setChecked(e.checked)}> Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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. **Example: root-provider** #### React ```tsx import { Switch, useSwitch } from '@ark-ui/react/switch' import button from 'styles/button.module.css' import styles from 'styles/switch.module.css' export const RootProvider = () => { const _switch = useSwitch() return (
                    Label
                    ) } ``` #### Solid ```tsx import { Switch, useSwitch } from '@ark-ui/solid/switch' import button from 'styles/button.module.css' import styles from 'styles/switch.module.css' export const RootProvider = () => { const _switch = useSwitch() return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Switch } from '@ark-ui/react/switch' import field from 'styles/field.module.css' import styles from 'styles/switch.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Switch } from '@ark-ui/solid/switch' import field from 'styles/field.module.css' import styles from 'styles/switch.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Additional Info Error Info ``` ### Context The Switch component allows access to its internal state through the `Context` component. This enables you to dynamically adjust and customize aspects of the component based on its current state: **Example: context** #### React ```tsx import { Switch } from '@ark-ui/react/switch' import styles from 'styles/switch.module.css' export const Context = () => ( {(context) => ( Feature is {context.checked ? 'enabled' : 'disabled'} )} ) ``` #### Solid ```tsx import { Switch } from '@ark-ui/solid/switch' import styles from 'styles/switch.module.css' export const Context = () => ( {(context) => ( Feature is {context().checked ? 'enabled' : 'disabled'} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(context)} Feature is {context().checked ? 'enabled' : 'disabled'} {/snippet} ``` ## Guides ### asChild The `Switch.Root` element of the switch is a `label` element. This is because the switch is a form control and should be associated with a label to provide context and meaning to the user. Otherwise, the HTML and accessibility structure will be invalid. > If you need to use the `asChild` property, make sure that the `label` element is the direct child of the `Switch.Root` > component. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `boolean` | No | The controlled checked state of the switch | | `disabled` | `boolean` | No | Whether the switch is disabled. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>` | No | The ids of the elements in the switch. Useful for composition. | | `invalid` | `boolean` | No | If `true`, the switch is marked as invalid. | | `label` | `string` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `name` | `string` | No | The name of the input field in a switch (Useful for form submission). | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Function to call when the switch is clicked. | | `readOnly` | `boolean` | No | Whether the switch is read-only | | `required` | `boolean` | No | If `true`, the switch input is marked as required, | | `value` | `string | number` | No | The value of switch input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSwitchReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `boolean` | No | The controlled checked state of the switch | | `defaultChecked` | `boolean` | No | The initial checked state of the switch when rendered. Use when you don't need to control the checked state of the switch. | | `disabled` | `boolean` | No | Whether the switch is disabled. | | `form` | `string` | No | The id of the form that the switch belongs to | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>` | No | The ids of the elements in the switch. Useful for composition. | | `invalid` | `boolean` | No | If `true`, the switch is marked as invalid. | | `label` | `string` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `name` | `string` | No | The name of the input field in a switch (Useful for form submission). | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Function to call when the switch is clicked. | | `readOnly` | `boolean` | No | Whether the switch is read-only | | `required` | `boolean` | No | If `true`, the switch input is marked as required, | | `value` | `string | number` | No | The value of switch input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSwitchReturn` | Yes | | | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `boolean` | No | The controlled checked state of the switch | | `defaultChecked` | `boolean` | No | The initial checked state of the switch when rendered. Use when you don't need to control the checked state of the switch. | | `disabled` | `boolean` | No | Whether the switch is disabled. | | `form` | `string` | No | The id of the form that the switch belongs to | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>` | No | The ids of the elements in the switch. Useful for composition. | | `invalid` | `boolean` | No | If `true`, the switch is marked as invalid. | | `label` | `string` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `name` | `string` | No | The name of the input field in a switch (Useful for form submission). | | `readOnly` | `boolean` | No | Whether the switch is read-only | | `required` | `boolean` | No | If `true`, the switch input is marked as required, | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SwitchApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `boolean` | No | The controlled checked state of the switch | | `defaultChecked` | `boolean` | No | The initial checked state of the switch when rendered. Use when you don't need to control the checked state of the switch. | | `disabled` | `boolean` | No | Whether the switch is disabled. | | `form` | `string` | No | The id of the form that the switch belongs to | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>` | No | The ids of the elements in the switch. Useful for composition. | | `invalid` | `boolean` | No | If `true`, the switch is marked as invalid. | | `label` | `string` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `name` | `string` | No | The name of the input field in a switch (Useful for form submission). | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Function to call when the switch is clicked. | | `readOnly` | `boolean` | No | Whether the switch is read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | If `true`, the switch input is marked as required, | | `value` | `string | number` | No | The value of switch input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSwitchContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSwitchReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `checked` | `boolean` | Whether the switch is checked | | `disabled` | `boolean` | Whether the switch is disabled | | `focused` | `boolean` | Whether the switch is focused | | `setChecked` | `(checked: boolean) => void` | Sets the checked state of the switch. | | `toggleChecked` | `VoidFunction` | Toggles the checked state of the switch. | ## Accessibility Complies with the [Switch WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/switch/). ### Keyboard Support **`Space + Enter`** Description: Toggle the switch --- # Switch (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Switch } from '@ark-ui/react/switch' import styles from 'styles/switch.module.css' export const Basic = () => ( Label ) ``` #### Solid ```tsx import { Switch } from '@ark-ui/solid/switch' import styles from 'styles/switch.module.css' export const Basic = () => ( Label ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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: **Example: controlled** #### React ```tsx import { Switch } from '@ark-ui/react/switch' import { useState } from 'react' import styles from 'styles/switch.module.css' export const Controlled = () => { const [checked, setChecked] = useState(false) return ( setChecked(e.checked)}> Label ) } ``` #### Solid ```tsx import { Switch } from '@ark-ui/solid/switch' import { createSignal } from 'solid-js' import styles from 'styles/switch.module.css' export const Controlled = () => { const [checked, setChecked] = createSignal(false) return ( setChecked(e.checked)}> Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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. **Example: root-provider** #### React ```tsx import { Switch, useSwitch } from '@ark-ui/react/switch' import button from 'styles/button.module.css' import styles from 'styles/switch.module.css' export const RootProvider = () => { const _switch = useSwitch() return (
                    Label
                    ) } ``` #### Solid ```tsx import { Switch, useSwitch } from '@ark-ui/solid/switch' import button from 'styles/button.module.css' import styles from 'styles/switch.module.css' export const RootProvider = () => { const _switch = useSwitch() return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Switch } from '@ark-ui/react/switch' import field from 'styles/field.module.css' import styles from 'styles/switch.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Switch } from '@ark-ui/solid/switch' import field from 'styles/field.module.css' import styles from 'styles/switch.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Additional Info Error Info ``` ### Context The Switch component allows access to its internal state through the `Context` component. This enables you to dynamically adjust and customize aspects of the component based on its current state: **Example: context** #### React ```tsx import { Switch } from '@ark-ui/react/switch' import styles from 'styles/switch.module.css' export const Context = () => ( {(context) => ( Feature is {context.checked ? 'enabled' : 'disabled'} )} ) ``` #### Solid ```tsx import { Switch } from '@ark-ui/solid/switch' import styles from 'styles/switch.module.css' export const Context = () => ( {(context) => ( Feature is {context().checked ? 'enabled' : 'disabled'} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(context)} Feature is {context().checked ? 'enabled' : 'disabled'} {/snippet} ``` ## Guides ### asChild The `Switch.Root` element of the switch is a `label` element. This is because the switch is a form control and should be associated with a label to provide context and meaning to the user. Otherwise, the HTML and accessibility structure will be invalid. > If you need to use the `asChild` property, make sure that the `label` element is the direct child of the `Switch.Root` > component. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `boolean` | No | The controlled checked state of the switch | | `disabled` | `boolean` | No | Whether the switch is disabled. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>` | No | The ids of the elements in the switch. Useful for composition. | | `invalid` | `boolean` | No | If `true`, the switch is marked as invalid. | | `label` | `string` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `name` | `string` | No | The name of the input field in a switch (Useful for form submission). | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Function to call when the switch is clicked. | | `readOnly` | `boolean` | No | Whether the switch is read-only | | `required` | `boolean` | No | If `true`, the switch input is marked as required, | | `value` | `string | number` | No | The value of switch input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSwitchReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `boolean` | No | The controlled checked state of the switch | | `defaultChecked` | `boolean` | No | The initial checked state of the switch when rendered. Use when you don't need to control the checked state of the switch. | | `disabled` | `boolean` | No | Whether the switch is disabled. | | `form` | `string` | No | The id of the form that the switch belongs to | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>` | No | The ids of the elements in the switch. Useful for composition. | | `invalid` | `boolean` | No | If `true`, the switch is marked as invalid. | | `label` | `string` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `name` | `string` | No | The name of the input field in a switch (Useful for form submission). | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Function to call when the switch is clicked. | | `readOnly` | `boolean` | No | Whether the switch is read-only | | `required` | `boolean` | No | If `true`, the switch input is marked as required, | | `value` | `string | number` | No | The value of switch input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSwitchReturn` | Yes | | | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `boolean` | No | The controlled checked state of the switch | | `defaultChecked` | `boolean` | No | The initial checked state of the switch when rendered. Use when you don't need to control the checked state of the switch. | | `disabled` | `boolean` | No | Whether the switch is disabled. | | `form` | `string` | No | The id of the form that the switch belongs to | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>` | No | The ids of the elements in the switch. Useful for composition. | | `invalid` | `boolean` | No | If `true`, the switch is marked as invalid. | | `label` | `string` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `name` | `string` | No | The name of the input field in a switch (Useful for form submission). | | `readOnly` | `boolean` | No | Whether the switch is read-only | | `required` | `boolean` | No | If `true`, the switch input is marked as required, | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SwitchApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `boolean` | No | The controlled checked state of the switch | | `defaultChecked` | `boolean` | No | The initial checked state of the switch when rendered. Use when you don't need to control the checked state of the switch. | | `disabled` | `boolean` | No | Whether the switch is disabled. | | `form` | `string` | No | The id of the form that the switch belongs to | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>` | No | The ids of the elements in the switch. Useful for composition. | | `invalid` | `boolean` | No | If `true`, the switch is marked as invalid. | | `label` | `string` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `name` | `string` | No | The name of the input field in a switch (Useful for form submission). | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Function to call when the switch is clicked. | | `readOnly` | `boolean` | No | Whether the switch is read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | If `true`, the switch input is marked as required, | | `value` | `string | number` | No | The value of switch input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSwitchContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSwitchReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `checked` | `boolean` | Whether the switch is checked | | `disabled` | `boolean` | Whether the switch is disabled | | `focused` | `boolean` | Whether the switch is focused | | `setChecked` | `(checked: boolean) => void` | Sets the checked state of the switch. | | `toggleChecked` | `VoidFunction` | Toggles the checked state of the switch. | ## Accessibility Complies with the [Switch WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/switch/). ### Keyboard Support **`Space + Enter`** Description: Toggle the switch --- # Switch (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Switch } from '@ark-ui/react/switch' import styles from 'styles/switch.module.css' export const Basic = () => ( Label ) ``` #### Solid ```tsx import { Switch } from '@ark-ui/solid/switch' import styles from 'styles/switch.module.css' export const Basic = () => ( Label ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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: **Example: controlled** #### React ```tsx import { Switch } from '@ark-ui/react/switch' import { useState } from 'react' import styles from 'styles/switch.module.css' export const Controlled = () => { const [checked, setChecked] = useState(false) return ( setChecked(e.checked)}> Label ) } ``` #### Solid ```tsx import { Switch } from '@ark-ui/solid/switch' import { createSignal } from 'solid-js' import styles from 'styles/switch.module.css' export const Controlled = () => { const [checked, setChecked] = createSignal(false) return ( setChecked(e.checked)}> Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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. **Example: root-provider** #### React ```tsx import { Switch, useSwitch } from '@ark-ui/react/switch' import button from 'styles/button.module.css' import styles from 'styles/switch.module.css' export const RootProvider = () => { const _switch = useSwitch() return (
                    Label
                    ) } ``` #### Solid ```tsx import { Switch, useSwitch } from '@ark-ui/solid/switch' import button from 'styles/button.module.css' import styles from 'styles/switch.module.css' export const RootProvider = () => { const _switch = useSwitch() return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Switch } from '@ark-ui/react/switch' import field from 'styles/field.module.css' import styles from 'styles/switch.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Switch } from '@ark-ui/solid/switch' import field from 'styles/field.module.css' import styles from 'styles/switch.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Additional Info Error Info ``` ### Context The Switch component allows access to its internal state through the `Context` component. This enables you to dynamically adjust and customize aspects of the component based on its current state: **Example: context** #### React ```tsx import { Switch } from '@ark-ui/react/switch' import styles from 'styles/switch.module.css' export const Context = () => ( {(context) => ( Feature is {context.checked ? 'enabled' : 'disabled'} )} ) ``` #### Solid ```tsx import { Switch } from '@ark-ui/solid/switch' import styles from 'styles/switch.module.css' export const Context = () => ( {(context) => ( Feature is {context().checked ? 'enabled' : 'disabled'} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(context)} Feature is {context().checked ? 'enabled' : 'disabled'} {/snippet} ``` ## Guides ### asChild The `Switch.Root` element of the switch is a `label` element. This is because the switch is a form control and should be associated with a label to provide context and meaning to the user. Otherwise, the HTML and accessibility structure will be invalid. > If you need to use the `asChild` property, make sure that the `label` element is the direct child of the `Switch.Root` > component. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `boolean` | No | The controlled checked state of the switch | | `disabled` | `boolean` | No | Whether the switch is disabled. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>` | No | The ids of the elements in the switch. Useful for composition. | | `invalid` | `boolean` | No | If `true`, the switch is marked as invalid. | | `label` | `string` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `name` | `string` | No | The name of the input field in a switch (Useful for form submission). | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Function to call when the switch is clicked. | | `readOnly` | `boolean` | No | Whether the switch is read-only | | `required` | `boolean` | No | If `true`, the switch input is marked as required, | | `value` | `string | number` | No | The value of switch input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSwitchReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `boolean` | No | The controlled checked state of the switch | | `defaultChecked` | `boolean` | No | The initial checked state of the switch when rendered. Use when you don't need to control the checked state of the switch. | | `disabled` | `boolean` | No | Whether the switch is disabled. | | `form` | `string` | No | The id of the form that the switch belongs to | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>` | No | The ids of the elements in the switch. Useful for composition. | | `invalid` | `boolean` | No | If `true`, the switch is marked as invalid. | | `label` | `string` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `name` | `string` | No | The name of the input field in a switch (Useful for form submission). | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Function to call when the switch is clicked. | | `readOnly` | `boolean` | No | Whether the switch is read-only | | `required` | `boolean` | No | If `true`, the switch input is marked as required, | | `value` | `string | number` | No | The value of switch input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSwitchReturn` | Yes | | | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `boolean` | No | The controlled checked state of the switch | | `defaultChecked` | `boolean` | No | The initial checked state of the switch when rendered. Use when you don't need to control the checked state of the switch. | | `disabled` | `boolean` | No | Whether the switch is disabled. | | `form` | `string` | No | The id of the form that the switch belongs to | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>` | No | The ids of the elements in the switch. Useful for composition. | | `invalid` | `boolean` | No | If `true`, the switch is marked as invalid. | | `label` | `string` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `name` | `string` | No | The name of the input field in a switch (Useful for form submission). | | `readOnly` | `boolean` | No | Whether the switch is read-only | | `required` | `boolean` | No | If `true`, the switch input is marked as required, | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SwitchApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `boolean` | No | The controlled checked state of the switch | | `defaultChecked` | `boolean` | No | The initial checked state of the switch when rendered. Use when you don't need to control the checked state of the switch. | | `disabled` | `boolean` | No | Whether the switch is disabled. | | `form` | `string` | No | The id of the form that the switch belongs to | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>` | No | The ids of the elements in the switch. Useful for composition. | | `invalid` | `boolean` | No | If `true`, the switch is marked as invalid. | | `label` | `string` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `name` | `string` | No | The name of the input field in a switch (Useful for form submission). | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Function to call when the switch is clicked. | | `readOnly` | `boolean` | No | Whether the switch is read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | If `true`, the switch input is marked as required, | | `value` | `string | number` | No | The value of switch input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSwitchContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSwitchReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `checked` | `boolean` | Whether the switch is checked | | `disabled` | `boolean` | Whether the switch is disabled | | `focused` | `boolean` | Whether the switch is focused | | `setChecked` | `(checked: boolean) => void` | Sets the checked state of the switch. | | `toggleChecked` | `VoidFunction` | Toggles the checked state of the switch. | ## Accessibility Complies with the [Switch WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/switch/). ### Keyboard Support **`Space + Enter`** Description: Toggle the switch --- # Switch (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Switch } from '@ark-ui/react/switch' import styles from 'styles/switch.module.css' export const Basic = () => ( Label ) ``` #### Solid ```tsx import { Switch } from '@ark-ui/solid/switch' import styles from 'styles/switch.module.css' export const Basic = () => ( Label ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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: **Example: controlled** #### React ```tsx import { Switch } from '@ark-ui/react/switch' import { useState } from 'react' import styles from 'styles/switch.module.css' export const Controlled = () => { const [checked, setChecked] = useState(false) return ( setChecked(e.checked)}> Label ) } ``` #### Solid ```tsx import { Switch } from '@ark-ui/solid/switch' import { createSignal } from 'solid-js' import styles from 'styles/switch.module.css' export const Controlled = () => { const [checked, setChecked] = createSignal(false) return ( setChecked(e.checked)}> Label ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Label ``` ### 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. **Example: root-provider** #### React ```tsx import { Switch, useSwitch } from '@ark-ui/react/switch' import button from 'styles/button.module.css' import styles from 'styles/switch.module.css' export const RootProvider = () => { const _switch = useSwitch() return (
                    Label
                    ) } ``` #### Solid ```tsx import { Switch, useSwitch } from '@ark-ui/solid/switch' import button from 'styles/button.module.css' import styles from 'styles/switch.module.css' export const RootProvider = () => { const _switch = useSwitch() return (
                    Label
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Label
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { Switch } from '@ark-ui/react/switch' import field from 'styles/field.module.css' import styles from 'styles/switch.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { Switch } from '@ark-ui/solid/switch' import field from 'styles/field.module.css' import styles from 'styles/switch.module.css' export const WithField = () => ( Label Additional Info Error Info ) ``` #### Vue ```vue ``` #### Svelte ```svelte Label Additional Info Error Info ``` ### Context The Switch component allows access to its internal state through the `Context` component. This enables you to dynamically adjust and customize aspects of the component based on its current state: **Example: context** #### React ```tsx import { Switch } from '@ark-ui/react/switch' import styles from 'styles/switch.module.css' export const Context = () => ( {(context) => ( Feature is {context.checked ? 'enabled' : 'disabled'} )} ) ``` #### Solid ```tsx import { Switch } from '@ark-ui/solid/switch' import styles from 'styles/switch.module.css' export const Context = () => ( {(context) => ( Feature is {context().checked ? 'enabled' : 'disabled'} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(context)} Feature is {context().checked ? 'enabled' : 'disabled'} {/snippet} ``` ## Guides ### asChild The `Switch.Root` element of the switch is a `label` element. This is because the switch is a form control and should be associated with a label to provide context and meaning to the user. Otherwise, the HTML and accessibility structure will be invalid. > If you need to use the `asChild` property, make sure that the `label` element is the direct child of the `Switch.Root` > component. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `boolean` | No | The controlled checked state of the switch | | `disabled` | `boolean` | No | Whether the switch is disabled. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>` | No | The ids of the elements in the switch. Useful for composition. | | `invalid` | `boolean` | No | If `true`, the switch is marked as invalid. | | `label` | `string` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `name` | `string` | No | The name of the input field in a switch (Useful for form submission). | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Function to call when the switch is clicked. | | `readOnly` | `boolean` | No | Whether the switch is read-only | | `required` | `boolean` | No | If `true`, the switch input is marked as required, | | `value` | `string | number` | No | The value of switch input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSwitchReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `boolean` | No | The controlled checked state of the switch | | `defaultChecked` | `boolean` | No | The initial checked state of the switch when rendered. Use when you don't need to control the checked state of the switch. | | `disabled` | `boolean` | No | Whether the switch is disabled. | | `form` | `string` | No | The id of the form that the switch belongs to | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>` | No | The ids of the elements in the switch. Useful for composition. | | `invalid` | `boolean` | No | If `true`, the switch is marked as invalid. | | `label` | `string` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `name` | `string` | No | The name of the input field in a switch (Useful for form submission). | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Function to call when the switch is clicked. | | `readOnly` | `boolean` | No | Whether the switch is read-only | | `required` | `boolean` | No | If `true`, the switch input is marked as required, | | `value` | `string | number` | No | The value of switch input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSwitchReturn` | Yes | | | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `boolean` | No | The controlled checked state of the switch | | `defaultChecked` | `boolean` | No | The initial checked state of the switch when rendered. Use when you don't need to control the checked state of the switch. | | `disabled` | `boolean` | No | Whether the switch is disabled. | | `form` | `string` | No | The id of the form that the switch belongs to | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>` | No | The ids of the elements in the switch. Useful for composition. | | `invalid` | `boolean` | No | If `true`, the switch is marked as invalid. | | `label` | `string` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `name` | `string` | No | The name of the input field in a switch (Useful for form submission). | | `readOnly` | `boolean` | No | Whether the switch is read-only | | `required` | `boolean` | No | If `true`, the switch input is marked as required, | | `value` | `string` | No | The value of checkbox input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `SwitchApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `checked` | `boolean` | No | The controlled checked state of the switch | | `defaultChecked` | `boolean` | No | The initial checked state of the switch when rendered. Use when you don't need to control the checked state of the switch. | | `disabled` | `boolean` | No | Whether the switch is disabled. | | `form` | `string` | No | The id of the form that the switch belongs to | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>` | No | The ids of the elements in the switch. Useful for composition. | | `invalid` | `boolean` | No | If `true`, the switch is marked as invalid. | | `label` | `string` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `name` | `string` | No | The name of the input field in a switch (Useful for form submission). | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Function to call when the switch is clicked. | | `readOnly` | `boolean` | No | Whether the switch is read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | If `true`, the switch input is marked as required, | | `value` | `string | number` | No | The value of switch input. Useful for form submission. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseSwitchContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseSwitchReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Thumb Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Thumb Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-active]` | Present when active or pressed | | `[data-focus]` | Present when focused | | `[data-focus-visible]` | Present when focused with keyboard | | `[data-readonly]` | Present when read-only | | `[data-hover]` | Present when hovered | | `[data-disabled]` | Present when disabled | | `[data-state]` | "checked" | "unchecked" | | `[data-invalid]` | Present when invalid | | `[data-required]` | Present when required | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `checked` | `boolean` | Whether the switch is checked | | `disabled` | `boolean` | Whether the switch is disabled | | `focused` | `boolean` | Whether the switch is focused | | `setChecked` | `(checked: boolean) => void` | Sets the checked state of the switch. | | `toggleChecked` | `VoidFunction` | Toggles the checked state of the switch. | ## Accessibility Complies with the [Switch WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/switch/). ### Keyboard Support **`Space + Enter`** Description: Toggle the switch --- # Tabs (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const Basic = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const Basic = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### 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: **Example: controlled** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import { useState } from 'react' import styles from 'styles/tabs.module.css' export const Controlled = () => { const [value, setValue] = useState('account') return ( setValue(e.value)}> Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) } ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import { createSignal } from 'solid-js' import styles from 'styles/tabs.module.css' export const Controlled = () => { const [value, setValue] = createSignal('account') return ( setValue(e.value)}> Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### 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. **Example: root-provider** #### React ```tsx import { Tabs, useTabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const RootProvider = () => { const tabs = useTabs({ defaultValue: 'account' }) return (
                    selected: {tabs.value} Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details.
                    ) } ``` #### Solid ```tsx import { Tabs, useTabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const RootProvider = () => { const tabs = useTabs({ defaultValue: 'account' }) return (
                    selected: {tabs().value} Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    selected: {tabs().value} Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details.
                    ``` ### Indicator To provide a visual cue for the selected tab, use the `Tabs.Indicator` component: **Example: indicator** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const Indicator = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const Indicator = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Disabled To disable a tab, simply pass the `disabled` prop to the `Tabs.Trigger` component: **Example: disabled-tab** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const DisabledTab = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const DisabledTab = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Vertical The default orientation of the tabs is `horizontal`. To change the orientation, set the `orientation` prop to `vertical`. **Example: vertical** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const Vertical = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const Vertical = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Lazy Mount Lazy mounting is a feature that allows the content of a tab to be rendered only when the tab is first activated. This is useful for performance optimization, especially when tab content is large or complex. To enable lazy mounting, use the `lazyMount` prop on the `Tabs.Content` component. In addition, the `unmountOnExit` prop can be used in conjunction with `lazyMount` to unmount the tab content when the tab is deactivated, freeing up resources. The next time the tab is activated, its content will be re-rendered. **Example: lazy-mount** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const LazyMount = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const LazyMount = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Manual Activation By default, the tab can be selected when it receives focus from either the keyboard or pointer interaction. This is called automatic tab activation. In contrast, manual tab activation means the tab is selected with the Enter key or by clicking on the tab. **Example: manual-activation** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const ManualActivation = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const ManualActivation = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Links Use the `asChild` prop to render tab triggers as anchor links. This is useful for SEO and allows tabs to work with browser navigation. **Example: links** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const Links = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` ## Guides ### Router Integration When using frameworks like Next.js, Remix, or React Router, controlling the active tabs based on the URL can be useful. To achieve this, you need to do two things: - Set the `value` prop to the current URL path. - Listen to the `onValueChange` event and update the URL path. Here's an example using Remix Router ```tsx import { Tabs } from '@ark-ui//tabs' import { useLocation, useNavigate, Link } from '@remix-run/react' export default function App() { const { pathname } = useLocation() const navigate = useNavigate() const lastPathFragment = pathname.substring(pathname.lastIndexOf('/') + 1) const activeTab = lastPathFragment.length > 0 ? lastPathFragment : 'homepage' return ( { navigate(`/${value === 'home' ? '' : value}`) }} > Home Page 1 Page 2 ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic` - `manual`: Tabs are activated when clicked or press `enter` key. - `automatic`: Tabs are activated when receiving focus | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `composite` | `boolean` | No | Whether the tab is composite | | `defaultValue` | `string` | No | The initial selected tab value when rendered. Use when you don't need to control the selected tab value. | | `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string trigger: (value: string) => string list: string content: (value: string) => string indicator: string }>` | No | The ids of the elements in the tabs. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it. Useful if tab triggers are anchor elements. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Callback to be called when the focused tab changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback to be called when the selected/active tab changes | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical` - `horizontal`: only left and right arrow key navigation will work. - `vertical`: only up and down arrow key navigation will work. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string` | No | The controlled selected tab value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tabs | | `[data-part]` | root | | `[data-orientation]` | The orientation of the tabs | | `[data-focus]` | Present when focused | **TabContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabList Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the tab is disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTabsReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic` - `manual`: Tabs are activated when clicked or press `enter` key. - `automatic`: Tabs are activated when receiving focus | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `composite` | `boolean` | No | Whether the tab is composite | | `defaultValue` | `string` | No | The initial selected tab value when rendered. Use when you don't need to control the selected tab value. | | `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. | | `ids` | `Partial<{ root: string trigger: (value: string) => string list: string content: (value: string) => string indicator: string }>` | No | The ids of the elements in the tabs. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it. Useful if tab triggers are anchor elements. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Callback to be called when the focused tab changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback to be called when the selected/active tab changes | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical` - `horizontal`: only left and right arrow key navigation will work. - `vertical`: only up and down arrow key navigation will work. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string` | No | The controlled selected tab value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tabs | | `[data-part]` | root | | `[data-orientation]` | The orientation of the tabs | | `[data-focus]` | Present when focused | **TabContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabList Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the tab is disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTabsReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic` - `manual`: Tabs are activated when clicked or press `enter` key. - `automatic`: Tabs are activated when receiving focus | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `composite` | `boolean` | No | Whether the tab is composite | | `defaultValue` | `string` | No | The initial selected tab value when rendered. Use when you don't need to control the selected tab value. | | `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string trigger: (id: string) => string content: (id: string) => string list: string indicator: string }>` | No | The ids of the elements in the tabs. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. | | `modelValue` | `string` | No | The v-model value of the tabs | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it. Useful if tab triggers are anchor elements. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical` - `horizontal`: only left and right arrow key navigation will work. - `vertical`: only up and down arrow key navigation will work. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tabs | | `[data-part]` | root | | `[data-orientation]` | The orientation of the tabs | | `[data-focus]` | Present when focused | **TabContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabList Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the tab is disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TabsApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic` - `manual`: Tabs are activated when clicked or press `enter` key. - `automatic`: Tabs are activated when receiving focus | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `composite` | `boolean` | No | Whether the tab is composite | | `defaultValue` | `string` | No | The initial selected tab value when rendered. Use when you don't need to control the selected tab value. | | `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string trigger: (value: string) => string list: string content: (value: string) => string indicator: string }>` | No | The ids of the elements in the tabs. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it. Useful if tab triggers are anchor elements. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Callback to be called when the focused tab changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback to be called when the selected/active tab changes | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical` - `horizontal`: only left and right arrow key navigation will work. - `vertical`: only up and down arrow key navigation will work. | | `ref` | `Element` | No | | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string` | No | The controlled selected tab value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tabs | | `[data-part]` | root | | `[data-orientation]` | The orientation of the tabs | | `[data-focus]` | Present when focused | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTabsContext]>` | Yes | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTabsReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string` | The current value of the tabs. | | `focusedValue` | `string` | The value of the tab that is currently focused. | | `setValue` | `(value: string) => void` | Sets the value of the tabs. | | `clearValue` | `VoidFunction` | Clears the value of the tabs. | | `setIndicatorRect` | `(value: string) => void` | Sets the indicator rect to the tab with the given value | | `syncTabIndex` | `VoidFunction` | Synchronizes the tab index of the content element. Useful when rendering tabs within a select or combobox | | `focus` | `VoidFunction` | Set focus on the selected tab trigger | | `selectNext` | `(fromValue?: string) => void` | Selects the next tab | | `selectPrev` | `(fromValue?: string) => void` | Selects the previous tab | | `getTriggerState` | `(props: TriggerProps) => TriggerState` | Returns the state of the trigger with the given props | ## Accessibility Complies with the [Tabs WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/). ### Keyboard Support **`Tab`** Description: When focus moves onto the tabs, focuses the active trigger. When a trigger is focused, moves focus to the active content. **`ArrowDown`** Description: Moves focus to the next trigger in vertical orientation and activates its associated content. **`ArrowRight`** Description: Moves focus to the next trigger in horizontal orientation and activates its associated content. **`ArrowUp`** Description: Moves focus to the previous trigger in vertical orientation and activates its associated content. **`ArrowLeft`** Description: Moves focus to the previous trigger in horizontal orientation and activates its associated content. **`Home`** Description: Moves focus to the first trigger and activates its associated content. **`End`** Description: Moves focus to the last trigger and activates its associated content. **`Enter + Space`** Description: In manual mode, when a trigger is focused, moves focus to its associated content. --- # Tabs (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const Basic = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const Basic = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### 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: **Example: controlled** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import { useState } from 'react' import styles from 'styles/tabs.module.css' export const Controlled = () => { const [value, setValue] = useState('account') return ( setValue(e.value)}> Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) } ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import { createSignal } from 'solid-js' import styles from 'styles/tabs.module.css' export const Controlled = () => { const [value, setValue] = createSignal('account') return ( setValue(e.value)}> Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### 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. **Example: root-provider** #### React ```tsx import { Tabs, useTabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const RootProvider = () => { const tabs = useTabs({ defaultValue: 'account' }) return (
                    selected: {tabs.value} Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details.
                    ) } ``` #### Solid ```tsx import { Tabs, useTabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const RootProvider = () => { const tabs = useTabs({ defaultValue: 'account' }) return (
                    selected: {tabs().value} Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    selected: {tabs().value} Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details.
                    ``` ### Indicator To provide a visual cue for the selected tab, use the `Tabs.Indicator` component: **Example: indicator** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const Indicator = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const Indicator = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Disabled To disable a tab, simply pass the `disabled` prop to the `Tabs.Trigger` component: **Example: disabled-tab** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const DisabledTab = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const DisabledTab = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Vertical The default orientation of the tabs is `horizontal`. To change the orientation, set the `orientation` prop to `vertical`. **Example: vertical** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const Vertical = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const Vertical = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Lazy Mount Lazy mounting is a feature that allows the content of a tab to be rendered only when the tab is first activated. This is useful for performance optimization, especially when tab content is large or complex. To enable lazy mounting, use the `lazyMount` prop on the `Tabs.Content` component. In addition, the `unmountOnExit` prop can be used in conjunction with `lazyMount` to unmount the tab content when the tab is deactivated, freeing up resources. The next time the tab is activated, its content will be re-rendered. **Example: lazy-mount** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const LazyMount = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const LazyMount = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Manual Activation By default, the tab can be selected when it receives focus from either the keyboard or pointer interaction. This is called automatic tab activation. In contrast, manual tab activation means the tab is selected with the Enter key or by clicking on the tab. **Example: manual-activation** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const ManualActivation = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const ManualActivation = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Links Use the `asChild` prop to render tab triggers as anchor links. This is useful for SEO and allows tabs to work with browser navigation. **Example: links** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const Links = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` ## Guides ### Router Integration When using frameworks like Next.js, Remix, or React Router, controlling the active tabs based on the URL can be useful. To achieve this, you need to do two things: - Set the `value` prop to the current URL path. - Listen to the `onValueChange` event and update the URL path. Here's an example using Remix Router ```tsx import { Tabs } from '@ark-ui//tabs' import { useLocation, useNavigate, Link } from '@remix-run/react' export default function App() { const { pathname } = useLocation() const navigate = useNavigate() const lastPathFragment = pathname.substring(pathname.lastIndexOf('/') + 1) const activeTab = lastPathFragment.length > 0 ? lastPathFragment : 'homepage' return ( { navigate(`/${value === 'home' ? '' : value}`) }} > Home Page 1 Page 2 ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic` - `manual`: Tabs are activated when clicked or press `enter` key. - `automatic`: Tabs are activated when receiving focus | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `composite` | `boolean` | No | Whether the tab is composite | | `defaultValue` | `string` | No | The initial selected tab value when rendered. Use when you don't need to control the selected tab value. | | `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string trigger: (value: string) => string list: string content: (value: string) => string indicator: string }>` | No | The ids of the elements in the tabs. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it. Useful if tab triggers are anchor elements. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Callback to be called when the focused tab changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback to be called when the selected/active tab changes | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical` - `horizontal`: only left and right arrow key navigation will work. - `vertical`: only up and down arrow key navigation will work. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string` | No | The controlled selected tab value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tabs | | `[data-part]` | root | | `[data-orientation]` | The orientation of the tabs | | `[data-focus]` | Present when focused | **TabContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabList Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the tab is disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTabsReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic` - `manual`: Tabs are activated when clicked or press `enter` key. - `automatic`: Tabs are activated when receiving focus | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `composite` | `boolean` | No | Whether the tab is composite | | `defaultValue` | `string` | No | The initial selected tab value when rendered. Use when you don't need to control the selected tab value. | | `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. | | `ids` | `Partial<{ root: string trigger: (value: string) => string list: string content: (value: string) => string indicator: string }>` | No | The ids of the elements in the tabs. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it. Useful if tab triggers are anchor elements. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Callback to be called when the focused tab changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback to be called when the selected/active tab changes | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical` - `horizontal`: only left and right arrow key navigation will work. - `vertical`: only up and down arrow key navigation will work. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string` | No | The controlled selected tab value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tabs | | `[data-part]` | root | | `[data-orientation]` | The orientation of the tabs | | `[data-focus]` | Present when focused | **TabContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabList Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the tab is disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTabsReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic` - `manual`: Tabs are activated when clicked or press `enter` key. - `automatic`: Tabs are activated when receiving focus | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `composite` | `boolean` | No | Whether the tab is composite | | `defaultValue` | `string` | No | The initial selected tab value when rendered. Use when you don't need to control the selected tab value. | | `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string trigger: (id: string) => string content: (id: string) => string list: string indicator: string }>` | No | The ids of the elements in the tabs. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. | | `modelValue` | `string` | No | The v-model value of the tabs | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it. Useful if tab triggers are anchor elements. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical` - `horizontal`: only left and right arrow key navigation will work. - `vertical`: only up and down arrow key navigation will work. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tabs | | `[data-part]` | root | | `[data-orientation]` | The orientation of the tabs | | `[data-focus]` | Present when focused | **TabContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabList Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the tab is disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TabsApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic` - `manual`: Tabs are activated when clicked or press `enter` key. - `automatic`: Tabs are activated when receiving focus | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `composite` | `boolean` | No | Whether the tab is composite | | `defaultValue` | `string` | No | The initial selected tab value when rendered. Use when you don't need to control the selected tab value. | | `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string trigger: (value: string) => string list: string content: (value: string) => string indicator: string }>` | No | The ids of the elements in the tabs. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it. Useful if tab triggers are anchor elements. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Callback to be called when the focused tab changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback to be called when the selected/active tab changes | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical` - `horizontal`: only left and right arrow key navigation will work. - `vertical`: only up and down arrow key navigation will work. | | `ref` | `Element` | No | | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string` | No | The controlled selected tab value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tabs | | `[data-part]` | root | | `[data-orientation]` | The orientation of the tabs | | `[data-focus]` | Present when focused | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTabsContext]>` | Yes | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTabsReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string` | The current value of the tabs. | | `focusedValue` | `string` | The value of the tab that is currently focused. | | `setValue` | `(value: string) => void` | Sets the value of the tabs. | | `clearValue` | `VoidFunction` | Clears the value of the tabs. | | `setIndicatorRect` | `(value: string) => void` | Sets the indicator rect to the tab with the given value | | `syncTabIndex` | `VoidFunction` | Synchronizes the tab index of the content element. Useful when rendering tabs within a select or combobox | | `focus` | `VoidFunction` | Set focus on the selected tab trigger | | `selectNext` | `(fromValue?: string) => void` | Selects the next tab | | `selectPrev` | `(fromValue?: string) => void` | Selects the previous tab | | `getTriggerState` | `(props: TriggerProps) => TriggerState` | Returns the state of the trigger with the given props | ## Accessibility Complies with the [Tabs WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/). ### Keyboard Support **`Tab`** Description: When focus moves onto the tabs, focuses the active trigger. When a trigger is focused, moves focus to the active content. **`ArrowDown`** Description: Moves focus to the next trigger in vertical orientation and activates its associated content. **`ArrowRight`** Description: Moves focus to the next trigger in horizontal orientation and activates its associated content. **`ArrowUp`** Description: Moves focus to the previous trigger in vertical orientation and activates its associated content. **`ArrowLeft`** Description: Moves focus to the previous trigger in horizontal orientation and activates its associated content. **`Home`** Description: Moves focus to the first trigger and activates its associated content. **`End`** Description: Moves focus to the last trigger and activates its associated content. **`Enter + Space`** Description: In manual mode, when a trigger is focused, moves focus to its associated content. --- # Tabs (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const Basic = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const Basic = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### 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: **Example: controlled** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import { useState } from 'react' import styles from 'styles/tabs.module.css' export const Controlled = () => { const [value, setValue] = useState('account') return ( setValue(e.value)}> Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) } ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import { createSignal } from 'solid-js' import styles from 'styles/tabs.module.css' export const Controlled = () => { const [value, setValue] = createSignal('account') return ( setValue(e.value)}> Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### 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. **Example: root-provider** #### React ```tsx import { Tabs, useTabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const RootProvider = () => { const tabs = useTabs({ defaultValue: 'account' }) return (
                    selected: {tabs.value} Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details.
                    ) } ``` #### Solid ```tsx import { Tabs, useTabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const RootProvider = () => { const tabs = useTabs({ defaultValue: 'account' }) return (
                    selected: {tabs().value} Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    selected: {tabs().value} Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details.
                    ``` ### Indicator To provide a visual cue for the selected tab, use the `Tabs.Indicator` component: **Example: indicator** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const Indicator = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const Indicator = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Disabled To disable a tab, simply pass the `disabled` prop to the `Tabs.Trigger` component: **Example: disabled-tab** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const DisabledTab = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const DisabledTab = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Vertical The default orientation of the tabs is `horizontal`. To change the orientation, set the `orientation` prop to `vertical`. **Example: vertical** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const Vertical = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const Vertical = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Lazy Mount Lazy mounting is a feature that allows the content of a tab to be rendered only when the tab is first activated. This is useful for performance optimization, especially when tab content is large or complex. To enable lazy mounting, use the `lazyMount` prop on the `Tabs.Content` component. In addition, the `unmountOnExit` prop can be used in conjunction with `lazyMount` to unmount the tab content when the tab is deactivated, freeing up resources. The next time the tab is activated, its content will be re-rendered. **Example: lazy-mount** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const LazyMount = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const LazyMount = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Manual Activation By default, the tab can be selected when it receives focus from either the keyboard or pointer interaction. This is called automatic tab activation. In contrast, manual tab activation means the tab is selected with the Enter key or by clicking on the tab. **Example: manual-activation** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const ManualActivation = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const ManualActivation = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Links Use the `asChild` prop to render tab triggers as anchor links. This is useful for SEO and allows tabs to work with browser navigation. **Example: links** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const Links = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` ## Guides ### Router Integration When using frameworks like Next.js, Remix, or React Router, controlling the active tabs based on the URL can be useful. To achieve this, you need to do two things: - Set the `value` prop to the current URL path. - Listen to the `onValueChange` event and update the URL path. Here's an example using Remix Router ```tsx import { Tabs } from '@ark-ui//tabs' import { useLocation, useNavigate, Link } from '@remix-run/react' export default function App() { const { pathname } = useLocation() const navigate = useNavigate() const lastPathFragment = pathname.substring(pathname.lastIndexOf('/') + 1) const activeTab = lastPathFragment.length > 0 ? lastPathFragment : 'homepage' return ( { navigate(`/${value === 'home' ? '' : value}`) }} > Home Page 1 Page 2 ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic` - `manual`: Tabs are activated when clicked or press `enter` key. - `automatic`: Tabs are activated when receiving focus | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `composite` | `boolean` | No | Whether the tab is composite | | `defaultValue` | `string` | No | The initial selected tab value when rendered. Use when you don't need to control the selected tab value. | | `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string trigger: (value: string) => string list: string content: (value: string) => string indicator: string }>` | No | The ids of the elements in the tabs. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it. Useful if tab triggers are anchor elements. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Callback to be called when the focused tab changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback to be called when the selected/active tab changes | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical` - `horizontal`: only left and right arrow key navigation will work. - `vertical`: only up and down arrow key navigation will work. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string` | No | The controlled selected tab value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tabs | | `[data-part]` | root | | `[data-orientation]` | The orientation of the tabs | | `[data-focus]` | Present when focused | **TabContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabList Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the tab is disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTabsReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic` - `manual`: Tabs are activated when clicked or press `enter` key. - `automatic`: Tabs are activated when receiving focus | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `composite` | `boolean` | No | Whether the tab is composite | | `defaultValue` | `string` | No | The initial selected tab value when rendered. Use when you don't need to control the selected tab value. | | `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. | | `ids` | `Partial<{ root: string trigger: (value: string) => string list: string content: (value: string) => string indicator: string }>` | No | The ids of the elements in the tabs. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it. Useful if tab triggers are anchor elements. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Callback to be called when the focused tab changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback to be called when the selected/active tab changes | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical` - `horizontal`: only left and right arrow key navigation will work. - `vertical`: only up and down arrow key navigation will work. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string` | No | The controlled selected tab value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tabs | | `[data-part]` | root | | `[data-orientation]` | The orientation of the tabs | | `[data-focus]` | Present when focused | **TabContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabList Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the tab is disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTabsReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic` - `manual`: Tabs are activated when clicked or press `enter` key. - `automatic`: Tabs are activated when receiving focus | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `composite` | `boolean` | No | Whether the tab is composite | | `defaultValue` | `string` | No | The initial selected tab value when rendered. Use when you don't need to control the selected tab value. | | `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string trigger: (id: string) => string content: (id: string) => string list: string indicator: string }>` | No | The ids of the elements in the tabs. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. | | `modelValue` | `string` | No | The v-model value of the tabs | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it. Useful if tab triggers are anchor elements. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical` - `horizontal`: only left and right arrow key navigation will work. - `vertical`: only up and down arrow key navigation will work. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tabs | | `[data-part]` | root | | `[data-orientation]` | The orientation of the tabs | | `[data-focus]` | Present when focused | **TabContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabList Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the tab is disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TabsApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic` - `manual`: Tabs are activated when clicked or press `enter` key. - `automatic`: Tabs are activated when receiving focus | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `composite` | `boolean` | No | Whether the tab is composite | | `defaultValue` | `string` | No | The initial selected tab value when rendered. Use when you don't need to control the selected tab value. | | `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string trigger: (value: string) => string list: string content: (value: string) => string indicator: string }>` | No | The ids of the elements in the tabs. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it. Useful if tab triggers are anchor elements. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Callback to be called when the focused tab changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback to be called when the selected/active tab changes | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical` - `horizontal`: only left and right arrow key navigation will work. - `vertical`: only up and down arrow key navigation will work. | | `ref` | `Element` | No | | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string` | No | The controlled selected tab value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tabs | | `[data-part]` | root | | `[data-orientation]` | The orientation of the tabs | | `[data-focus]` | Present when focused | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTabsContext]>` | Yes | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTabsReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string` | The current value of the tabs. | | `focusedValue` | `string` | The value of the tab that is currently focused. | | `setValue` | `(value: string) => void` | Sets the value of the tabs. | | `clearValue` | `VoidFunction` | Clears the value of the tabs. | | `setIndicatorRect` | `(value: string) => void` | Sets the indicator rect to the tab with the given value | | `syncTabIndex` | `VoidFunction` | Synchronizes the tab index of the content element. Useful when rendering tabs within a select or combobox | | `focus` | `VoidFunction` | Set focus on the selected tab trigger | | `selectNext` | `(fromValue?: string) => void` | Selects the next tab | | `selectPrev` | `(fromValue?: string) => void` | Selects the previous tab | | `getTriggerState` | `(props: TriggerProps) => TriggerState` | Returns the state of the trigger with the given props | ## Accessibility Complies with the [Tabs WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/). ### Keyboard Support **`Tab`** Description: When focus moves onto the tabs, focuses the active trigger. When a trigger is focused, moves focus to the active content. **`ArrowDown`** Description: Moves focus to the next trigger in vertical orientation and activates its associated content. **`ArrowRight`** Description: Moves focus to the next trigger in horizontal orientation and activates its associated content. **`ArrowUp`** Description: Moves focus to the previous trigger in vertical orientation and activates its associated content. **`ArrowLeft`** Description: Moves focus to the previous trigger in horizontal orientation and activates its associated content. **`Home`** Description: Moves focus to the first trigger and activates its associated content. **`End`** Description: Moves focus to the last trigger and activates its associated content. **`Enter + Space`** Description: In manual mode, when a trigger is focused, moves focus to its associated content. --- # Tabs (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const Basic = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const Basic = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### 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: **Example: controlled** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import { useState } from 'react' import styles from 'styles/tabs.module.css' export const Controlled = () => { const [value, setValue] = useState('account') return ( setValue(e.value)}> Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) } ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import { createSignal } from 'solid-js' import styles from 'styles/tabs.module.css' export const Controlled = () => { const [value, setValue] = createSignal('account') return ( setValue(e.value)}> Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### 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. **Example: root-provider** #### React ```tsx import { Tabs, useTabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const RootProvider = () => { const tabs = useTabs({ defaultValue: 'account' }) return (
                    selected: {tabs.value} Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details.
                    ) } ``` #### Solid ```tsx import { Tabs, useTabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const RootProvider = () => { const tabs = useTabs({ defaultValue: 'account' }) return (
                    selected: {tabs().value} Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details.
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    selected: {tabs().value} Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details.
                    ``` ### Indicator To provide a visual cue for the selected tab, use the `Tabs.Indicator` component: **Example: indicator** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const Indicator = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const Indicator = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Disabled To disable a tab, simply pass the `disabled` prop to the `Tabs.Trigger` component: **Example: disabled-tab** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const DisabledTab = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const DisabledTab = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Vertical The default orientation of the tabs is `horizontal`. To change the orientation, set the `orientation` prop to `vertical`. **Example: vertical** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const Vertical = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const Vertical = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Lazy Mount Lazy mounting is a feature that allows the content of a tab to be rendered only when the tab is first activated. This is useful for performance optimization, especially when tab content is large or complex. To enable lazy mounting, use the `lazyMount` prop on the `Tabs.Content` component. In addition, the `unmountOnExit` prop can be used in conjunction with `lazyMount` to unmount the tab content when the tab is deactivated, freeing up resources. The next time the tab is activated, its content will be re-rendered. **Example: lazy-mount** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const LazyMount = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const LazyMount = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Manual Activation By default, the tab can be selected when it receives focus from either the keyboard or pointer interaction. This is called automatic tab activation. In contrast, manual tab activation means the tab is selected with the Enter key or by clicking on the tab. **Example: manual-activation** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const ManualActivation = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Solid ```tsx import { Tabs } from '@ark-ui/solid/tabs' import styles from 'styles/tabs.module.css' export const ManualActivation = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` #### Vue ```vue ``` #### Svelte ```svelte Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ``` ### Links Use the `asChild` prop to render tab triggers as anchor links. This is useful for SEO and allows tabs to work with browser navigation. **Example: links** #### React ```tsx import { Tabs } from '@ark-ui/react/tabs' import styles from 'styles/tabs.module.css' export const Links = () => ( Account Password Billing Make changes to your account here. Change your password here. Manage your billing and payment details. ) ``` ## Guides ### Router Integration When using frameworks like Next.js, Remix, or React Router, controlling the active tabs based on the URL can be useful. To achieve this, you need to do two things: - Set the `value` prop to the current URL path. - Listen to the `onValueChange` event and update the URL path. Here's an example using Remix Router ```tsx import { Tabs } from '@ark-ui//tabs' import { useLocation, useNavigate, Link } from '@remix-run/react' export default function App() { const { pathname } = useLocation() const navigate = useNavigate() const lastPathFragment = pathname.substring(pathname.lastIndexOf('/') + 1) const activeTab = lastPathFragment.length > 0 ? lastPathFragment : 'homepage' return ( { navigate(`/${value === 'home' ? '' : value}`) }} > Home Page 1 Page 2 ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic` - `manual`: Tabs are activated when clicked or press `enter` key. - `automatic`: Tabs are activated when receiving focus | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `composite` | `boolean` | No | Whether the tab is composite | | `defaultValue` | `string` | No | The initial selected tab value when rendered. Use when you don't need to control the selected tab value. | | `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string trigger: (value: string) => string list: string content: (value: string) => string indicator: string }>` | No | The ids of the elements in the tabs. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it. Useful if tab triggers are anchor elements. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Callback to be called when the focused tab changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback to be called when the selected/active tab changes | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical` - `horizontal`: only left and right arrow key navigation will work. - `vertical`: only up and down arrow key navigation will work. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string` | No | The controlled selected tab value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tabs | | `[data-part]` | root | | `[data-orientation]` | The orientation of the tabs | | `[data-focus]` | Present when focused | **TabContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabList Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the tab is disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTabsReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic` - `manual`: Tabs are activated when clicked or press `enter` key. - `automatic`: Tabs are activated when receiving focus | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `composite` | `boolean` | No | Whether the tab is composite | | `defaultValue` | `string` | No | The initial selected tab value when rendered. Use when you don't need to control the selected tab value. | | `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. | | `ids` | `Partial<{ root: string trigger: (value: string) => string list: string content: (value: string) => string indicator: string }>` | No | The ids of the elements in the tabs. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it. Useful if tab triggers are anchor elements. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Callback to be called when the focused tab changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback to be called when the selected/active tab changes | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical` - `horizontal`: only left and right arrow key navigation will work. - `vertical`: only up and down arrow key navigation will work. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string` | No | The controlled selected tab value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tabs | | `[data-part]` | root | | `[data-orientation]` | The orientation of the tabs | | `[data-focus]` | Present when focused | **TabContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabList Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the tab is disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTabsReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic` - `manual`: Tabs are activated when clicked or press `enter` key. - `automatic`: Tabs are activated when receiving focus | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `composite` | `boolean` | No | Whether the tab is composite | | `defaultValue` | `string` | No | The initial selected tab value when rendered. Use when you don't need to control the selected tab value. | | `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string trigger: (id: string) => string content: (id: string) => string list: string indicator: string }>` | No | The ids of the elements in the tabs. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. | | `modelValue` | `string` | No | The v-model value of the tabs | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it. Useful if tab triggers are anchor elements. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical` - `horizontal`: only left and right arrow key navigation will work. - `vertical`: only up and down arrow key navigation will work. | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tabs | | `[data-part]` | root | | `[data-orientation]` | The orientation of the tabs | | `[data-focus]` | Present when focused | **TabContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabList Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **TabTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the tab | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the tab is disabled | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TabsApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `activationMode` | `'manual' | 'automatic'` | No | The activation mode of the tabs. Can be `manual` or `automatic` - `manual`: Tabs are activated when clicked or press `enter` key. - `automatic`: Tabs are activated when receiving focus | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `composite` | `boolean` | No | Whether the tab is composite | | `defaultValue` | `string` | No | The initial selected tab value when rendered. Use when you don't need to control the selected tab value. | | `deselectable` | `boolean` | No | Whether the active tab can be deselected when clicking on it. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string trigger: (value: string) => string list: string content: (value: string) => string indicator: string }>` | No | The ids of the elements in the tabs. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loopFocus` | `boolean` | No | Whether the keyboard navigation will loop from last tab to first, and vice versa. | | `navigate` | `(details: NavigateDetails) => void` | No | Function to navigate to the selected tab when clicking on it. Useful if tab triggers are anchor elements. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Callback to be called when the focused tab changes | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback to be called when the selected/active tab changes | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the tabs. Can be `horizontal` or `vertical` - `horizontal`: only left and right arrow key navigation will work. - `vertical`: only up and down arrow key navigation will work. | | `ref` | `Element` | No | | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string` | No | The controlled selected tab value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tabs | | `[data-part]` | root | | `[data-orientation]` | The orientation of the tabs | | `[data-focus]` | Present when focused | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTabsContext]>` | Yes | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTabsReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string` | The current value of the tabs. | | `focusedValue` | `string` | The value of the tab that is currently focused. | | `setValue` | `(value: string) => void` | Sets the value of the tabs. | | `clearValue` | `VoidFunction` | Clears the value of the tabs. | | `setIndicatorRect` | `(value: string) => void` | Sets the indicator rect to the tab with the given value | | `syncTabIndex` | `VoidFunction` | Synchronizes the tab index of the content element. Useful when rendering tabs within a select or combobox | | `focus` | `VoidFunction` | Set focus on the selected tab trigger | | `selectNext` | `(fromValue?: string) => void` | Selects the next tab | | `selectPrev` | `(fromValue?: string) => void` | Selects the previous tab | | `getTriggerState` | `(props: TriggerProps) => TriggerState` | Returns the state of the trigger with the given props | ## Accessibility Complies with the [Tabs WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/). ### Keyboard Support **`Tab`** Description: When focus moves onto the tabs, focuses the active trigger. When a trigger is focused, moves focus to the active content. **`ArrowDown`** Description: Moves focus to the next trigger in vertical orientation and activates its associated content. **`ArrowRight`** Description: Moves focus to the next trigger in horizontal orientation and activates its associated content. **`ArrowUp`** Description: Moves focus to the previous trigger in vertical orientation and activates its associated content. **`ArrowLeft`** Description: Moves focus to the previous trigger in horizontal orientation and activates its associated content. **`Home`** Description: Moves focus to the first trigger and activates its associated content. **`End`** Description: Moves focus to the last trigger and activates its associated content. **`Enter + Space`** Description: In manual mode, when a trigger is focused, moves focus to its associated content. --- # Tags Input (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const Basic = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Basic = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: controlled** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tags-input.module.css' export const Controlled = () => { const [value, setValue] = useState(['React', 'Solid']) return ( setValue(details.value)}> {(api) => ( <> Frameworks {api.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Controlled = () => { const [value, setValue] = createSignal(['vue', 'react']) return ( setValue(details.value)} class={styles.Root}> {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: controlled-input-value** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/tags-input.module.css' export const ControlledInputValue = () => { const [inputValue, setInputValue] = useState('') return (
                    Current: "{inputValue}"
                    setInputValue(details.inputValue)} > {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )}
                    ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/tags-input.module.css' export const ControlledInputValue = () => { const [inputValue, setInputValue] = createSignal('') return ( setInputValue(details.inputValue)} class={styles.Root} > {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: root-provider** #### React ```tsx import { TagsInput, useTagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const RootProvider = () => { const tagsInput = useTagsInput() return (
                    {(api) => ( <> Frameworks {api.value.map((value, index) => ( {value} ))} )} values: {JSON.stringify(tagsInput.value)}
                    ) } ``` #### Solid ```tsx import { TagsInput, useTagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tags-input.module.css' export const RootProvider = () => { const tagsInput = useTagsInput() return (
                    {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet render(api)} Frameworks {#each api().value as value, index (index)} {value} {/each} {/snippet} values: {JSON.stringify(tagsInput().value)}
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/tags-input.module.css' export const WithField = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} Additional Info Error Info ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/tags-input.module.css' export const WithField = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} Additional Info Error Info ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} Additional Info Error Info ``` ### 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`. When the tag reaches the limit, new tags cannot be added except the `allowOverflow` prop is set to `true`. **Example: max-with-overflow** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const MaxWithOverflow = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const MaxWithOverflow = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: delimiter** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' const DELIMITER_PATTERN = /[,;\s]/ export const Delimiter = () => { return ( {(tagsInput) => ( <> Frameworks (add with comma, semicolon, or space) {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Delimiter = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Disabled Use the `disabled` prop to make the tags input non-interactive. Users won't be able to add, remove, or edit tags. **Example: disabled** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const Disabled = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Disabled = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Invalid Use the `invalid` prop to mark the tags input as invalid for form validation purposes. **Example: invalid** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const Invalid = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Invalid = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Max Length Use the `maxLength` prop to limit the number of characters allowed per tag. This prevents users from creating overly long tags. **Example: max-tag-length** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const MaxTagLength = () => { return ( {(tagsInput) => ( <> Frameworks (Max 10 characters) {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const MaxTagLength = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Read-only Use the `readOnly` prop to make tags visible but not editable. Users can view tags but cannot add, remove, or modify them. **Example: readonly** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const Readonly = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Readonly = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Validation Before a tag is added, the `validate` function is called to determine whether to accept or reject a tag. A common use-case for validating tags is preventing duplicates or validating the data type. **Example: validation** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' const TAG_PATTERN = /^[a-zA-Z0-9-]+$/ const validateTag = ({ value, inputValue }: { value: string[]; inputValue: string }) => !!inputValue?.trim() && !value.includes(inputValue) && inputValue.length >= 3 && TAG_PATTERN.test(inputValue) export const Validation = () => { return ( {(tagsInput) => ( <> Frameworks (Min 3 chars, alphanumeric) {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Validation = () => { return ( { return !details.value.includes(details.inputValue) }} class={styles.Root} > {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte { return !details.value.includes(details.inputValue) }} class={styles.Root} > {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: blur-behavior** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const BlurBehavior = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const BlurBehavior = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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 **Example: paste-behavior** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const PasteBehavior = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const PasteBehavior = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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}` **Example: disabled-editing** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const DisabledEditing = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const DisabledEditing = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Programmatic Control Use the `useTagsInput` hook with `RootProvider` to access the component's API methods like `addValue()`, `setValue()`, and `clearValue()` for full programmatic control. **Example: programmatic-control** #### React ```tsx import { TagsInput, useTagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tags-input.module.css' export const ProgrammaticControl = () => { const tagsInput = useTagsInput() return (
                    {(api) => ( <> Frameworks {api.value.map((value, index) => ( {value} ))} )}
                    ) } ``` #### Solid ```tsx import { TagsInput, useTagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tags-input.module.css' export const ProgrammaticControl = () => { const tagsInput = useTagsInput() return (
                    {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet render(api)} Frameworks {#each api().value as value, index (index)} {value} {/each} {/snippet}
                    ``` ### Combobox Combine TagsInput with Combobox to create an autocomplete tags input. This pattern uses shared IDs between both components and the `asChild` prop to compose the inputs together. **Example: with-combobox** #### React ```tsx import { Combobox, useCombobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { TagsInput, useTagsInput } from '@ark-ui/react/tags-input' import { CheckIcon, XIcon } from 'lucide-react' import { useId } from 'react' import combobox from 'styles/combobox.module.css' import styles from 'styles/tags-input.module.css' export const WithCombobox = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Preact', 'Next.js', 'Astro', 'Nuxt'], filter: contains, }) const uid = useId() const tagsInput = useTagsInput({ ids: { input: `input_${uid}`, control: `control_${uid}` }, }) const comboboxApi = useCombobox({ ids: { input: `input_${uid}`, control: `control_${uid}` }, collection, onInputValueChange(details) { filter(details.inputValue) }, value: [], allowCustomValue: true, onValueChange: (details) => { if (details.value[0]) { tagsInput.addValue(details.value[0]) } }, selectionBehavior: 'clear', }) return ( Frameworks {tagsInput.value.map((value, index) => ( {value} ))} No frameworks found {collection.items.map((item) => ( {item} ))} ) } ``` #### Solid ```tsx import { Combobox, useCombobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { TagsInput, useTagsInput } from '@ark-ui/solid/tags-input' import { CheckIcon, XIcon } from 'lucide-solid' import { For, createUniqueId } from 'solid-js' import { Portal } from 'solid-js/web' import combobox from 'styles/combobox.module.css' import styles from 'styles/tags-input.module.css' export const WithCombobox = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Preact', 'Next.js', 'Astro', 'Nuxt'], filter: filterFn().contains, }) const uid = createUniqueId() const tagsInput = useTagsInput({ ids: { input: `input_${uid}`, control: `control_${uid}` }, }) const comboboxApi = useCombobox({ ids: { input: `input_${uid}`, control: `control_${uid}` }, collection: collection(), onInputValueChange(details) { filter(details.inputValue) }, value: [], allowCustomValue: true, onValueChange: (details) => { if (details.value[0]) { tagsInput().addValue(details.value[0]) } }, selectionBehavior: 'clear', }) return ( Frameworks {(value, index) => ( {value} )} } /> No frameworks found {(item) => ( {item} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {#snippet asChild(inputProps)} {/snippet} No frameworks found {#each collection().items as item (item)} {item} {/each} ``` ## Guides ### Navigation When the input has an empty value or the caret is at the start position, the tags can be selected by using the arrow left and arrow right keys. When "visual" focus in on any tag: - Pressing Enter or double-clicking on the tag will put it in edit mode, allowing the user change its value and press Enter to commit the changes. - Pressing Delete or Backspace will delete the tag that has _visual_ focus. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `addOnPaste` | `boolean` | No | Whether to add a tag when you paste values into the tag input | | `allowOverflow` | `boolean` | No | Whether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether the input should be auto-focused | | `blurBehavior` | `'clear' | 'add'` | No | The behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value | | `defaultInputValue` | `string` | No | The initial tag input value when rendered. Use when you don't need to control the tag input value. | | `defaultValue` | `string[]` | No | The initial tag value when rendered. Use when you don't need to control the tag value. | | `delimiter` | `string | RegExp` | No | The character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input | | `disabled` | `boolean` | No | Whether the tags input should be disabled | | `editable` | `boolean` | No | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string input: string hiddenInput: string clearBtn: string label: string control: string item: (opts: ItemProps) => string itemDeleteTrigger: (opts: ItemProps) => string itemInput: (opts: ItemProps) => string }>` | No | The ids of the elements in the tags input. Useful for composition. | | `inputValue` | `string` | No | The controlled tag input's value | | `invalid` | `boolean` | No | Whether the tags input is invalid | | `max` | `number` | No | The max number of tags | | `maxLength` | `number` | No | The max length of the input. | | `name` | `string` | No | The name attribute for the input. Useful for form submissions | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Callback fired when a tag is highlighted by pointer or keyboard navigation | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Callback fired when the input value is updated | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the tag values is updated | | `onValueInvalid` | `(details: ValidityChangeDetails) => void` | No | Callback fired when the max tag count is reached or the `validateTag` function returns `false` | | `readOnly` | `boolean` | No | Whether the tags input should be read-only | | `required` | `boolean` | No | Whether the tags input is required | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `validate` | `(details: ValidateArgs) => boolean` | No | Returns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. | | `value` | `string[]` | No | The controlled tag value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-empty]` | Present when the content is empty | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | clear-trigger | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-empty]` | Present when the content is empty | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **ItemInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-preview | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `string | number` | Yes | | | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTagsInputReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `addOnPaste` | `boolean` | No | Whether to add a tag when you paste values into the tag input | | `allowOverflow` | `boolean` | No | Whether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether the input should be auto-focused | | `blurBehavior` | `'clear' | 'add'` | No | The behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value | | `defaultInputValue` | `string` | No | The initial tag input value when rendered. Use when you don't need to control the tag input value. | | `defaultValue` | `string[]` | No | The initial tag value when rendered. Use when you don't need to control the tag value. | | `delimiter` | `string | RegExp` | No | The character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input | | `disabled` | `boolean` | No | Whether the tags input should be disabled | | `editable` | `boolean` | No | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. | | `form` | `string` | No | The associate form of the underlying input element. | | `ids` | `Partial<{ root: string input: string hiddenInput: string clearBtn: string label: string control: string item: (opts: ItemProps) => string itemDeleteTrigger: (opts: ItemProps) => string itemInput: (opts: ItemProps) => string }>` | No | The ids of the elements in the tags input. Useful for composition. | | `inputValue` | `string` | No | The controlled tag input's value | | `invalid` | `boolean` | No | Whether the tags input is invalid | | `max` | `number` | No | The max number of tags | | `maxLength` | `number` | No | The max length of the input. | | `name` | `string` | No | The name attribute for the input. Useful for form submissions | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Callback fired when a tag is highlighted by pointer or keyboard navigation | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Callback fired when the input value is updated | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the tag values is updated | | `onValueInvalid` | `(details: ValidityChangeDetails) => void` | No | Callback fired when the max tag count is reached or the `validateTag` function returns `false` | | `readOnly` | `boolean` | No | Whether the tags input should be read-only | | `required` | `boolean` | No | Whether the tags input is required | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `validate` | `(details: ValidateArgs) => boolean` | No | Returns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. | | `value` | `string[]` | No | The controlled tag value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-empty]` | Present when the content is empty | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | clear-trigger | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-empty]` | Present when the content is empty | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **ItemInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-preview | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `string | number` | Yes | | | `value` | `string` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTagsInputReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `addOnPaste` | `boolean` | No | Whether to add a tag when you paste values into the tag input | | `allowOverflow` | `boolean` | No | Whether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether the input should be auto-focused | | `blurBehavior` | `'clear' | 'add'` | No | The behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value | | `defaultInputValue` | `string` | No | The initial tag input value when rendered. Use when you don't need to control the tag input value. | | `defaultValue` | `string[]` | No | The initial tag value when rendered. Use when you don't need to control the tag value. | | `delimiter` | `string | RegExp` | No | The character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input | | `disabled` | `boolean` | No | Whether the tags input should be disabled | | `editable` | `boolean` | No | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string input: string hiddenInput: string clearBtn: string label: string control: string item(opts: ItemProps): string itemDeleteTrigger(opts: ItemProps): string itemInput(opts: ItemProps): string }>` | No | The ids of the elements in the tags input. Useful for composition. | | `inputValue` | `string` | No | The controlled tag input's value | | `invalid` | `boolean` | No | Whether the tags input is invalid | | `max` | `number` | No | The max number of tags | | `maxLength` | `number` | No | The max length of the input. | | `modelValue` | `string[]` | No | The v-model value of the tags input | | `name` | `string` | No | The name attribute for the input. Useful for form submissions | | `readOnly` | `boolean` | No | Whether the tags input should be read-only | | `required` | `boolean` | No | Whether the tags input is required | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `validate` | `(details: ValidateArgs) => boolean` | No | Returns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-empty]` | Present when the content is empty | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | clear-trigger | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-empty]` | Present when the content is empty | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **ItemInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-preview | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `string | number` | Yes | | | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TagsInputApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `addOnPaste` | `boolean` | No | Whether to add a tag when you paste values into the tag input | | `allowOverflow` | `boolean` | No | Whether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether the input should be auto-focused | | `blurBehavior` | `'clear' | 'add'` | No | The behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value | | `defaultInputValue` | `string` | No | The initial tag input value when rendered. Use when you don't need to control the tag input value. | | `defaultValue` | `string[]` | No | The initial tag value when rendered. Use when you don't need to control the tag value. | | `delimiter` | `string | RegExp` | No | The character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input | | `disabled` | `boolean` | No | Whether the tags input should be disabled | | `editable` | `boolean` | No | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string input: string hiddenInput: string clearBtn: string label: string control: string item: (opts: ItemProps) => string itemDeleteTrigger: (opts: ItemProps) => string itemInput: (opts: ItemProps) => string }>` | No | The ids of the elements in the tags input. Useful for composition. | | `inputValue` | `string` | No | The controlled tag input's value | | `invalid` | `boolean` | No | Whether the tags input is invalid | | `max` | `number` | No | The max number of tags | | `maxLength` | `number` | No | The max length of the input. | | `name` | `string` | No | The name attribute for the input. Useful for form submissions | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Callback fired when a tag is highlighted by pointer or keyboard navigation | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Callback fired when the input value is updated | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the tag values is updated | | `onValueInvalid` | `(details: ValidityChangeDetails) => void` | No | Callback fired when the max tag count is reached or the `validateTag` function returns `false` | | `readOnly` | `boolean` | No | Whether the tags input should be read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the tags input is required | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `validate` | `(details: ValidateArgs) => boolean` | No | Returns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. | | `value` | `string[]` | No | The controlled tag value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-empty]` | Present when the content is empty | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | clear-trigger | | `[data-readonly]` | Present when read-only | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTagsInputReturn]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-empty]` | Present when the content is empty | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTagsInputItemContext]>` | Yes | | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **ItemInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-preview | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `value` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTagsInputReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `empty` | `boolean` | Whether the tags are empty | | `inputValue` | `string` | The value of the tags entry input. | | `value` | `string[]` | The value of the tags as an array of strings. | | `valueAsString` | `string` | The value of the tags as a string. | | `count` | `number` | The number of the tags. | | `atMax` | `boolean` | Whether the tags have reached the max limit. | | `setValue` | `(value: string[]) => void` | Function to set the value of the tags. | | `clearValue` | `(id?: string) => void` | Function to clear the value of the tags. | | `addValue` | `(value: string) => void` | Function to add a tag to the tags. | | `setValueAtIndex` | `(index: number, value: string) => void` | Function to set the value of a tag at the given index. | | `setInputValue` | `(value: string) => void` | Function to set the value of the tags entry input. | | `clearInputValue` | `VoidFunction` | Function to clear the value of the tags entry input. | | `focus` | `VoidFunction` | Function to focus the tags entry input. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a tag | ## Accessibility ### Keyboard Support **`ArrowLeft`** Description: Moves focus to the previous tag item **`ArrowRight`** Description: Moves focus to the next tag item **`Backspace`** Description: Deletes the tag item that has visual focus or the last tag item **`Enter`** Description: When a tag item has visual focus, it puts the tag in edit mode.
                    When the input has focus, it adds the value to the list of tags
                    **`Delete`** Description: Deletes the tag item that has visual focus **`Control + V`** Description: When `addOnPaste` is set. Adds the pasted value as a tags --- # Tags Input (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const Basic = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Basic = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: controlled** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tags-input.module.css' export const Controlled = () => { const [value, setValue] = useState(['React', 'Solid']) return ( setValue(details.value)}> {(api) => ( <> Frameworks {api.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Controlled = () => { const [value, setValue] = createSignal(['vue', 'react']) return ( setValue(details.value)} class={styles.Root}> {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: controlled-input-value** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/tags-input.module.css' export const ControlledInputValue = () => { const [inputValue, setInputValue] = useState('') return (
                    Current: "{inputValue}"
                    setInputValue(details.inputValue)} > {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )}
                    ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/tags-input.module.css' export const ControlledInputValue = () => { const [inputValue, setInputValue] = createSignal('') return ( setInputValue(details.inputValue)} class={styles.Root} > {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: root-provider** #### React ```tsx import { TagsInput, useTagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const RootProvider = () => { const tagsInput = useTagsInput() return (
                    {(api) => ( <> Frameworks {api.value.map((value, index) => ( {value} ))} )} values: {JSON.stringify(tagsInput.value)}
                    ) } ``` #### Solid ```tsx import { TagsInput, useTagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tags-input.module.css' export const RootProvider = () => { const tagsInput = useTagsInput() return (
                    {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet render(api)} Frameworks {#each api().value as value, index (index)} {value} {/each} {/snippet} values: {JSON.stringify(tagsInput().value)}
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/tags-input.module.css' export const WithField = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} Additional Info Error Info ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/tags-input.module.css' export const WithField = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} Additional Info Error Info ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} Additional Info Error Info ``` ### 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`. When the tag reaches the limit, new tags cannot be added except the `allowOverflow` prop is set to `true`. **Example: max-with-overflow** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const MaxWithOverflow = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const MaxWithOverflow = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: delimiter** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' const DELIMITER_PATTERN = /[,;\s]/ export const Delimiter = () => { return ( {(tagsInput) => ( <> Frameworks (add with comma, semicolon, or space) {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Delimiter = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Disabled Use the `disabled` prop to make the tags input non-interactive. Users won't be able to add, remove, or edit tags. **Example: disabled** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const Disabled = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Disabled = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Invalid Use the `invalid` prop to mark the tags input as invalid for form validation purposes. **Example: invalid** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const Invalid = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Invalid = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Max Length Use the `maxLength` prop to limit the number of characters allowed per tag. This prevents users from creating overly long tags. **Example: max-tag-length** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const MaxTagLength = () => { return ( {(tagsInput) => ( <> Frameworks (Max 10 characters) {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const MaxTagLength = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Read-only Use the `readOnly` prop to make tags visible but not editable. Users can view tags but cannot add, remove, or modify them. **Example: readonly** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const Readonly = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Readonly = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Validation Before a tag is added, the `validate` function is called to determine whether to accept or reject a tag. A common use-case for validating tags is preventing duplicates or validating the data type. **Example: validation** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' const TAG_PATTERN = /^[a-zA-Z0-9-]+$/ const validateTag = ({ value, inputValue }: { value: string[]; inputValue: string }) => !!inputValue?.trim() && !value.includes(inputValue) && inputValue.length >= 3 && TAG_PATTERN.test(inputValue) export const Validation = () => { return ( {(tagsInput) => ( <> Frameworks (Min 3 chars, alphanumeric) {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Validation = () => { return ( { return !details.value.includes(details.inputValue) }} class={styles.Root} > {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte { return !details.value.includes(details.inputValue) }} class={styles.Root} > {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: blur-behavior** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const BlurBehavior = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const BlurBehavior = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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 **Example: paste-behavior** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const PasteBehavior = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const PasteBehavior = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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}` **Example: disabled-editing** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const DisabledEditing = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const DisabledEditing = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Programmatic Control Use the `useTagsInput` hook with `RootProvider` to access the component's API methods like `addValue()`, `setValue()`, and `clearValue()` for full programmatic control. **Example: programmatic-control** #### React ```tsx import { TagsInput, useTagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tags-input.module.css' export const ProgrammaticControl = () => { const tagsInput = useTagsInput() return (
                    {(api) => ( <> Frameworks {api.value.map((value, index) => ( {value} ))} )}
                    ) } ``` #### Solid ```tsx import { TagsInput, useTagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tags-input.module.css' export const ProgrammaticControl = () => { const tagsInput = useTagsInput() return (
                    {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet render(api)} Frameworks {#each api().value as value, index (index)} {value} {/each} {/snippet}
                    ``` ### Combobox Combine TagsInput with Combobox to create an autocomplete tags input. This pattern uses shared IDs between both components and the `asChild` prop to compose the inputs together. **Example: with-combobox** #### React ```tsx import { Combobox, useCombobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { TagsInput, useTagsInput } from '@ark-ui/react/tags-input' import { CheckIcon, XIcon } from 'lucide-react' import { useId } from 'react' import combobox from 'styles/combobox.module.css' import styles from 'styles/tags-input.module.css' export const WithCombobox = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Preact', 'Next.js', 'Astro', 'Nuxt'], filter: contains, }) const uid = useId() const tagsInput = useTagsInput({ ids: { input: `input_${uid}`, control: `control_${uid}` }, }) const comboboxApi = useCombobox({ ids: { input: `input_${uid}`, control: `control_${uid}` }, collection, onInputValueChange(details) { filter(details.inputValue) }, value: [], allowCustomValue: true, onValueChange: (details) => { if (details.value[0]) { tagsInput.addValue(details.value[0]) } }, selectionBehavior: 'clear', }) return ( Frameworks {tagsInput.value.map((value, index) => ( {value} ))} No frameworks found {collection.items.map((item) => ( {item} ))} ) } ``` #### Solid ```tsx import { Combobox, useCombobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { TagsInput, useTagsInput } from '@ark-ui/solid/tags-input' import { CheckIcon, XIcon } from 'lucide-solid' import { For, createUniqueId } from 'solid-js' import { Portal } from 'solid-js/web' import combobox from 'styles/combobox.module.css' import styles from 'styles/tags-input.module.css' export const WithCombobox = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Preact', 'Next.js', 'Astro', 'Nuxt'], filter: filterFn().contains, }) const uid = createUniqueId() const tagsInput = useTagsInput({ ids: { input: `input_${uid}`, control: `control_${uid}` }, }) const comboboxApi = useCombobox({ ids: { input: `input_${uid}`, control: `control_${uid}` }, collection: collection(), onInputValueChange(details) { filter(details.inputValue) }, value: [], allowCustomValue: true, onValueChange: (details) => { if (details.value[0]) { tagsInput().addValue(details.value[0]) } }, selectionBehavior: 'clear', }) return ( Frameworks {(value, index) => ( {value} )} } /> No frameworks found {(item) => ( {item} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {#snippet asChild(inputProps)} {/snippet} No frameworks found {#each collection().items as item (item)} {item} {/each} ``` ## Guides ### Navigation When the input has an empty value or the caret is at the start position, the tags can be selected by using the arrow left and arrow right keys. When "visual" focus in on any tag: - Pressing Enter or double-clicking on the tag will put it in edit mode, allowing the user change its value and press Enter to commit the changes. - Pressing Delete or Backspace will delete the tag that has _visual_ focus. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `addOnPaste` | `boolean` | No | Whether to add a tag when you paste values into the tag input | | `allowOverflow` | `boolean` | No | Whether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether the input should be auto-focused | | `blurBehavior` | `'clear' | 'add'` | No | The behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value | | `defaultInputValue` | `string` | No | The initial tag input value when rendered. Use when you don't need to control the tag input value. | | `defaultValue` | `string[]` | No | The initial tag value when rendered. Use when you don't need to control the tag value. | | `delimiter` | `string | RegExp` | No | The character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input | | `disabled` | `boolean` | No | Whether the tags input should be disabled | | `editable` | `boolean` | No | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string input: string hiddenInput: string clearBtn: string label: string control: string item: (opts: ItemProps) => string itemDeleteTrigger: (opts: ItemProps) => string itemInput: (opts: ItemProps) => string }>` | No | The ids of the elements in the tags input. Useful for composition. | | `inputValue` | `string` | No | The controlled tag input's value | | `invalid` | `boolean` | No | Whether the tags input is invalid | | `max` | `number` | No | The max number of tags | | `maxLength` | `number` | No | The max length of the input. | | `name` | `string` | No | The name attribute for the input. Useful for form submissions | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Callback fired when a tag is highlighted by pointer or keyboard navigation | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Callback fired when the input value is updated | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the tag values is updated | | `onValueInvalid` | `(details: ValidityChangeDetails) => void` | No | Callback fired when the max tag count is reached or the `validateTag` function returns `false` | | `readOnly` | `boolean` | No | Whether the tags input should be read-only | | `required` | `boolean` | No | Whether the tags input is required | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `validate` | `(details: ValidateArgs) => boolean` | No | Returns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. | | `value` | `string[]` | No | The controlled tag value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-empty]` | Present when the content is empty | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | clear-trigger | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-empty]` | Present when the content is empty | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **ItemInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-preview | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `string | number` | Yes | | | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTagsInputReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `addOnPaste` | `boolean` | No | Whether to add a tag when you paste values into the tag input | | `allowOverflow` | `boolean` | No | Whether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether the input should be auto-focused | | `blurBehavior` | `'clear' | 'add'` | No | The behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value | | `defaultInputValue` | `string` | No | The initial tag input value when rendered. Use when you don't need to control the tag input value. | | `defaultValue` | `string[]` | No | The initial tag value when rendered. Use when you don't need to control the tag value. | | `delimiter` | `string | RegExp` | No | The character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input | | `disabled` | `boolean` | No | Whether the tags input should be disabled | | `editable` | `boolean` | No | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. | | `form` | `string` | No | The associate form of the underlying input element. | | `ids` | `Partial<{ root: string input: string hiddenInput: string clearBtn: string label: string control: string item: (opts: ItemProps) => string itemDeleteTrigger: (opts: ItemProps) => string itemInput: (opts: ItemProps) => string }>` | No | The ids of the elements in the tags input. Useful for composition. | | `inputValue` | `string` | No | The controlled tag input's value | | `invalid` | `boolean` | No | Whether the tags input is invalid | | `max` | `number` | No | The max number of tags | | `maxLength` | `number` | No | The max length of the input. | | `name` | `string` | No | The name attribute for the input. Useful for form submissions | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Callback fired when a tag is highlighted by pointer or keyboard navigation | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Callback fired when the input value is updated | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the tag values is updated | | `onValueInvalid` | `(details: ValidityChangeDetails) => void` | No | Callback fired when the max tag count is reached or the `validateTag` function returns `false` | | `readOnly` | `boolean` | No | Whether the tags input should be read-only | | `required` | `boolean` | No | Whether the tags input is required | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `validate` | `(details: ValidateArgs) => boolean` | No | Returns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. | | `value` | `string[]` | No | The controlled tag value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-empty]` | Present when the content is empty | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | clear-trigger | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-empty]` | Present when the content is empty | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **ItemInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-preview | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `string | number` | Yes | | | `value` | `string` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTagsInputReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `addOnPaste` | `boolean` | No | Whether to add a tag when you paste values into the tag input | | `allowOverflow` | `boolean` | No | Whether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether the input should be auto-focused | | `blurBehavior` | `'clear' | 'add'` | No | The behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value | | `defaultInputValue` | `string` | No | The initial tag input value when rendered. Use when you don't need to control the tag input value. | | `defaultValue` | `string[]` | No | The initial tag value when rendered. Use when you don't need to control the tag value. | | `delimiter` | `string | RegExp` | No | The character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input | | `disabled` | `boolean` | No | Whether the tags input should be disabled | | `editable` | `boolean` | No | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string input: string hiddenInput: string clearBtn: string label: string control: string item(opts: ItemProps): string itemDeleteTrigger(opts: ItemProps): string itemInput(opts: ItemProps): string }>` | No | The ids of the elements in the tags input. Useful for composition. | | `inputValue` | `string` | No | The controlled tag input's value | | `invalid` | `boolean` | No | Whether the tags input is invalid | | `max` | `number` | No | The max number of tags | | `maxLength` | `number` | No | The max length of the input. | | `modelValue` | `string[]` | No | The v-model value of the tags input | | `name` | `string` | No | The name attribute for the input. Useful for form submissions | | `readOnly` | `boolean` | No | Whether the tags input should be read-only | | `required` | `boolean` | No | Whether the tags input is required | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `validate` | `(details: ValidateArgs) => boolean` | No | Returns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-empty]` | Present when the content is empty | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | clear-trigger | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-empty]` | Present when the content is empty | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **ItemInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-preview | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `string | number` | Yes | | | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TagsInputApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `addOnPaste` | `boolean` | No | Whether to add a tag when you paste values into the tag input | | `allowOverflow` | `boolean` | No | Whether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether the input should be auto-focused | | `blurBehavior` | `'clear' | 'add'` | No | The behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value | | `defaultInputValue` | `string` | No | The initial tag input value when rendered. Use when you don't need to control the tag input value. | | `defaultValue` | `string[]` | No | The initial tag value when rendered. Use when you don't need to control the tag value. | | `delimiter` | `string | RegExp` | No | The character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input | | `disabled` | `boolean` | No | Whether the tags input should be disabled | | `editable` | `boolean` | No | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string input: string hiddenInput: string clearBtn: string label: string control: string item: (opts: ItemProps) => string itemDeleteTrigger: (opts: ItemProps) => string itemInput: (opts: ItemProps) => string }>` | No | The ids of the elements in the tags input. Useful for composition. | | `inputValue` | `string` | No | The controlled tag input's value | | `invalid` | `boolean` | No | Whether the tags input is invalid | | `max` | `number` | No | The max number of tags | | `maxLength` | `number` | No | The max length of the input. | | `name` | `string` | No | The name attribute for the input. Useful for form submissions | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Callback fired when a tag is highlighted by pointer or keyboard navigation | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Callback fired when the input value is updated | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the tag values is updated | | `onValueInvalid` | `(details: ValidityChangeDetails) => void` | No | Callback fired when the max tag count is reached or the `validateTag` function returns `false` | | `readOnly` | `boolean` | No | Whether the tags input should be read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the tags input is required | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `validate` | `(details: ValidateArgs) => boolean` | No | Returns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. | | `value` | `string[]` | No | The controlled tag value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-empty]` | Present when the content is empty | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | clear-trigger | | `[data-readonly]` | Present when read-only | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTagsInputReturn]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-empty]` | Present when the content is empty | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTagsInputItemContext]>` | Yes | | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **ItemInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-preview | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `value` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTagsInputReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `empty` | `boolean` | Whether the tags are empty | | `inputValue` | `string` | The value of the tags entry input. | | `value` | `string[]` | The value of the tags as an array of strings. | | `valueAsString` | `string` | The value of the tags as a string. | | `count` | `number` | The number of the tags. | | `atMax` | `boolean` | Whether the tags have reached the max limit. | | `setValue` | `(value: string[]) => void` | Function to set the value of the tags. | | `clearValue` | `(id?: string) => void` | Function to clear the value of the tags. | | `addValue` | `(value: string) => void` | Function to add a tag to the tags. | | `setValueAtIndex` | `(index: number, value: string) => void` | Function to set the value of a tag at the given index. | | `setInputValue` | `(value: string) => void` | Function to set the value of the tags entry input. | | `clearInputValue` | `VoidFunction` | Function to clear the value of the tags entry input. | | `focus` | `VoidFunction` | Function to focus the tags entry input. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a tag | ## Accessibility ### Keyboard Support **`ArrowLeft`** Description: Moves focus to the previous tag item **`ArrowRight`** Description: Moves focus to the next tag item **`Backspace`** Description: Deletes the tag item that has visual focus or the last tag item **`Enter`** Description: When a tag item has visual focus, it puts the tag in edit mode.
                    When the input has focus, it adds the value to the list of tags
                    **`Delete`** Description: Deletes the tag item that has visual focus **`Control + V`** Description: When `addOnPaste` is set. Adds the pasted value as a tags --- # Tags Input (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const Basic = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Basic = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: controlled** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tags-input.module.css' export const Controlled = () => { const [value, setValue] = useState(['React', 'Solid']) return ( setValue(details.value)}> {(api) => ( <> Frameworks {api.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Controlled = () => { const [value, setValue] = createSignal(['vue', 'react']) return ( setValue(details.value)} class={styles.Root}> {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: controlled-input-value** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/tags-input.module.css' export const ControlledInputValue = () => { const [inputValue, setInputValue] = useState('') return (
                    Current: "{inputValue}"
                    setInputValue(details.inputValue)} > {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )}
                    ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/tags-input.module.css' export const ControlledInputValue = () => { const [inputValue, setInputValue] = createSignal('') return ( setInputValue(details.inputValue)} class={styles.Root} > {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: root-provider** #### React ```tsx import { TagsInput, useTagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const RootProvider = () => { const tagsInput = useTagsInput() return (
                    {(api) => ( <> Frameworks {api.value.map((value, index) => ( {value} ))} )} values: {JSON.stringify(tagsInput.value)}
                    ) } ``` #### Solid ```tsx import { TagsInput, useTagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tags-input.module.css' export const RootProvider = () => { const tagsInput = useTagsInput() return (
                    {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet render(api)} Frameworks {#each api().value as value, index (index)} {value} {/each} {/snippet} values: {JSON.stringify(tagsInput().value)}
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/tags-input.module.css' export const WithField = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} Additional Info Error Info ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/tags-input.module.css' export const WithField = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} Additional Info Error Info ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} Additional Info Error Info ``` ### 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`. When the tag reaches the limit, new tags cannot be added except the `allowOverflow` prop is set to `true`. **Example: max-with-overflow** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const MaxWithOverflow = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const MaxWithOverflow = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: delimiter** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' const DELIMITER_PATTERN = /[,;\s]/ export const Delimiter = () => { return ( {(tagsInput) => ( <> Frameworks (add with comma, semicolon, or space) {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Delimiter = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Disabled Use the `disabled` prop to make the tags input non-interactive. Users won't be able to add, remove, or edit tags. **Example: disabled** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const Disabled = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Disabled = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Invalid Use the `invalid` prop to mark the tags input as invalid for form validation purposes. **Example: invalid** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const Invalid = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Invalid = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Max Length Use the `maxLength` prop to limit the number of characters allowed per tag. This prevents users from creating overly long tags. **Example: max-tag-length** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const MaxTagLength = () => { return ( {(tagsInput) => ( <> Frameworks (Max 10 characters) {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const MaxTagLength = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Read-only Use the `readOnly` prop to make tags visible but not editable. Users can view tags but cannot add, remove, or modify them. **Example: readonly** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const Readonly = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Readonly = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Validation Before a tag is added, the `validate` function is called to determine whether to accept or reject a tag. A common use-case for validating tags is preventing duplicates or validating the data type. **Example: validation** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' const TAG_PATTERN = /^[a-zA-Z0-9-]+$/ const validateTag = ({ value, inputValue }: { value: string[]; inputValue: string }) => !!inputValue?.trim() && !value.includes(inputValue) && inputValue.length >= 3 && TAG_PATTERN.test(inputValue) export const Validation = () => { return ( {(tagsInput) => ( <> Frameworks (Min 3 chars, alphanumeric) {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Validation = () => { return ( { return !details.value.includes(details.inputValue) }} class={styles.Root} > {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte { return !details.value.includes(details.inputValue) }} class={styles.Root} > {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: blur-behavior** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const BlurBehavior = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const BlurBehavior = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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 **Example: paste-behavior** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const PasteBehavior = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const PasteBehavior = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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}` **Example: disabled-editing** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const DisabledEditing = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const DisabledEditing = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Programmatic Control Use the `useTagsInput` hook with `RootProvider` to access the component's API methods like `addValue()`, `setValue()`, and `clearValue()` for full programmatic control. **Example: programmatic-control** #### React ```tsx import { TagsInput, useTagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tags-input.module.css' export const ProgrammaticControl = () => { const tagsInput = useTagsInput() return (
                    {(api) => ( <> Frameworks {api.value.map((value, index) => ( {value} ))} )}
                    ) } ``` #### Solid ```tsx import { TagsInput, useTagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tags-input.module.css' export const ProgrammaticControl = () => { const tagsInput = useTagsInput() return (
                    {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet render(api)} Frameworks {#each api().value as value, index (index)} {value} {/each} {/snippet}
                    ``` ### Combobox Combine TagsInput with Combobox to create an autocomplete tags input. This pattern uses shared IDs between both components and the `asChild` prop to compose the inputs together. **Example: with-combobox** #### React ```tsx import { Combobox, useCombobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { TagsInput, useTagsInput } from '@ark-ui/react/tags-input' import { CheckIcon, XIcon } from 'lucide-react' import { useId } from 'react' import combobox from 'styles/combobox.module.css' import styles from 'styles/tags-input.module.css' export const WithCombobox = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Preact', 'Next.js', 'Astro', 'Nuxt'], filter: contains, }) const uid = useId() const tagsInput = useTagsInput({ ids: { input: `input_${uid}`, control: `control_${uid}` }, }) const comboboxApi = useCombobox({ ids: { input: `input_${uid}`, control: `control_${uid}` }, collection, onInputValueChange(details) { filter(details.inputValue) }, value: [], allowCustomValue: true, onValueChange: (details) => { if (details.value[0]) { tagsInput.addValue(details.value[0]) } }, selectionBehavior: 'clear', }) return ( Frameworks {tagsInput.value.map((value, index) => ( {value} ))} No frameworks found {collection.items.map((item) => ( {item} ))} ) } ``` #### Solid ```tsx import { Combobox, useCombobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { TagsInput, useTagsInput } from '@ark-ui/solid/tags-input' import { CheckIcon, XIcon } from 'lucide-solid' import { For, createUniqueId } from 'solid-js' import { Portal } from 'solid-js/web' import combobox from 'styles/combobox.module.css' import styles from 'styles/tags-input.module.css' export const WithCombobox = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Preact', 'Next.js', 'Astro', 'Nuxt'], filter: filterFn().contains, }) const uid = createUniqueId() const tagsInput = useTagsInput({ ids: { input: `input_${uid}`, control: `control_${uid}` }, }) const comboboxApi = useCombobox({ ids: { input: `input_${uid}`, control: `control_${uid}` }, collection: collection(), onInputValueChange(details) { filter(details.inputValue) }, value: [], allowCustomValue: true, onValueChange: (details) => { if (details.value[0]) { tagsInput().addValue(details.value[0]) } }, selectionBehavior: 'clear', }) return ( Frameworks {(value, index) => ( {value} )} } /> No frameworks found {(item) => ( {item} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {#snippet asChild(inputProps)} {/snippet} No frameworks found {#each collection().items as item (item)} {item} {/each} ``` ## Guides ### Navigation When the input has an empty value or the caret is at the start position, the tags can be selected by using the arrow left and arrow right keys. When "visual" focus in on any tag: - Pressing Enter or double-clicking on the tag will put it in edit mode, allowing the user change its value and press Enter to commit the changes. - Pressing Delete or Backspace will delete the tag that has _visual_ focus. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `addOnPaste` | `boolean` | No | Whether to add a tag when you paste values into the tag input | | `allowOverflow` | `boolean` | No | Whether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether the input should be auto-focused | | `blurBehavior` | `'clear' | 'add'` | No | The behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value | | `defaultInputValue` | `string` | No | The initial tag input value when rendered. Use when you don't need to control the tag input value. | | `defaultValue` | `string[]` | No | The initial tag value when rendered. Use when you don't need to control the tag value. | | `delimiter` | `string | RegExp` | No | The character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input | | `disabled` | `boolean` | No | Whether the tags input should be disabled | | `editable` | `boolean` | No | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string input: string hiddenInput: string clearBtn: string label: string control: string item: (opts: ItemProps) => string itemDeleteTrigger: (opts: ItemProps) => string itemInput: (opts: ItemProps) => string }>` | No | The ids of the elements in the tags input. Useful for composition. | | `inputValue` | `string` | No | The controlled tag input's value | | `invalid` | `boolean` | No | Whether the tags input is invalid | | `max` | `number` | No | The max number of tags | | `maxLength` | `number` | No | The max length of the input. | | `name` | `string` | No | The name attribute for the input. Useful for form submissions | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Callback fired when a tag is highlighted by pointer or keyboard navigation | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Callback fired when the input value is updated | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the tag values is updated | | `onValueInvalid` | `(details: ValidityChangeDetails) => void` | No | Callback fired when the max tag count is reached or the `validateTag` function returns `false` | | `readOnly` | `boolean` | No | Whether the tags input should be read-only | | `required` | `boolean` | No | Whether the tags input is required | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `validate` | `(details: ValidateArgs) => boolean` | No | Returns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. | | `value` | `string[]` | No | The controlled tag value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-empty]` | Present when the content is empty | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | clear-trigger | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-empty]` | Present when the content is empty | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **ItemInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-preview | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `string | number` | Yes | | | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTagsInputReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `addOnPaste` | `boolean` | No | Whether to add a tag when you paste values into the tag input | | `allowOverflow` | `boolean` | No | Whether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether the input should be auto-focused | | `blurBehavior` | `'clear' | 'add'` | No | The behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value | | `defaultInputValue` | `string` | No | The initial tag input value when rendered. Use when you don't need to control the tag input value. | | `defaultValue` | `string[]` | No | The initial tag value when rendered. Use when you don't need to control the tag value. | | `delimiter` | `string | RegExp` | No | The character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input | | `disabled` | `boolean` | No | Whether the tags input should be disabled | | `editable` | `boolean` | No | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. | | `form` | `string` | No | The associate form of the underlying input element. | | `ids` | `Partial<{ root: string input: string hiddenInput: string clearBtn: string label: string control: string item: (opts: ItemProps) => string itemDeleteTrigger: (opts: ItemProps) => string itemInput: (opts: ItemProps) => string }>` | No | The ids of the elements in the tags input. Useful for composition. | | `inputValue` | `string` | No | The controlled tag input's value | | `invalid` | `boolean` | No | Whether the tags input is invalid | | `max` | `number` | No | The max number of tags | | `maxLength` | `number` | No | The max length of the input. | | `name` | `string` | No | The name attribute for the input. Useful for form submissions | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Callback fired when a tag is highlighted by pointer or keyboard navigation | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Callback fired when the input value is updated | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the tag values is updated | | `onValueInvalid` | `(details: ValidityChangeDetails) => void` | No | Callback fired when the max tag count is reached or the `validateTag` function returns `false` | | `readOnly` | `boolean` | No | Whether the tags input should be read-only | | `required` | `boolean` | No | Whether the tags input is required | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `validate` | `(details: ValidateArgs) => boolean` | No | Returns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. | | `value` | `string[]` | No | The controlled tag value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-empty]` | Present when the content is empty | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | clear-trigger | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-empty]` | Present when the content is empty | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **ItemInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-preview | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `string | number` | Yes | | | `value` | `string` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTagsInputReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `addOnPaste` | `boolean` | No | Whether to add a tag when you paste values into the tag input | | `allowOverflow` | `boolean` | No | Whether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether the input should be auto-focused | | `blurBehavior` | `'clear' | 'add'` | No | The behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value | | `defaultInputValue` | `string` | No | The initial tag input value when rendered. Use when you don't need to control the tag input value. | | `defaultValue` | `string[]` | No | The initial tag value when rendered. Use when you don't need to control the tag value. | | `delimiter` | `string | RegExp` | No | The character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input | | `disabled` | `boolean` | No | Whether the tags input should be disabled | | `editable` | `boolean` | No | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string input: string hiddenInput: string clearBtn: string label: string control: string item(opts: ItemProps): string itemDeleteTrigger(opts: ItemProps): string itemInput(opts: ItemProps): string }>` | No | The ids of the elements in the tags input. Useful for composition. | | `inputValue` | `string` | No | The controlled tag input's value | | `invalid` | `boolean` | No | Whether the tags input is invalid | | `max` | `number` | No | The max number of tags | | `maxLength` | `number` | No | The max length of the input. | | `modelValue` | `string[]` | No | The v-model value of the tags input | | `name` | `string` | No | The name attribute for the input. Useful for form submissions | | `readOnly` | `boolean` | No | Whether the tags input should be read-only | | `required` | `boolean` | No | Whether the tags input is required | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `validate` | `(details: ValidateArgs) => boolean` | No | Returns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-empty]` | Present when the content is empty | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | clear-trigger | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-empty]` | Present when the content is empty | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **ItemInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-preview | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `string | number` | Yes | | | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TagsInputApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `addOnPaste` | `boolean` | No | Whether to add a tag when you paste values into the tag input | | `allowOverflow` | `boolean` | No | Whether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether the input should be auto-focused | | `blurBehavior` | `'clear' | 'add'` | No | The behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value | | `defaultInputValue` | `string` | No | The initial tag input value when rendered. Use when you don't need to control the tag input value. | | `defaultValue` | `string[]` | No | The initial tag value when rendered. Use when you don't need to control the tag value. | | `delimiter` | `string | RegExp` | No | The character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input | | `disabled` | `boolean` | No | Whether the tags input should be disabled | | `editable` | `boolean` | No | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string input: string hiddenInput: string clearBtn: string label: string control: string item: (opts: ItemProps) => string itemDeleteTrigger: (opts: ItemProps) => string itemInput: (opts: ItemProps) => string }>` | No | The ids of the elements in the tags input. Useful for composition. | | `inputValue` | `string` | No | The controlled tag input's value | | `invalid` | `boolean` | No | Whether the tags input is invalid | | `max` | `number` | No | The max number of tags | | `maxLength` | `number` | No | The max length of the input. | | `name` | `string` | No | The name attribute for the input. Useful for form submissions | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Callback fired when a tag is highlighted by pointer or keyboard navigation | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Callback fired when the input value is updated | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the tag values is updated | | `onValueInvalid` | `(details: ValidityChangeDetails) => void` | No | Callback fired when the max tag count is reached or the `validateTag` function returns `false` | | `readOnly` | `boolean` | No | Whether the tags input should be read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the tags input is required | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `validate` | `(details: ValidateArgs) => boolean` | No | Returns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. | | `value` | `string[]` | No | The controlled tag value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-empty]` | Present when the content is empty | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | clear-trigger | | `[data-readonly]` | Present when read-only | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTagsInputReturn]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-empty]` | Present when the content is empty | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTagsInputItemContext]>` | Yes | | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **ItemInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-preview | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `value` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTagsInputReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `empty` | `boolean` | Whether the tags are empty | | `inputValue` | `string` | The value of the tags entry input. | | `value` | `string[]` | The value of the tags as an array of strings. | | `valueAsString` | `string` | The value of the tags as a string. | | `count` | `number` | The number of the tags. | | `atMax` | `boolean` | Whether the tags have reached the max limit. | | `setValue` | `(value: string[]) => void` | Function to set the value of the tags. | | `clearValue` | `(id?: string) => void` | Function to clear the value of the tags. | | `addValue` | `(value: string) => void` | Function to add a tag to the tags. | | `setValueAtIndex` | `(index: number, value: string) => void` | Function to set the value of a tag at the given index. | | `setInputValue` | `(value: string) => void` | Function to set the value of the tags entry input. | | `clearInputValue` | `VoidFunction` | Function to clear the value of the tags entry input. | | `focus` | `VoidFunction` | Function to focus the tags entry input. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a tag | ## Accessibility ### Keyboard Support **`ArrowLeft`** Description: Moves focus to the previous tag item **`ArrowRight`** Description: Moves focus to the next tag item **`Backspace`** Description: Deletes the tag item that has visual focus or the last tag item **`Enter`** Description: When a tag item has visual focus, it puts the tag in edit mode.
                    When the input has focus, it adds the value to the list of tags
                    **`Delete`** Description: Deletes the tag item that has visual focus **`Control + V`** Description: When `addOnPaste` is set. Adds the pasted value as a tags --- # Tags Input (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const Basic = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Basic = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: controlled** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tags-input.module.css' export const Controlled = () => { const [value, setValue] = useState(['React', 'Solid']) return ( setValue(details.value)}> {(api) => ( <> Frameworks {api.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Controlled = () => { const [value, setValue] = createSignal(['vue', 'react']) return ( setValue(details.value)} class={styles.Root}> {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: controlled-input-value** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/tags-input.module.css' export const ControlledInputValue = () => { const [inputValue, setInputValue] = useState('') return (
                    Current: "{inputValue}"
                    setInputValue(details.inputValue)} > {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )}
                    ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index, createSignal } from 'solid-js' import styles from 'styles/tags-input.module.css' export const ControlledInputValue = () => { const [inputValue, setInputValue] = createSignal('') return ( setInputValue(details.inputValue)} class={styles.Root} > {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: root-provider** #### React ```tsx import { TagsInput, useTagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const RootProvider = () => { const tagsInput = useTagsInput() return (
                    {(api) => ( <> Frameworks {api.value.map((value, index) => ( {value} ))} )} values: {JSON.stringify(tagsInput.value)}
                    ) } ``` #### Solid ```tsx import { TagsInput, useTagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tags-input.module.css' export const RootProvider = () => { const tagsInput = useTagsInput() return (
                    {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet render(api)} Frameworks {#each api().value as value, index (index)} {value} {/each} {/snippet} values: {JSON.stringify(tagsInput().value)}
                    ``` ### 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. **Example: with-field** #### React ```tsx import { Field } from '@ark-ui/react/field' import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import field from 'styles/field.module.css' import styles from 'styles/tags-input.module.css' export const WithField = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} Additional Info Error Info ) } ``` #### Solid ```tsx import { Field } from '@ark-ui/solid/field' import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/tags-input.module.css' export const WithField = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} Additional Info Error Info ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} Additional Info Error Info ``` ### 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`. When the tag reaches the limit, new tags cannot be added except the `allowOverflow` prop is set to `true`. **Example: max-with-overflow** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const MaxWithOverflow = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const MaxWithOverflow = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: delimiter** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' const DELIMITER_PATTERN = /[,;\s]/ export const Delimiter = () => { return ( {(tagsInput) => ( <> Frameworks (add with comma, semicolon, or space) {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Delimiter = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Disabled Use the `disabled` prop to make the tags input non-interactive. Users won't be able to add, remove, or edit tags. **Example: disabled** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const Disabled = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Disabled = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Invalid Use the `invalid` prop to mark the tags input as invalid for form validation purposes. **Example: invalid** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const Invalid = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Invalid = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Max Length Use the `maxLength` prop to limit the number of characters allowed per tag. This prevents users from creating overly long tags. **Example: max-tag-length** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const MaxTagLength = () => { return ( {(tagsInput) => ( <> Frameworks (Max 10 characters) {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const MaxTagLength = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Read-only Use the `readOnly` prop to make tags visible but not editable. Users can view tags but cannot add, remove, or modify them. **Example: readonly** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const Readonly = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Readonly = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Validation Before a tag is added, the `validate` function is called to determine whether to accept or reject a tag. A common use-case for validating tags is preventing duplicates or validating the data type. **Example: validation** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' const TAG_PATTERN = /^[a-zA-Z0-9-]+$/ const validateTag = ({ value, inputValue }: { value: string[]; inputValue: string }) => !!inputValue?.trim() && !value.includes(inputValue) && inputValue.length >= 3 && TAG_PATTERN.test(inputValue) export const Validation = () => { return ( {(tagsInput) => ( <> Frameworks (Min 3 chars, alphanumeric) {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const Validation = () => { return ( { return !details.value.includes(details.inputValue) }} class={styles.Root} > {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte { return !details.value.includes(details.inputValue) }} class={styles.Root} > {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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. **Example: blur-behavior** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const BlurBehavior = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const BlurBehavior = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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 **Example: paste-behavior** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const PasteBehavior = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const PasteBehavior = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### 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}` **Example: disabled-editing** #### React ```tsx import { TagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import styles from 'styles/tags-input.module.css' export const DisabledEditing = () => { return ( {(tagsInput) => ( <> Frameworks {tagsInput.value.map((value, index) => ( {value} ))} )} ) } ``` #### Solid ```tsx import { TagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import styles from 'styles/tags-input.module.css' export const DisabledEditing = () => { return ( {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tagsInput)} Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {/snippet} ``` ### Programmatic Control Use the `useTagsInput` hook with `RootProvider` to access the component's API methods like `addValue()`, `setValue()`, and `clearValue()` for full programmatic control. **Example: programmatic-control** #### React ```tsx import { TagsInput, useTagsInput } from '@ark-ui/react/tags-input' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tags-input.module.css' export const ProgrammaticControl = () => { const tagsInput = useTagsInput() return (
                    {(api) => ( <> Frameworks {api.value.map((value, index) => ( {value} ))} )}
                    ) } ``` #### Solid ```tsx import { TagsInput, useTagsInput } from '@ark-ui/solid/tags-input' import { XIcon } from 'lucide-solid' import { Index } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tags-input.module.css' export const ProgrammaticControl = () => { const tagsInput = useTagsInput() return (
                    {(api) => ( <> Frameworks {(value, index) => ( {value()} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet render(api)} Frameworks {#each api().value as value, index (index)} {value} {/each} {/snippet}
                    ``` ### Combobox Combine TagsInput with Combobox to create an autocomplete tags input. This pattern uses shared IDs between both components and the `asChild` prop to compose the inputs together. **Example: with-combobox** #### React ```tsx import { Combobox, useCombobox, useListCollection } from '@ark-ui/react/combobox' import { useFilter } from '@ark-ui/react/locale' import { Portal } from '@ark-ui/react/portal' import { TagsInput, useTagsInput } from '@ark-ui/react/tags-input' import { CheckIcon, XIcon } from 'lucide-react' import { useId } from 'react' import combobox from 'styles/combobox.module.css' import styles from 'styles/tags-input.module.css' export const WithCombobox = () => { const { contains } = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Preact', 'Next.js', 'Astro', 'Nuxt'], filter: contains, }) const uid = useId() const tagsInput = useTagsInput({ ids: { input: `input_${uid}`, control: `control_${uid}` }, }) const comboboxApi = useCombobox({ ids: { input: `input_${uid}`, control: `control_${uid}` }, collection, onInputValueChange(details) { filter(details.inputValue) }, value: [], allowCustomValue: true, onValueChange: (details) => { if (details.value[0]) { tagsInput.addValue(details.value[0]) } }, selectionBehavior: 'clear', }) return ( Frameworks {tagsInput.value.map((value, index) => ( {value} ))} No frameworks found {collection.items.map((item) => ( {item} ))} ) } ``` #### Solid ```tsx import { Combobox, useCombobox, useListCollection } from '@ark-ui/solid/combobox' import { useFilter } from '@ark-ui/solid/locale' import { TagsInput, useTagsInput } from '@ark-ui/solid/tags-input' import { CheckIcon, XIcon } from 'lucide-solid' import { For, createUniqueId } from 'solid-js' import { Portal } from 'solid-js/web' import combobox from 'styles/combobox.module.css' import styles from 'styles/tags-input.module.css' export const WithCombobox = () => { const filterFn = useFilter({ sensitivity: 'base' }) const { collection, filter } = useListCollection({ initialItems: ['React', 'Solid', 'Vue', 'Svelte', 'Angular', 'Preact', 'Next.js', 'Astro', 'Nuxt'], filter: filterFn().contains, }) const uid = createUniqueId() const tagsInput = useTagsInput({ ids: { input: `input_${uid}`, control: `control_${uid}` }, }) const comboboxApi = useCombobox({ ids: { input: `input_${uid}`, control: `control_${uid}` }, collection: collection(), onInputValueChange(details) { filter(details.inputValue) }, value: [], allowCustomValue: true, onValueChange: (details) => { if (details.value[0]) { tagsInput().addValue(details.value[0]) } }, selectionBehavior: 'clear', }) return ( Frameworks {(value, index) => ( {value} )} } /> No frameworks found {(item) => ( {item} )} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Frameworks {#each tagsInput().value as value, index (index)} {value} {/each} {#snippet asChild(inputProps)} {/snippet} No frameworks found {#each collection().items as item (item)} {item} {/each} ``` ## Guides ### Navigation When the input has an empty value or the caret is at the start position, the tags can be selected by using the arrow left and arrow right keys. When "visual" focus in on any tag: - Pressing Enter or double-clicking on the tag will put it in edit mode, allowing the user change its value and press Enter to commit the changes. - Pressing Delete or Backspace will delete the tag that has _visual_ focus. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `addOnPaste` | `boolean` | No | Whether to add a tag when you paste values into the tag input | | `allowOverflow` | `boolean` | No | Whether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether the input should be auto-focused | | `blurBehavior` | `'clear' | 'add'` | No | The behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value | | `defaultInputValue` | `string` | No | The initial tag input value when rendered. Use when you don't need to control the tag input value. | | `defaultValue` | `string[]` | No | The initial tag value when rendered. Use when you don't need to control the tag value. | | `delimiter` | `string | RegExp` | No | The character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input | | `disabled` | `boolean` | No | Whether the tags input should be disabled | | `editable` | `boolean` | No | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string input: string hiddenInput: string clearBtn: string label: string control: string item: (opts: ItemProps) => string itemDeleteTrigger: (opts: ItemProps) => string itemInput: (opts: ItemProps) => string }>` | No | The ids of the elements in the tags input. Useful for composition. | | `inputValue` | `string` | No | The controlled tag input's value | | `invalid` | `boolean` | No | Whether the tags input is invalid | | `max` | `number` | No | The max number of tags | | `maxLength` | `number` | No | The max length of the input. | | `name` | `string` | No | The name attribute for the input. Useful for form submissions | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Callback fired when a tag is highlighted by pointer or keyboard navigation | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Callback fired when the input value is updated | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the tag values is updated | | `onValueInvalid` | `(details: ValidityChangeDetails) => void` | No | Callback fired when the max tag count is reached or the `validateTag` function returns `false` | | `readOnly` | `boolean` | No | Whether the tags input should be read-only | | `required` | `boolean` | No | Whether the tags input is required | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `validate` | `(details: ValidateArgs) => boolean` | No | Returns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. | | `value` | `string[]` | No | The controlled tag value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-empty]` | Present when the content is empty | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | clear-trigger | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-empty]` | Present when the content is empty | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **ItemInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-preview | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `string | number` | Yes | | | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTagsInputReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `addOnPaste` | `boolean` | No | Whether to add a tag when you paste values into the tag input | | `allowOverflow` | `boolean` | No | Whether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether the input should be auto-focused | | `blurBehavior` | `'clear' | 'add'` | No | The behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value | | `defaultInputValue` | `string` | No | The initial tag input value when rendered. Use when you don't need to control the tag input value. | | `defaultValue` | `string[]` | No | The initial tag value when rendered. Use when you don't need to control the tag value. | | `delimiter` | `string | RegExp` | No | The character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input | | `disabled` | `boolean` | No | Whether the tags input should be disabled | | `editable` | `boolean` | No | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. | | `form` | `string` | No | The associate form of the underlying input element. | | `ids` | `Partial<{ root: string input: string hiddenInput: string clearBtn: string label: string control: string item: (opts: ItemProps) => string itemDeleteTrigger: (opts: ItemProps) => string itemInput: (opts: ItemProps) => string }>` | No | The ids of the elements in the tags input. Useful for composition. | | `inputValue` | `string` | No | The controlled tag input's value | | `invalid` | `boolean` | No | Whether the tags input is invalid | | `max` | `number` | No | The max number of tags | | `maxLength` | `number` | No | The max length of the input. | | `name` | `string` | No | The name attribute for the input. Useful for form submissions | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Callback fired when a tag is highlighted by pointer or keyboard navigation | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Callback fired when the input value is updated | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the tag values is updated | | `onValueInvalid` | `(details: ValidityChangeDetails) => void` | No | Callback fired when the max tag count is reached or the `validateTag` function returns `false` | | `readOnly` | `boolean` | No | Whether the tags input should be read-only | | `required` | `boolean` | No | Whether the tags input is required | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `validate` | `(details: ValidateArgs) => boolean` | No | Returns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. | | `value` | `string[]` | No | The controlled tag value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-empty]` | Present when the content is empty | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | clear-trigger | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-empty]` | Present when the content is empty | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **ItemInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-preview | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `string | number` | Yes | | | `value` | `string` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'label'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTagsInputReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `addOnPaste` | `boolean` | No | Whether to add a tag when you paste values into the tag input | | `allowOverflow` | `boolean` | No | Whether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether the input should be auto-focused | | `blurBehavior` | `'clear' | 'add'` | No | The behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value | | `defaultInputValue` | `string` | No | The initial tag input value when rendered. Use when you don't need to control the tag input value. | | `defaultValue` | `string[]` | No | The initial tag value when rendered. Use when you don't need to control the tag value. | | `delimiter` | `string | RegExp` | No | The character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input | | `disabled` | `boolean` | No | Whether the tags input should be disabled | | `editable` | `boolean` | No | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string input: string hiddenInput: string clearBtn: string label: string control: string item(opts: ItemProps): string itemDeleteTrigger(opts: ItemProps): string itemInput(opts: ItemProps): string }>` | No | The ids of the elements in the tags input. Useful for composition. | | `inputValue` | `string` | No | The controlled tag input's value | | `invalid` | `boolean` | No | Whether the tags input is invalid | | `max` | `number` | No | The max number of tags | | `maxLength` | `number` | No | The max length of the input. | | `modelValue` | `string[]` | No | The v-model value of the tags input | | `name` | `string` | No | The name attribute for the input. Useful for form submissions | | `readOnly` | `boolean` | No | Whether the tags input should be read-only | | `required` | `boolean` | No | Whether the tags input is required | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `validate` | `(details: ValidateArgs) => boolean` | No | Returns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-empty]` | Present when the content is empty | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | clear-trigger | | `[data-readonly]` | Present when read-only | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-empty]` | Present when the content is empty | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **ItemInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-preview | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `string | number` | Yes | | | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TagsInputApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `addOnPaste` | `boolean` | No | Whether to add a tag when you paste values into the tag input | | `allowOverflow` | `boolean` | No | Whether to allow tags to exceed max. In this case, we'll attach `data-invalid` to the root | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoFocus` | `boolean` | No | Whether the input should be auto-focused | | `blurBehavior` | `'clear' | 'add'` | No | The behavior of the tags input when the input is blurred - `"add"`: add the input value as a new tag - `"clear"`: clear the input value | | `defaultInputValue` | `string` | No | The initial tag input value when rendered. Use when you don't need to control the tag input value. | | `defaultValue` | `string[]` | No | The initial tag value when rendered. Use when you don't need to control the tag value. | | `delimiter` | `string | RegExp` | No | The character that serves has: - event key to trigger the addition of a new tag - character used to split tags when pasting into the input | | `disabled` | `boolean` | No | Whether the tags input should be disabled | | `editable` | `boolean` | No | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. | | `form` | `string` | No | The associate form of the underlying input element. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string input: string hiddenInput: string clearBtn: string label: string control: string item: (opts: ItemProps) => string itemDeleteTrigger: (opts: ItemProps) => string itemInput: (opts: ItemProps) => string }>` | No | The ids of the elements in the tags input. Useful for composition. | | `inputValue` | `string` | No | The controlled tag input's value | | `invalid` | `boolean` | No | Whether the tags input is invalid | | `max` | `number` | No | The max number of tags | | `maxLength` | `number` | No | The max length of the input. | | `name` | `string` | No | The name attribute for the input. Useful for form submissions | | `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component | | `onHighlightChange` | `(details: HighlightChangeDetails) => void` | No | Callback fired when a tag is highlighted by pointer or keyboard navigation | | `onInputValueChange` | `(details: InputValueChangeDetails) => void` | No | Callback fired when the input value is updated | | `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component | | `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Callback fired when the tag values is updated | | `onValueInvalid` | `(details: ValidityChangeDetails) => void` | No | Callback fired when the max tag count is reached or the `validateTag` function returns `false` | | `readOnly` | `boolean` | No | Whether the tags input should be read-only | | `ref` | `Element` | No | | | `required` | `boolean` | No | Whether the tags input is required | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states | | `validate` | `(details: ValidateArgs) => boolean` | No | Returns a boolean that determines whether a tag can be added. Useful for preventing duplicates or invalid tag values. | | `value` | `string[]` | No | The controlled tag value | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | root | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-empty]` | Present when the content is empty | **ClearTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ClearTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | clear-trigger | | `[data-readonly]` | Present when read-only | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTagsInputReturn]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Control Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | control | | `[data-disabled]` | Present when disabled | | `[data-readonly]` | Present when read-only | | `[data-invalid]` | Present when invalid | | `[data-focus]` | Present when focused | **HiddenInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Input Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | input | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-empty]` | Present when the content is empty | **ItemContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTagsInputItemContext]>` | Yes | | **ItemDeleteTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemDeleteTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-delete-trigger | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **ItemInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemPreview Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemPreview Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-preview | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `value` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item | | `[data-value]` | The value of the item | | `[data-disabled]` | Present when disabled | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-highlighted]` | Present when highlighted | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'label'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Label Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tags-input | | `[data-part]` | label | | `[data-disabled]` | Present when disabled | | `[data-invalid]` | Present when invalid | | `[data-readonly]` | Present when read-only | | `[data-required]` | Present when required | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTagsInputReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `empty` | `boolean` | Whether the tags are empty | | `inputValue` | `string` | The value of the tags entry input. | | `value` | `string[]` | The value of the tags as an array of strings. | | `valueAsString` | `string` | The value of the tags as a string. | | `count` | `number` | The number of the tags. | | `atMax` | `boolean` | Whether the tags have reached the max limit. | | `setValue` | `(value: string[]) => void` | Function to set the value of the tags. | | `clearValue` | `(id?: string) => void` | Function to clear the value of the tags. | | `addValue` | `(value: string) => void` | Function to add a tag to the tags. | | `setValueAtIndex` | `(index: number, value: string) => void` | Function to set the value of a tag at the given index. | | `setInputValue` | `(value: string) => void` | Function to set the value of the tags entry input. | | `clearInputValue` | `VoidFunction` | Function to clear the value of the tags entry input. | | `focus` | `VoidFunction` | Function to focus the tags entry input. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of a tag | ## Accessibility ### Keyboard Support **`ArrowLeft`** Description: Moves focus to the previous tag item **`ArrowRight`** Description: Moves focus to the next tag item **`Backspace`** Description: Deletes the tag item that has visual focus or the last tag item **`Enter`** Description: When a tag item has visual focus, it puts the tag in edit mode.
                    When the input has focus, it adds the value to the list of tags
                    **`Delete`** Description: Deletes the tag item that has visual focus **`Control + V`** Description: When `addOnPaste` is set. Adds the pasted value as a tags --- # Timer (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Basic = () => (
                    days
                    :
                    hours
                    :
                    minutes
                    :
                    seconds
                    Play Resume Pause
                    ) ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Basic = () => (
                    days
                    :
                    hours
                    :
                    minutes
                    :
                    seconds
                    Play Resume Pause
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    days
                    :
                    hours
                    :
                    minutes
                    :
                    seconds
                    Play Resume Pause
                    ``` ### Countdown You can create a countdown timer by setting the `countdown` prop to `true` and `startMs` to the initial time: **Example: countdown** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Countdown = () => (
                    minutes
                    :
                    seconds
                    Start Pause Reset
                    ) ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Countdown = () => (
                    minutes
                    :
                    seconds
                    Start Pause Reset
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    minutes
                    :
                    seconds
                    Start Pause Reset
                    ``` ### Interval Use the `interval` prop to control how frequently the timer updates. This is useful for displaying milliseconds: **Example: interval** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Interval = () => (
                    seconds
                    .
                    ms
                    Start Pause Reset
                    ) ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Interval = () => (
                    seconds
                    .
                    ms
                    Start Pause Reset
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    seconds
                    .
                    ms
                    Start Pause Reset
                    ``` ### Events The Timer component provides events that you can listen to for various timer-related actions. - The `onComplete` event is triggered when the timer reaches its target time. - The `onTick` event is called on each timer update, providing details about the current timer state. **Example: events** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PlayIcon, RotateCcwIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Events = () => { const [ticks, setTicks] = useState(0) return ( console.log('Timer completed')} onTick={() => setTicks((t) => t + 1)} >
                    minutes
                    :
                    seconds
                    Start Reset Ticks: {ticks}
                    ) } ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PlayIcon, RotateCcwIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Events = () => { const [ticks, setTicks] = createSignal(0) return ( console.log('Timer completed')} onTick={() => setTicks((t) => t + 1)} >
                    minutes
                    :
                    seconds
                    Start Reset Ticks: {ticks()}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    minutes
                    :
                    seconds
                    Start Reset Ticks: {ticks}
                    ``` ### Pomodoro Here's an example of building a pomodoro timer that alternates between work and break sessions: **Example: pomodoro** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Pomodoro = () => { const [isWorking, setIsWorking] = useState(true) const [cycles, setCycles] = useState(0) const handleComplete = () => { setIsWorking(!isWorking) if (!isWorking) setCycles((c) => c + 1) } return (

                    {isWorking ? 'Work Session' : 'Break Session'}

                    minutes
                    :
                    seconds
                    Start Pause Reset Completed cycles: {cycles}
                    ) } ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Pomodoro = () => { const [isWorking, setIsWorking] = createSignal(true) const [cycles, setCycles] = createSignal(0) const handleComplete = () => { setIsWorking(!isWorking()) if (!isWorking()) setCycles((c) => c + 1) } return (

                    {isWorking() ? 'Work Session' : 'Break Session'}

                    minutes
                    :
                    seconds
                    Start Pause Reset Completed cycles: {cycles()}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte

                    {isWorking ? 'Work Session' : 'Break Session'}

                    minutes
                    :
                    seconds
                    Start Pause Reset Completed cycles: {cycles}
                    ``` ### Root Provider An alternative way to control the timer is to use the `RootProvider` component and the `useTimer` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { Timer, useTimer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const RootProvider = () => { const timer = useTimer({ targetMs: 60 * 60 * 1000 }) return (
                    timer: {JSON.stringify(timer.time)}
                    hours
                    :
                    minutes
                    :
                    seconds
                    Start Resume Pause Reset
                    ) } ``` #### Solid ```tsx import { Timer, useTimer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const RootProvider = () => { const timer = useTimer({ targetMs: 60 * 60 * 1000 }) return (
                    timer: {JSON.stringify(timer().time)}
                    hours
                    :
                    minutes
                    :
                    seconds
                    Start Resume Pause Reset
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    timer: {JSON.stringify(timer().time)}
                    hours
                    :
                    minutes
                    :
                    seconds
                    Start Resume Pause Reset
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoStart` | `boolean` | No | Whether the timer should start automatically | | `countdown` | `boolean` | No | Whether the timer should countdown, decrementing the timer on each tick. | | `ids` | `Partial<{ root: string; area: string }>` | No | The ids of the timer parts | | `interval` | `number` | No | The interval in milliseconds to update the timer count. | | `onComplete` | `() => void` | No | Function invoked when the timer is completed | | `onTick` | `(details: TickDetails) => void` | No | Function invoked when the timer ticks | | `startMs` | `number` | No | The total duration of the timer in milliseconds. | | `targetMs` | `number` | No | The minimum count of the timer in milliseconds. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `TimerAction` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `keyof Time` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | timer | | `[data-part]` | item | | `[data-type]` | The type of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTimerReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoStart` | `boolean` | No | Whether the timer should start automatically | | `countdown` | `boolean` | No | Whether the timer should countdown, decrementing the timer on each tick. | | `ids` | `Partial<{ root: string; area: string }>` | No | The ids of the timer parts | | `interval` | `number` | No | The interval in milliseconds to update the timer count. | | `onComplete` | `() => void` | No | Function invoked when the timer is completed | | `onTick` | `(details: TickDetails) => void` | No | Function invoked when the timer ticks | | `startMs` | `number` | No | The total duration of the timer in milliseconds. | | `targetMs` | `number` | No | The minimum count of the timer in milliseconds. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `TimerAction` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `keyof Time` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | timer | | `[data-part]` | item | | `[data-type]` | The type of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTimerReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoStart` | `boolean` | No | Whether the timer should start automatically | | `countdown` | `boolean` | No | Whether the timer should countdown, decrementing the timer on each tick. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; area: string }>` | No | The ids of the timer parts | | `interval` | `number` | No | The interval in milliseconds to update the timer count. | | `startMs` | `number` | No | The total duration of the timer in milliseconds. | | `targetMs` | `number` | No | The minimum count of the timer in milliseconds. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `TimerAction` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `keyof Time` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | timer | | `[data-part]` | item | | `[data-type]` | The type of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TimerApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoStart` | `boolean` | No | Whether the timer should start automatically | | `countdown` | `boolean` | No | Whether the timer should countdown, decrementing the timer on each tick. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; area: string }>` | No | The ids of the timer parts | | `interval` | `number` | No | The interval in milliseconds to update the timer count. | | `onComplete` | `() => void` | No | Function invoked when the timer is completed | | `onTick` | `(details: TickDetails) => void` | No | Function invoked when the timer ticks | | `ref` | `Element` | No | | | `startMs` | `number` | No | The total duration of the timer in milliseconds. | | `targetMs` | `number` | No | The minimum count of the timer in milliseconds. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `TimerAction` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `api` | `Snippet<[UseTimerContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `keyof Time` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | timer | | `[data-part]` | item | | `[data-type]` | The type of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTimerReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `running` | `boolean` | Whether the timer is running. | | `paused` | `boolean` | Whether the timer is paused. | | `time` | `Time` | The formatted timer count value. | | `formattedTime` | `Time` | The formatted time parts of the timer count. | | `start` | `VoidFunction` | Function to start the timer. | | `pause` | `VoidFunction` | Function to pause the timer. | | `resume` | `VoidFunction` | Function to resume the timer. | | `reset` | `VoidFunction` | Function to reset the timer. | | `restart` | `VoidFunction` | Function to restart the timer. | | `progressPercent` | `number` | The progress percentage of the timer. | --- # Timer (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Basic = () => (
                    days
                    :
                    hours
                    :
                    minutes
                    :
                    seconds
                    Play Resume Pause
                    ) ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Basic = () => (
                    days
                    :
                    hours
                    :
                    minutes
                    :
                    seconds
                    Play Resume Pause
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    days
                    :
                    hours
                    :
                    minutes
                    :
                    seconds
                    Play Resume Pause
                    ``` ### Countdown You can create a countdown timer by setting the `countdown` prop to `true` and `startMs` to the initial time: **Example: countdown** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Countdown = () => (
                    minutes
                    :
                    seconds
                    Start Pause Reset
                    ) ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Countdown = () => (
                    minutes
                    :
                    seconds
                    Start Pause Reset
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    minutes
                    :
                    seconds
                    Start Pause Reset
                    ``` ### Interval Use the `interval` prop to control how frequently the timer updates. This is useful for displaying milliseconds: **Example: interval** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Interval = () => (
                    seconds
                    .
                    ms
                    Start Pause Reset
                    ) ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Interval = () => (
                    seconds
                    .
                    ms
                    Start Pause Reset
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    seconds
                    .
                    ms
                    Start Pause Reset
                    ``` ### Events The Timer component provides events that you can listen to for various timer-related actions. - The `onComplete` event is triggered when the timer reaches its target time. - The `onTick` event is called on each timer update, providing details about the current timer state. **Example: events** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PlayIcon, RotateCcwIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Events = () => { const [ticks, setTicks] = useState(0) return ( console.log('Timer completed')} onTick={() => setTicks((t) => t + 1)} >
                    minutes
                    :
                    seconds
                    Start Reset Ticks: {ticks}
                    ) } ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PlayIcon, RotateCcwIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Events = () => { const [ticks, setTicks] = createSignal(0) return ( console.log('Timer completed')} onTick={() => setTicks((t) => t + 1)} >
                    minutes
                    :
                    seconds
                    Start Reset Ticks: {ticks()}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    minutes
                    :
                    seconds
                    Start Reset Ticks: {ticks}
                    ``` ### Pomodoro Here's an example of building a pomodoro timer that alternates between work and break sessions: **Example: pomodoro** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Pomodoro = () => { const [isWorking, setIsWorking] = useState(true) const [cycles, setCycles] = useState(0) const handleComplete = () => { setIsWorking(!isWorking) if (!isWorking) setCycles((c) => c + 1) } return (

                    {isWorking ? 'Work Session' : 'Break Session'}

                    minutes
                    :
                    seconds
                    Start Pause Reset Completed cycles: {cycles}
                    ) } ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Pomodoro = () => { const [isWorking, setIsWorking] = createSignal(true) const [cycles, setCycles] = createSignal(0) const handleComplete = () => { setIsWorking(!isWorking()) if (!isWorking()) setCycles((c) => c + 1) } return (

                    {isWorking() ? 'Work Session' : 'Break Session'}

                    minutes
                    :
                    seconds
                    Start Pause Reset Completed cycles: {cycles()}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte

                    {isWorking ? 'Work Session' : 'Break Session'}

                    minutes
                    :
                    seconds
                    Start Pause Reset Completed cycles: {cycles}
                    ``` ### Root Provider An alternative way to control the timer is to use the `RootProvider` component and the `useTimer` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { Timer, useTimer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const RootProvider = () => { const timer = useTimer({ targetMs: 60 * 60 * 1000 }) return (
                    timer: {JSON.stringify(timer.time)}
                    hours
                    :
                    minutes
                    :
                    seconds
                    Start Resume Pause Reset
                    ) } ``` #### Solid ```tsx import { Timer, useTimer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const RootProvider = () => { const timer = useTimer({ targetMs: 60 * 60 * 1000 }) return (
                    timer: {JSON.stringify(timer().time)}
                    hours
                    :
                    minutes
                    :
                    seconds
                    Start Resume Pause Reset
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    timer: {JSON.stringify(timer().time)}
                    hours
                    :
                    minutes
                    :
                    seconds
                    Start Resume Pause Reset
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoStart` | `boolean` | No | Whether the timer should start automatically | | `countdown` | `boolean` | No | Whether the timer should countdown, decrementing the timer on each tick. | | `ids` | `Partial<{ root: string; area: string }>` | No | The ids of the timer parts | | `interval` | `number` | No | The interval in milliseconds to update the timer count. | | `onComplete` | `() => void` | No | Function invoked when the timer is completed | | `onTick` | `(details: TickDetails) => void` | No | Function invoked when the timer ticks | | `startMs` | `number` | No | The total duration of the timer in milliseconds. | | `targetMs` | `number` | No | The minimum count of the timer in milliseconds. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `TimerAction` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `keyof Time` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | timer | | `[data-part]` | item | | `[data-type]` | The type of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTimerReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoStart` | `boolean` | No | Whether the timer should start automatically | | `countdown` | `boolean` | No | Whether the timer should countdown, decrementing the timer on each tick. | | `ids` | `Partial<{ root: string; area: string }>` | No | The ids of the timer parts | | `interval` | `number` | No | The interval in milliseconds to update the timer count. | | `onComplete` | `() => void` | No | Function invoked when the timer is completed | | `onTick` | `(details: TickDetails) => void` | No | Function invoked when the timer ticks | | `startMs` | `number` | No | The total duration of the timer in milliseconds. | | `targetMs` | `number` | No | The minimum count of the timer in milliseconds. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `TimerAction` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `keyof Time` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | timer | | `[data-part]` | item | | `[data-type]` | The type of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTimerReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoStart` | `boolean` | No | Whether the timer should start automatically | | `countdown` | `boolean` | No | Whether the timer should countdown, decrementing the timer on each tick. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; area: string }>` | No | The ids of the timer parts | | `interval` | `number` | No | The interval in milliseconds to update the timer count. | | `startMs` | `number` | No | The total duration of the timer in milliseconds. | | `targetMs` | `number` | No | The minimum count of the timer in milliseconds. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `TimerAction` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `keyof Time` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | timer | | `[data-part]` | item | | `[data-type]` | The type of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TimerApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoStart` | `boolean` | No | Whether the timer should start automatically | | `countdown` | `boolean` | No | Whether the timer should countdown, decrementing the timer on each tick. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; area: string }>` | No | The ids of the timer parts | | `interval` | `number` | No | The interval in milliseconds to update the timer count. | | `onComplete` | `() => void` | No | Function invoked when the timer is completed | | `onTick` | `(details: TickDetails) => void` | No | Function invoked when the timer ticks | | `ref` | `Element` | No | | | `startMs` | `number` | No | The total duration of the timer in milliseconds. | | `targetMs` | `number` | No | The minimum count of the timer in milliseconds. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `TimerAction` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `api` | `Snippet<[UseTimerContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `keyof Time` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | timer | | `[data-part]` | item | | `[data-type]` | The type of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTimerReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `running` | `boolean` | Whether the timer is running. | | `paused` | `boolean` | Whether the timer is paused. | | `time` | `Time` | The formatted timer count value. | | `formattedTime` | `Time` | The formatted time parts of the timer count. | | `start` | `VoidFunction` | Function to start the timer. | | `pause` | `VoidFunction` | Function to pause the timer. | | `resume` | `VoidFunction` | Function to resume the timer. | | `reset` | `VoidFunction` | Function to reset the timer. | | `restart` | `VoidFunction` | Function to restart the timer. | | `progressPercent` | `number` | The progress percentage of the timer. | --- # Timer (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Basic = () => (
                    days
                    :
                    hours
                    :
                    minutes
                    :
                    seconds
                    Play Resume Pause
                    ) ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Basic = () => (
                    days
                    :
                    hours
                    :
                    minutes
                    :
                    seconds
                    Play Resume Pause
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    days
                    :
                    hours
                    :
                    minutes
                    :
                    seconds
                    Play Resume Pause
                    ``` ### Countdown You can create a countdown timer by setting the `countdown` prop to `true` and `startMs` to the initial time: **Example: countdown** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Countdown = () => (
                    minutes
                    :
                    seconds
                    Start Pause Reset
                    ) ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Countdown = () => (
                    minutes
                    :
                    seconds
                    Start Pause Reset
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    minutes
                    :
                    seconds
                    Start Pause Reset
                    ``` ### Interval Use the `interval` prop to control how frequently the timer updates. This is useful for displaying milliseconds: **Example: interval** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Interval = () => (
                    seconds
                    .
                    ms
                    Start Pause Reset
                    ) ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Interval = () => (
                    seconds
                    .
                    ms
                    Start Pause Reset
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    seconds
                    .
                    ms
                    Start Pause Reset
                    ``` ### Events The Timer component provides events that you can listen to for various timer-related actions. - The `onComplete` event is triggered when the timer reaches its target time. - The `onTick` event is called on each timer update, providing details about the current timer state. **Example: events** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PlayIcon, RotateCcwIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Events = () => { const [ticks, setTicks] = useState(0) return ( console.log('Timer completed')} onTick={() => setTicks((t) => t + 1)} >
                    minutes
                    :
                    seconds
                    Start Reset Ticks: {ticks}
                    ) } ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PlayIcon, RotateCcwIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Events = () => { const [ticks, setTicks] = createSignal(0) return ( console.log('Timer completed')} onTick={() => setTicks((t) => t + 1)} >
                    minutes
                    :
                    seconds
                    Start Reset Ticks: {ticks()}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    minutes
                    :
                    seconds
                    Start Reset Ticks: {ticks}
                    ``` ### Pomodoro Here's an example of building a pomodoro timer that alternates between work and break sessions: **Example: pomodoro** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Pomodoro = () => { const [isWorking, setIsWorking] = useState(true) const [cycles, setCycles] = useState(0) const handleComplete = () => { setIsWorking(!isWorking) if (!isWorking) setCycles((c) => c + 1) } return (

                    {isWorking ? 'Work Session' : 'Break Session'}

                    minutes
                    :
                    seconds
                    Start Pause Reset Completed cycles: {cycles}
                    ) } ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Pomodoro = () => { const [isWorking, setIsWorking] = createSignal(true) const [cycles, setCycles] = createSignal(0) const handleComplete = () => { setIsWorking(!isWorking()) if (!isWorking()) setCycles((c) => c + 1) } return (

                    {isWorking() ? 'Work Session' : 'Break Session'}

                    minutes
                    :
                    seconds
                    Start Pause Reset Completed cycles: {cycles()}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte

                    {isWorking ? 'Work Session' : 'Break Session'}

                    minutes
                    :
                    seconds
                    Start Pause Reset Completed cycles: {cycles}
                    ``` ### Root Provider An alternative way to control the timer is to use the `RootProvider` component and the `useTimer` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { Timer, useTimer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const RootProvider = () => { const timer = useTimer({ targetMs: 60 * 60 * 1000 }) return (
                    timer: {JSON.stringify(timer.time)}
                    hours
                    :
                    minutes
                    :
                    seconds
                    Start Resume Pause Reset
                    ) } ``` #### Solid ```tsx import { Timer, useTimer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const RootProvider = () => { const timer = useTimer({ targetMs: 60 * 60 * 1000 }) return (
                    timer: {JSON.stringify(timer().time)}
                    hours
                    :
                    minutes
                    :
                    seconds
                    Start Resume Pause Reset
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    timer: {JSON.stringify(timer().time)}
                    hours
                    :
                    minutes
                    :
                    seconds
                    Start Resume Pause Reset
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoStart` | `boolean` | No | Whether the timer should start automatically | | `countdown` | `boolean` | No | Whether the timer should countdown, decrementing the timer on each tick. | | `ids` | `Partial<{ root: string; area: string }>` | No | The ids of the timer parts | | `interval` | `number` | No | The interval in milliseconds to update the timer count. | | `onComplete` | `() => void` | No | Function invoked when the timer is completed | | `onTick` | `(details: TickDetails) => void` | No | Function invoked when the timer ticks | | `startMs` | `number` | No | The total duration of the timer in milliseconds. | | `targetMs` | `number` | No | The minimum count of the timer in milliseconds. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `TimerAction` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `keyof Time` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | timer | | `[data-part]` | item | | `[data-type]` | The type of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTimerReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoStart` | `boolean` | No | Whether the timer should start automatically | | `countdown` | `boolean` | No | Whether the timer should countdown, decrementing the timer on each tick. | | `ids` | `Partial<{ root: string; area: string }>` | No | The ids of the timer parts | | `interval` | `number` | No | The interval in milliseconds to update the timer count. | | `onComplete` | `() => void` | No | Function invoked when the timer is completed | | `onTick` | `(details: TickDetails) => void` | No | Function invoked when the timer ticks | | `startMs` | `number` | No | The total duration of the timer in milliseconds. | | `targetMs` | `number` | No | The minimum count of the timer in milliseconds. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `TimerAction` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `keyof Time` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | timer | | `[data-part]` | item | | `[data-type]` | The type of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTimerReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoStart` | `boolean` | No | Whether the timer should start automatically | | `countdown` | `boolean` | No | Whether the timer should countdown, decrementing the timer on each tick. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; area: string }>` | No | The ids of the timer parts | | `interval` | `number` | No | The interval in milliseconds to update the timer count. | | `startMs` | `number` | No | The total duration of the timer in milliseconds. | | `targetMs` | `number` | No | The minimum count of the timer in milliseconds. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `TimerAction` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `keyof Time` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | timer | | `[data-part]` | item | | `[data-type]` | The type of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TimerApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoStart` | `boolean` | No | Whether the timer should start automatically | | `countdown` | `boolean` | No | Whether the timer should countdown, decrementing the timer on each tick. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; area: string }>` | No | The ids of the timer parts | | `interval` | `number` | No | The interval in milliseconds to update the timer count. | | `onComplete` | `() => void` | No | Function invoked when the timer is completed | | `onTick` | `(details: TickDetails) => void` | No | Function invoked when the timer ticks | | `ref` | `Element` | No | | | `startMs` | `number` | No | The total duration of the timer in milliseconds. | | `targetMs` | `number` | No | The minimum count of the timer in milliseconds. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `TimerAction` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `api` | `Snippet<[UseTimerContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `keyof Time` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | timer | | `[data-part]` | item | | `[data-type]` | The type of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTimerReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `running` | `boolean` | Whether the timer is running. | | `paused` | `boolean` | Whether the timer is paused. | | `time` | `Time` | The formatted timer count value. | | `formattedTime` | `Time` | The formatted time parts of the timer count. | | `start` | `VoidFunction` | Function to start the timer. | | `pause` | `VoidFunction` | Function to pause the timer. | | `resume` | `VoidFunction` | Function to resume the timer. | | `reset` | `VoidFunction` | Function to reset the timer. | | `restart` | `VoidFunction` | Function to restart the timer. | | `progressPercent` | `number` | The progress percentage of the timer. | --- # Timer (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Basic = () => (
                    days
                    :
                    hours
                    :
                    minutes
                    :
                    seconds
                    Play Resume Pause
                    ) ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Basic = () => (
                    days
                    :
                    hours
                    :
                    minutes
                    :
                    seconds
                    Play Resume Pause
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    days
                    :
                    hours
                    :
                    minutes
                    :
                    seconds
                    Play Resume Pause
                    ``` ### Countdown You can create a countdown timer by setting the `countdown` prop to `true` and `startMs` to the initial time: **Example: countdown** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Countdown = () => (
                    minutes
                    :
                    seconds
                    Start Pause Reset
                    ) ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Countdown = () => (
                    minutes
                    :
                    seconds
                    Start Pause Reset
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    minutes
                    :
                    seconds
                    Start Pause Reset
                    ``` ### Interval Use the `interval` prop to control how frequently the timer updates. This is useful for displaying milliseconds: **Example: interval** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Interval = () => (
                    seconds
                    .
                    ms
                    Start Pause Reset
                    ) ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Interval = () => (
                    seconds
                    .
                    ms
                    Start Pause Reset
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    seconds
                    .
                    ms
                    Start Pause Reset
                    ``` ### Events The Timer component provides events that you can listen to for various timer-related actions. - The `onComplete` event is triggered when the timer reaches its target time. - The `onTick` event is called on each timer update, providing details about the current timer state. **Example: events** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PlayIcon, RotateCcwIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Events = () => { const [ticks, setTicks] = useState(0) return ( console.log('Timer completed')} onTick={() => setTicks((t) => t + 1)} >
                    minutes
                    :
                    seconds
                    Start Reset Ticks: {ticks}
                    ) } ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PlayIcon, RotateCcwIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Events = () => { const [ticks, setTicks] = createSignal(0) return ( console.log('Timer completed')} onTick={() => setTicks((t) => t + 1)} >
                    minutes
                    :
                    seconds
                    Start Reset Ticks: {ticks()}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    minutes
                    :
                    seconds
                    Start Reset Ticks: {ticks}
                    ``` ### Pomodoro Here's an example of building a pomodoro timer that alternates between work and break sessions: **Example: pomodoro** #### React ```tsx import { Timer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Pomodoro = () => { const [isWorking, setIsWorking] = useState(true) const [cycles, setCycles] = useState(0) const handleComplete = () => { setIsWorking(!isWorking) if (!isWorking) setCycles((c) => c + 1) } return (

                    {isWorking ? 'Work Session' : 'Break Session'}

                    minutes
                    :
                    seconds
                    Start Pause Reset Completed cycles: {cycles}
                    ) } ``` #### Solid ```tsx import { Timer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const Pomodoro = () => { const [isWorking, setIsWorking] = createSignal(true) const [cycles, setCycles] = createSignal(0) const handleComplete = () => { setIsWorking(!isWorking()) if (!isWorking()) setCycles((c) => c + 1) } return (

                    {isWorking() ? 'Work Session' : 'Break Session'}

                    minutes
                    :
                    seconds
                    Start Pause Reset Completed cycles: {cycles()}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte

                    {isWorking ? 'Work Session' : 'Break Session'}

                    minutes
                    :
                    seconds
                    Start Pause Reset Completed cycles: {cycles}
                    ``` ### Root Provider An alternative way to control the timer is to use the `RootProvider` component and the `useTimer` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { Timer, useTimer } from '@ark-ui/react/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const RootProvider = () => { const timer = useTimer({ targetMs: 60 * 60 * 1000 }) return (
                    timer: {JSON.stringify(timer.time)}
                    hours
                    :
                    minutes
                    :
                    seconds
                    Start Resume Pause Reset
                    ) } ``` #### Solid ```tsx import { Timer, useTimer } from '@ark-ui/solid/timer' import { PauseIcon, PlayIcon, RotateCcwIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/timer.module.css' export const RootProvider = () => { const timer = useTimer({ targetMs: 60 * 60 * 1000 }) return (
                    timer: {JSON.stringify(timer().time)}
                    hours
                    :
                    minutes
                    :
                    seconds
                    Start Resume Pause Reset
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    timer: {JSON.stringify(timer().time)}
                    hours
                    :
                    minutes
                    :
                    seconds
                    Start Resume Pause Reset
                    ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoStart` | `boolean` | No | Whether the timer should start automatically | | `countdown` | `boolean` | No | Whether the timer should countdown, decrementing the timer on each tick. | | `ids` | `Partial<{ root: string; area: string }>` | No | The ids of the timer parts | | `interval` | `number` | No | The interval in milliseconds to update the timer count. | | `onComplete` | `() => void` | No | Function invoked when the timer is completed | | `onTick` | `(details: TickDetails) => void` | No | Function invoked when the timer ticks | | `startMs` | `number` | No | The total duration of the timer in milliseconds. | | `targetMs` | `number` | No | The minimum count of the timer in milliseconds. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `TimerAction` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `keyof Time` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | timer | | `[data-part]` | item | | `[data-type]` | The type of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTimerReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoStart` | `boolean` | No | Whether the timer should start automatically | | `countdown` | `boolean` | No | Whether the timer should countdown, decrementing the timer on each tick. | | `ids` | `Partial<{ root: string; area: string }>` | No | The ids of the timer parts | | `interval` | `number` | No | The interval in milliseconds to update the timer count. | | `onComplete` | `() => void` | No | Function invoked when the timer is completed | | `onTick` | `(details: TickDetails) => void` | No | Function invoked when the timer ticks | | `startMs` | `number` | No | The total duration of the timer in milliseconds. | | `targetMs` | `number` | No | The minimum count of the timer in milliseconds. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `TimerAction` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `keyof Time` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | timer | | `[data-part]` | item | | `[data-type]` | The type of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTimerReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoStart` | `boolean` | No | Whether the timer should start automatically | | `countdown` | `boolean` | No | Whether the timer should countdown, decrementing the timer on each tick. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; area: string }>` | No | The ids of the timer parts | | `interval` | `number` | No | The interval in milliseconds to update the timer count. | | `startMs` | `number` | No | The total duration of the timer in milliseconds. | | `targetMs` | `number` | No | The minimum count of the timer in milliseconds. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `TimerAction` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `keyof Time` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | timer | | `[data-part]` | item | | `[data-type]` | The type of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TimerApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `autoStart` | `boolean` | No | Whether the timer should start automatically | | `countdown` | `boolean` | No | Whether the timer should countdown, decrementing the timer on each tick. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; area: string }>` | No | The ids of the timer parts | | `interval` | `number` | No | The interval in milliseconds to update the timer count. | | `onComplete` | `() => void` | No | Function invoked when the timer is completed | | `onTick` | `(details: TickDetails) => void` | No | Function invoked when the timer ticks | | `ref` | `Element` | No | | | `startMs` | `number` | No | The total duration of the timer in milliseconds. | | `targetMs` | `number` | No | The minimum count of the timer in milliseconds. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `TimerAction` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Area Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `api` | `Snippet<[UseTimerContext]>` | No | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `keyof Time` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | timer | | `[data-part]` | item | | `[data-type]` | The type of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--value` | The current value | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTimerReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Separator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `running` | `boolean` | Whether the timer is running. | | `paused` | `boolean` | Whether the timer is paused. | | `time` | `Time` | The formatted timer count value. | | `formattedTime` | `Time` | The formatted time parts of the timer count. | | `start` | `VoidFunction` | Function to start the timer. | | `pause` | `VoidFunction` | Function to pause the timer. | | `resume` | `VoidFunction` | Function to resume the timer. | | `reset` | `VoidFunction` | Function to reset the timer. | | `restart` | `VoidFunction` | Function to restart the timer. | | `progressPercent` | `number` | The progress percentage of the timer. | --- # Toast (REACT) ## Anatomy ```tsx const toaster = createToaster({ placement: 'bottom-end' }) {(toast) => ( )} ``` ## Setup To use the Toast component, create the toast engine using the `createToaster` function. This function manages the placement and grouping of toasts, and provides a `toast` object needed to create toast notification. ```ts const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 24, }) ``` ## Examples Here's an example of creating a toast using the `toast.create` method. **Example: basic** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 24, }) export const Basic = () => { return (
                    {(toast) => ( {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const Basic = () => { const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 24, }) return (
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ### Types You can create different types of toasts (`success`, `error`, `warning`, `info`) with appropriate styling. For example, to create a success toast, you can do: ```ts toaster.success({ title: 'Success!', description: 'Your changes have been saved.', }) ``` **Example: types** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { CircleAlertIcon, TriangleAlertIcon, CircleCheckIcon, InfoIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) const iconMap = { success: CircleCheckIcon, error: CircleAlertIcon, warning: TriangleAlertIcon, info: InfoIcon, } export const Types = () => { return (
                    {(toast) => { const ToastIcon = toast.type ? iconMap[toast.type as keyof typeof iconMap] : undefined return ( {ToastIcon && } {toast.title} {toast.description} ) }}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { CircleAlertIcon, CircleCheckIcon, InfoIcon, TriangleAlertIcon, XIcon } from 'lucide-solid' import { Dynamic } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const iconMap = { success: CircleCheckIcon, error: CircleAlertIcon, warning: TriangleAlertIcon, info: InfoIcon, } export const Types = () => { const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) return (
                    {(toast) => { const icon = () => (toast().type ? iconMap[toast().type as keyof typeof iconMap] : InfoIcon) return ( {toast().title} {toast().description} ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {@const icon = toast().type ? iconMap[toast().type as keyof typeof iconMap] : InfoIcon} {toast().title} {toast().description} {/snippet}
                    ``` ### Promise You can use `toaster.promise()` to automatically handle the different states of an asynchronous operation. It provides options for the `success`, `error`, and `loading` states of the promise and will automatically update the toast when the promise resolves or rejects. **Example: promise-toast** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon, LoaderIcon, CircleCheckIcon, CircleAlertIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) const uploadFile = () => { return new Promise((resolve, reject) => { setTimeout(() => { Math.random() > 0.5 ? resolve() : reject(new Error('Upload failed')) }, 2000) }) } export const PromiseToast = () => { const handleUpload = async () => { toaster.promise(uploadFile, { loading: { title: 'Uploading file...', description: 'Please wait while we upload your document.', }, success: { title: 'Upload complete', description: 'Your file has been uploaded successfully.', }, error: { title: 'Upload failed', description: 'Could not upload the file. Please try again.', }, }) } const getIcon = (type: string | undefined) => { switch (type) { case 'loading': return case 'success': return case 'error': return default: return null } } return (
                    {(toast) => ( {getIcon(toast.type)} {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { CircleAlertIcon, CircleCheckIcon, InfoIcon, LoaderIcon, XIcon } from 'lucide-solid' import { Dynamic } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const uploadFile = () => { return new Promise((resolve, reject) => { setTimeout(() => { Math.random() > 0.5 ? resolve() : reject(new Error('Upload failed')) }, 2000) }) } const iconMap = { loading: LoaderIcon, success: CircleCheckIcon, error: CircleAlertIcon, info: InfoIcon, } export const PromiseToast = () => { const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) const handleUpload = async () => { toaster.promise(uploadFile, { loading: { title: 'Uploading file...', description: 'Please wait while we process your file.', }, success: { title: 'Upload complete', description: 'Your file has been uploaded successfully.', }, error: { title: 'Upload failed', description: 'There was an error uploading your file. Please try again.', }, }) } return (
                    {(toast) => { const icon = () => (toast().type ? iconMap[toast().type as keyof typeof iconMap] : InfoIcon) return ( {toast().title} {toast().description} ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {@const icon = toast().type ? iconMap[toast().type as keyof typeof iconMap] : InfoIcon} {toast().title} {toast().description} {/snippet}
                    ``` ### Update To update a toast, use the `toast.update` method. **Example: update** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { useRef } from 'react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 24, }) export const Update = () => { const id = useRef(undefined) const createToast = () => { id.current = toaster.create({ title: 'Sending message...', description: 'Please wait while we deliver your message.', type: 'loading', }) } const updateToast = () => { if (!id.current) { return } toaster.update(id.current, { title: 'Message sent', description: 'Your message has been delivered successfully.', type: 'success', }) } return (
                    {(toast) => ( {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const Update = () => { const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 16, }) const [id, setId] = createSignal(undefined) const createToast = () => { const newId = toaster.create({ title: 'Uploading file...', description: 'Please wait while your file is being uploaded.', type: 'loading', }) setId(newId) } const updateToast = () => { const currentId = id() if (!currentId) { return } toaster.update(currentId, { title: 'Upload complete', description: 'Your file has been uploaded successfully.', type: 'success', }) } return (
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ### Action To add an action to a toast, use the `toast.action` property. **Example: action** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ placement: 'bottom-end', gap: 24, }) export const Action = () => { return (
                    {(toast) => ( {toast.title} {toast.description} {toast.action && ( {toast.action?.label} )} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const Action = () => { const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 16, }) return (
                    {(toast) => ( {toast().title} {toast().description} {toast().action && ( {toast().action?.label} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {#if toast().action} {toast().action?.label} {/if} {/snippet}
                    ``` ### Duration You can control how long a toast stays visible by setting a custom `duration` in milliseconds, or use `Infinity` to keep it visible until manually dismissed. **Example: duration** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon, ClockIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) const durations = [ { label: '1s', value: 1000 }, { label: '3s', value: 3000 }, { label: '5s', value: 5000 }, { label: '∞', value: Infinity }, ] export const Duration = () => { return (
                    {durations.map((duration) => ( ))}
                    {(toast) => ( {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const durations = [ { label: '1s', value: 1000 }, { label: '3s', value: 3000 }, { label: '5s', value: 5000 }, { label: '∞', value: Infinity }, ] export const Duration = () => { const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) return (
                    {(duration) => ( )}
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each durations as duration} {/each}
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ### Max Visible Set the `max` prop on the `createToaster` function to define the maximum number of toasts that can be rendered at any one time. Any extra toasts will be queued and rendered when a toast has been dismissed. **Example: max-toasts** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon, InfoIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ max: 3, overlap: true, placement: 'bottom-end', gap: 16, }) export const MaxToasts = () => { return (
                    {(toast) => (
                    {toast.title} {toast.description}
                    )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const MaxToasts = () => { const toaster = createToaster({ max: 3, overlap: true, placement: 'bottom-end', gap: 16, }) return (
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ### Placement Configure where toasts appear on the screen using the `placement` option in `createToaster`. Options include `top-start`, `top-end`, `bottom-start`, `bottom-end`, and more. **Example: placement** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ placement: 'top-end', overlap: true, gap: 16, }) export const Placement = () => { return (
                    {(toast) => ( {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const Placement = () => { const toaster = createToaster({ placement: 'top-end', overlap: true, gap: 16, }) return (
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ## Guides ### Toast in Effects When creating a toast inside React effects (like `useEffect`, `useLayoutEffect`, or event handlers that trigger during render), you may encounter a "flushSync" warning. To avoid this, wrap the toast call in `queueMicrotask`: ```tsx import { useEffect } from 'react' export const EffectToast = () => { useEffect(() => { // ❌ This may cause flushSync warnings // toaster.create({ title: 'Effect triggered!' }) // ✅ Wrap in queueMicrotask to avoid warnings queueMicrotask(() => { toaster.create({ title: 'Effect triggered!', description: 'This toast was called safely from an effect', type: 'success', }) }) }, []) return
                    Component content
                    } ``` This ensures the toast creation is deferred until after the current execution context, preventing React's concurrent rendering warnings. ### Styling There's a minimal styling required for the toast to work correctly. #### Toast root The toast root will be assigned these css properties at runtime: - `--x` - The x position - `--y` - The y position - `--scale` - The scale - `--z-index` - The z-index - `--height` - The height - `--opacity` - The opacity - `--gap` - The gap between toasts ```css [data-scope='toast'][data-part='root'] { translate: var(--x) var(--y); scale: var(--scale); z-index: var(--z-index); height: var(--height); opacity: var(--opacity); will-change: translate, opacity, scale; transition: translate 400ms, scale 400ms, opacity 400ms, height 400ms, box-shadow 200ms; transition-timing-function: cubic-bezier(0.21, 1.02, 0.73, 1); &[data-state='closed'] { transition: translate 400ms, scale 400ms, opacity 200ms; transition-timing-function: cubic-bezier(0.06, 0.71, 0.55, 1); } } ``` #### Styling based on type You can also style based on the `data-type` attribute. ```css [data-scope='toast'][data-part='root'] { &[data-type='error'] { background: red; color: white; } &[data-type='info'] { background: blue; color: white; } &[data-type='warning'] { background: orange; } &[data-type='success'] { background: green; color: white; } } ``` #### Mobile considerations A very common use case is to adjust the toast width on mobile so it spans the full width of the screen. ```css @media (max-width: 640px) { [data-scope='toast'][data-part='group'] { width: 100%; } [data-scope='toast'][data-part='root'] { inset-inline: 0; width: calc(100% - var(--gap) * 2); } } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toast | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the toast | | `[data-align]` | | | `[data-side]` | | | `[data-mounted]` | Present when mounted | | `[data-paused]` | Present when paused | | `[data-first]` | | | `[data-sibling]` | | | `[data-stack]` | | | `[data-overlap]` | Present when overlapping | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Toaster Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `toaster` | `CreateToasterReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `getRootNode` | `() => Node | ShadowRoot | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toast | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the toast | | `[data-align]` | | | `[data-side]` | | | `[data-mounted]` | Present when mounted | | `[data-paused]` | Present when paused | | `[data-first]` | | | `[data-sibling]` | | | `[data-stack]` | | | `[data-overlap]` | Present when overlapping | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Toaster Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `toaster` | `CreateToasterReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `getRootNode` | `() => Node | ShadowRoot | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toast | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the toast | | `[data-align]` | | | `[data-side]` | | | `[data-mounted]` | Present when mounted | | `[data-paused]` | Present when paused | | `[data-first]` | | | `[data-sibling]` | | | `[data-stack]` | | | `[data-overlap]` | Present when overlapping | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Toaster Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `toaster` | `CreateToasterReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toast | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the toast | | `[data-align]` | | | `[data-side]` | | | `[data-mounted]` | Present when mounted | | `[data-paused]` | Present when paused | | `[data-first]` | | | `[data-sibling]` | | | `[data-stack]` | | | `[data-overlap]` | Present when overlapping | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseToastContext]>` | Yes | | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Toaster Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `toaster` | `CreateToasterReturn` | Yes | The toaster instance. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `getRootNode` | `() => Node | ShadowRoot | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `getCount` | `() => number` | The total number of toasts | | `getToasts` | `() => ToastProps[]` | The toasts | | `subscribe` | `(callback: (toasts: Options[]) => void) => VoidFunction` | Subscribe to the toast group | --- # Toast (VUE) ## Anatomy ```tsx const toaster = createToaster({ placement: 'bottom-end' }) {(toast) => ( )} ``` ## Setup To use the Toast component, create the toast engine using the `createToaster` function. This function manages the placement and grouping of toasts, and provides a `toast` object needed to create toast notification. ```ts const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 24, }) ``` ## Examples Here's an example of creating a toast using the `toast.create` method. **Example: basic** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 24, }) export const Basic = () => { return (
                    {(toast) => ( {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const Basic = () => { const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 24, }) return (
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ### Types You can create different types of toasts (`success`, `error`, `warning`, `info`) with appropriate styling. For example, to create a success toast, you can do: ```ts toaster.success({ title: 'Success!', description: 'Your changes have been saved.', }) ``` **Example: types** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { CircleAlertIcon, TriangleAlertIcon, CircleCheckIcon, InfoIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) const iconMap = { success: CircleCheckIcon, error: CircleAlertIcon, warning: TriangleAlertIcon, info: InfoIcon, } export const Types = () => { return (
                    {(toast) => { const ToastIcon = toast.type ? iconMap[toast.type as keyof typeof iconMap] : undefined return ( {ToastIcon && } {toast.title} {toast.description} ) }}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { CircleAlertIcon, CircleCheckIcon, InfoIcon, TriangleAlertIcon, XIcon } from 'lucide-solid' import { Dynamic } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const iconMap = { success: CircleCheckIcon, error: CircleAlertIcon, warning: TriangleAlertIcon, info: InfoIcon, } export const Types = () => { const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) return (
                    {(toast) => { const icon = () => (toast().type ? iconMap[toast().type as keyof typeof iconMap] : InfoIcon) return ( {toast().title} {toast().description} ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {@const icon = toast().type ? iconMap[toast().type as keyof typeof iconMap] : InfoIcon} {toast().title} {toast().description} {/snippet}
                    ``` ### Promise You can use `toaster.promise()` to automatically handle the different states of an asynchronous operation. It provides options for the `success`, `error`, and `loading` states of the promise and will automatically update the toast when the promise resolves or rejects. **Example: promise-toast** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon, LoaderIcon, CircleCheckIcon, CircleAlertIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) const uploadFile = () => { return new Promise((resolve, reject) => { setTimeout(() => { Math.random() > 0.5 ? resolve() : reject(new Error('Upload failed')) }, 2000) }) } export const PromiseToast = () => { const handleUpload = async () => { toaster.promise(uploadFile, { loading: { title: 'Uploading file...', description: 'Please wait while we upload your document.', }, success: { title: 'Upload complete', description: 'Your file has been uploaded successfully.', }, error: { title: 'Upload failed', description: 'Could not upload the file. Please try again.', }, }) } const getIcon = (type: string | undefined) => { switch (type) { case 'loading': return case 'success': return case 'error': return default: return null } } return (
                    {(toast) => ( {getIcon(toast.type)} {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { CircleAlertIcon, CircleCheckIcon, InfoIcon, LoaderIcon, XIcon } from 'lucide-solid' import { Dynamic } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const uploadFile = () => { return new Promise((resolve, reject) => { setTimeout(() => { Math.random() > 0.5 ? resolve() : reject(new Error('Upload failed')) }, 2000) }) } const iconMap = { loading: LoaderIcon, success: CircleCheckIcon, error: CircleAlertIcon, info: InfoIcon, } export const PromiseToast = () => { const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) const handleUpload = async () => { toaster.promise(uploadFile, { loading: { title: 'Uploading file...', description: 'Please wait while we process your file.', }, success: { title: 'Upload complete', description: 'Your file has been uploaded successfully.', }, error: { title: 'Upload failed', description: 'There was an error uploading your file. Please try again.', }, }) } return (
                    {(toast) => { const icon = () => (toast().type ? iconMap[toast().type as keyof typeof iconMap] : InfoIcon) return ( {toast().title} {toast().description} ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {@const icon = toast().type ? iconMap[toast().type as keyof typeof iconMap] : InfoIcon} {toast().title} {toast().description} {/snippet}
                    ``` ### Update To update a toast, use the `toast.update` method. **Example: update** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { useRef } from 'react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 24, }) export const Update = () => { const id = useRef(undefined) const createToast = () => { id.current = toaster.create({ title: 'Sending message...', description: 'Please wait while we deliver your message.', type: 'loading', }) } const updateToast = () => { if (!id.current) { return } toaster.update(id.current, { title: 'Message sent', description: 'Your message has been delivered successfully.', type: 'success', }) } return (
                    {(toast) => ( {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const Update = () => { const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 16, }) const [id, setId] = createSignal(undefined) const createToast = () => { const newId = toaster.create({ title: 'Uploading file...', description: 'Please wait while your file is being uploaded.', type: 'loading', }) setId(newId) } const updateToast = () => { const currentId = id() if (!currentId) { return } toaster.update(currentId, { title: 'Upload complete', description: 'Your file has been uploaded successfully.', type: 'success', }) } return (
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ### Action To add an action to a toast, use the `toast.action` property. **Example: action** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ placement: 'bottom-end', gap: 24, }) export const Action = () => { return (
                    {(toast) => ( {toast.title} {toast.description} {toast.action && ( {toast.action?.label} )} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const Action = () => { const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 16, }) return (
                    {(toast) => ( {toast().title} {toast().description} {toast().action && ( {toast().action?.label} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {#if toast().action} {toast().action?.label} {/if} {/snippet}
                    ``` ### Duration You can control how long a toast stays visible by setting a custom `duration` in milliseconds, or use `Infinity` to keep it visible until manually dismissed. **Example: duration** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon, ClockIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) const durations = [ { label: '1s', value: 1000 }, { label: '3s', value: 3000 }, { label: '5s', value: 5000 }, { label: '∞', value: Infinity }, ] export const Duration = () => { return (
                    {durations.map((duration) => ( ))}
                    {(toast) => ( {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const durations = [ { label: '1s', value: 1000 }, { label: '3s', value: 3000 }, { label: '5s', value: 5000 }, { label: '∞', value: Infinity }, ] export const Duration = () => { const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) return (
                    {(duration) => ( )}
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each durations as duration} {/each}
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ### Max Visible Set the `max` prop on the `createToaster` function to define the maximum number of toasts that can be rendered at any one time. Any extra toasts will be queued and rendered when a toast has been dismissed. **Example: max-toasts** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon, InfoIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ max: 3, overlap: true, placement: 'bottom-end', gap: 16, }) export const MaxToasts = () => { return (
                    {(toast) => (
                    {toast.title} {toast.description}
                    )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const MaxToasts = () => { const toaster = createToaster({ max: 3, overlap: true, placement: 'bottom-end', gap: 16, }) return (
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ### Placement Configure where toasts appear on the screen using the `placement` option in `createToaster`. Options include `top-start`, `top-end`, `bottom-start`, `bottom-end`, and more. **Example: placement** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ placement: 'top-end', overlap: true, gap: 16, }) export const Placement = () => { return (
                    {(toast) => ( {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const Placement = () => { const toaster = createToaster({ placement: 'top-end', overlap: true, gap: 16, }) return (
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ## Guides ### Toast in Effects When creating a toast inside React effects (like `useEffect`, `useLayoutEffect`, or event handlers that trigger during render), you may encounter a "flushSync" warning. To avoid this, wrap the toast call in `queueMicrotask`: ```tsx import { useEffect } from 'react' export const EffectToast = () => { useEffect(() => { // ❌ This may cause flushSync warnings // toaster.create({ title: 'Effect triggered!' }) // ✅ Wrap in queueMicrotask to avoid warnings queueMicrotask(() => { toaster.create({ title: 'Effect triggered!', description: 'This toast was called safely from an effect', type: 'success', }) }) }, []) return
                    Component content
                    } ``` This ensures the toast creation is deferred until after the current execution context, preventing React's concurrent rendering warnings. ### Styling There's a minimal styling required for the toast to work correctly. #### Toast root The toast root will be assigned these css properties at runtime: - `--x` - The x position - `--y` - The y position - `--scale` - The scale - `--z-index` - The z-index - `--height` - The height - `--opacity` - The opacity - `--gap` - The gap between toasts ```css [data-scope='toast'][data-part='root'] { translate: var(--x) var(--y); scale: var(--scale); z-index: var(--z-index); height: var(--height); opacity: var(--opacity); will-change: translate, opacity, scale; transition: translate 400ms, scale 400ms, opacity 400ms, height 400ms, box-shadow 200ms; transition-timing-function: cubic-bezier(0.21, 1.02, 0.73, 1); &[data-state='closed'] { transition: translate 400ms, scale 400ms, opacity 200ms; transition-timing-function: cubic-bezier(0.06, 0.71, 0.55, 1); } } ``` #### Styling based on type You can also style based on the `data-type` attribute. ```css [data-scope='toast'][data-part='root'] { &[data-type='error'] { background: red; color: white; } &[data-type='info'] { background: blue; color: white; } &[data-type='warning'] { background: orange; } &[data-type='success'] { background: green; color: white; } } ``` #### Mobile considerations A very common use case is to adjust the toast width on mobile so it spans the full width of the screen. ```css @media (max-width: 640px) { [data-scope='toast'][data-part='group'] { width: 100%; } [data-scope='toast'][data-part='root'] { inset-inline: 0; width: calc(100% - var(--gap) * 2); } } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toast | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the toast | | `[data-align]` | | | `[data-side]` | | | `[data-mounted]` | Present when mounted | | `[data-paused]` | Present when paused | | `[data-first]` | | | `[data-sibling]` | | | `[data-stack]` | | | `[data-overlap]` | Present when overlapping | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Toaster Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `toaster` | `CreateToasterReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `getRootNode` | `() => Node | ShadowRoot | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toast | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the toast | | `[data-align]` | | | `[data-side]` | | | `[data-mounted]` | Present when mounted | | `[data-paused]` | Present when paused | | `[data-first]` | | | `[data-sibling]` | | | `[data-stack]` | | | `[data-overlap]` | Present when overlapping | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Toaster Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `toaster` | `CreateToasterReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `getRootNode` | `() => Node | ShadowRoot | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toast | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the toast | | `[data-align]` | | | `[data-side]` | | | `[data-mounted]` | Present when mounted | | `[data-paused]` | Present when paused | | `[data-first]` | | | `[data-sibling]` | | | `[data-stack]` | | | `[data-overlap]` | Present when overlapping | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Toaster Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `toaster` | `CreateToasterReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toast | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the toast | | `[data-align]` | | | `[data-side]` | | | `[data-mounted]` | Present when mounted | | `[data-paused]` | Present when paused | | `[data-first]` | | | `[data-sibling]` | | | `[data-stack]` | | | `[data-overlap]` | Present when overlapping | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseToastContext]>` | Yes | | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Toaster Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `toaster` | `CreateToasterReturn` | Yes | The toaster instance. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `getRootNode` | `() => Node | ShadowRoot | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `getCount` | `() => number` | The total number of toasts | | `getToasts` | `() => ToastProps[]` | The toasts | | `subscribe` | `(callback: (toasts: Options[]) => void) => VoidFunction` | Subscribe to the toast group | --- # Toast (SVELTE) ## Anatomy ```tsx const toaster = createToaster({ placement: 'bottom-end' }) {(toast) => ( )} ``` ## Setup To use the Toast component, create the toast engine using the `createToaster` function. This function manages the placement and grouping of toasts, and provides a `toast` object needed to create toast notification. ```ts const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 24, }) ``` ## Examples Here's an example of creating a toast using the `toast.create` method. **Example: basic** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 24, }) export const Basic = () => { return (
                    {(toast) => ( {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const Basic = () => { const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 24, }) return (
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ### Types You can create different types of toasts (`success`, `error`, `warning`, `info`) with appropriate styling. For example, to create a success toast, you can do: ```ts toaster.success({ title: 'Success!', description: 'Your changes have been saved.', }) ``` **Example: types** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { CircleAlertIcon, TriangleAlertIcon, CircleCheckIcon, InfoIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) const iconMap = { success: CircleCheckIcon, error: CircleAlertIcon, warning: TriangleAlertIcon, info: InfoIcon, } export const Types = () => { return (
                    {(toast) => { const ToastIcon = toast.type ? iconMap[toast.type as keyof typeof iconMap] : undefined return ( {ToastIcon && } {toast.title} {toast.description} ) }}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { CircleAlertIcon, CircleCheckIcon, InfoIcon, TriangleAlertIcon, XIcon } from 'lucide-solid' import { Dynamic } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const iconMap = { success: CircleCheckIcon, error: CircleAlertIcon, warning: TriangleAlertIcon, info: InfoIcon, } export const Types = () => { const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) return (
                    {(toast) => { const icon = () => (toast().type ? iconMap[toast().type as keyof typeof iconMap] : InfoIcon) return ( {toast().title} {toast().description} ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {@const icon = toast().type ? iconMap[toast().type as keyof typeof iconMap] : InfoIcon} {toast().title} {toast().description} {/snippet}
                    ``` ### Promise You can use `toaster.promise()` to automatically handle the different states of an asynchronous operation. It provides options for the `success`, `error`, and `loading` states of the promise and will automatically update the toast when the promise resolves or rejects. **Example: promise-toast** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon, LoaderIcon, CircleCheckIcon, CircleAlertIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) const uploadFile = () => { return new Promise((resolve, reject) => { setTimeout(() => { Math.random() > 0.5 ? resolve() : reject(new Error('Upload failed')) }, 2000) }) } export const PromiseToast = () => { const handleUpload = async () => { toaster.promise(uploadFile, { loading: { title: 'Uploading file...', description: 'Please wait while we upload your document.', }, success: { title: 'Upload complete', description: 'Your file has been uploaded successfully.', }, error: { title: 'Upload failed', description: 'Could not upload the file. Please try again.', }, }) } const getIcon = (type: string | undefined) => { switch (type) { case 'loading': return case 'success': return case 'error': return default: return null } } return (
                    {(toast) => ( {getIcon(toast.type)} {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { CircleAlertIcon, CircleCheckIcon, InfoIcon, LoaderIcon, XIcon } from 'lucide-solid' import { Dynamic } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const uploadFile = () => { return new Promise((resolve, reject) => { setTimeout(() => { Math.random() > 0.5 ? resolve() : reject(new Error('Upload failed')) }, 2000) }) } const iconMap = { loading: LoaderIcon, success: CircleCheckIcon, error: CircleAlertIcon, info: InfoIcon, } export const PromiseToast = () => { const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) const handleUpload = async () => { toaster.promise(uploadFile, { loading: { title: 'Uploading file...', description: 'Please wait while we process your file.', }, success: { title: 'Upload complete', description: 'Your file has been uploaded successfully.', }, error: { title: 'Upload failed', description: 'There was an error uploading your file. Please try again.', }, }) } return (
                    {(toast) => { const icon = () => (toast().type ? iconMap[toast().type as keyof typeof iconMap] : InfoIcon) return ( {toast().title} {toast().description} ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {@const icon = toast().type ? iconMap[toast().type as keyof typeof iconMap] : InfoIcon} {toast().title} {toast().description} {/snippet}
                    ``` ### Update To update a toast, use the `toast.update` method. **Example: update** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { useRef } from 'react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 24, }) export const Update = () => { const id = useRef(undefined) const createToast = () => { id.current = toaster.create({ title: 'Sending message...', description: 'Please wait while we deliver your message.', type: 'loading', }) } const updateToast = () => { if (!id.current) { return } toaster.update(id.current, { title: 'Message sent', description: 'Your message has been delivered successfully.', type: 'success', }) } return (
                    {(toast) => ( {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const Update = () => { const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 16, }) const [id, setId] = createSignal(undefined) const createToast = () => { const newId = toaster.create({ title: 'Uploading file...', description: 'Please wait while your file is being uploaded.', type: 'loading', }) setId(newId) } const updateToast = () => { const currentId = id() if (!currentId) { return } toaster.update(currentId, { title: 'Upload complete', description: 'Your file has been uploaded successfully.', type: 'success', }) } return (
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ### Action To add an action to a toast, use the `toast.action` property. **Example: action** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ placement: 'bottom-end', gap: 24, }) export const Action = () => { return (
                    {(toast) => ( {toast.title} {toast.description} {toast.action && ( {toast.action?.label} )} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const Action = () => { const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 16, }) return (
                    {(toast) => ( {toast().title} {toast().description} {toast().action && ( {toast().action?.label} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {#if toast().action} {toast().action?.label} {/if} {/snippet}
                    ``` ### Duration You can control how long a toast stays visible by setting a custom `duration` in milliseconds, or use `Infinity` to keep it visible until manually dismissed. **Example: duration** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon, ClockIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) const durations = [ { label: '1s', value: 1000 }, { label: '3s', value: 3000 }, { label: '5s', value: 5000 }, { label: '∞', value: Infinity }, ] export const Duration = () => { return (
                    {durations.map((duration) => ( ))}
                    {(toast) => ( {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const durations = [ { label: '1s', value: 1000 }, { label: '3s', value: 3000 }, { label: '5s', value: 5000 }, { label: '∞', value: Infinity }, ] export const Duration = () => { const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) return (
                    {(duration) => ( )}
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each durations as duration} {/each}
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ### Max Visible Set the `max` prop on the `createToaster` function to define the maximum number of toasts that can be rendered at any one time. Any extra toasts will be queued and rendered when a toast has been dismissed. **Example: max-toasts** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon, InfoIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ max: 3, overlap: true, placement: 'bottom-end', gap: 16, }) export const MaxToasts = () => { return (
                    {(toast) => (
                    {toast.title} {toast.description}
                    )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const MaxToasts = () => { const toaster = createToaster({ max: 3, overlap: true, placement: 'bottom-end', gap: 16, }) return (
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ### Placement Configure where toasts appear on the screen using the `placement` option in `createToaster`. Options include `top-start`, `top-end`, `bottom-start`, `bottom-end`, and more. **Example: placement** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ placement: 'top-end', overlap: true, gap: 16, }) export const Placement = () => { return (
                    {(toast) => ( {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const Placement = () => { const toaster = createToaster({ placement: 'top-end', overlap: true, gap: 16, }) return (
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ## Guides ### Toast in Effects When creating a toast inside React effects (like `useEffect`, `useLayoutEffect`, or event handlers that trigger during render), you may encounter a "flushSync" warning. To avoid this, wrap the toast call in `queueMicrotask`: ```tsx import { useEffect } from 'react' export const EffectToast = () => { useEffect(() => { // ❌ This may cause flushSync warnings // toaster.create({ title: 'Effect triggered!' }) // ✅ Wrap in queueMicrotask to avoid warnings queueMicrotask(() => { toaster.create({ title: 'Effect triggered!', description: 'This toast was called safely from an effect', type: 'success', }) }) }, []) return
                    Component content
                    } ``` This ensures the toast creation is deferred until after the current execution context, preventing React's concurrent rendering warnings. ### Styling There's a minimal styling required for the toast to work correctly. #### Toast root The toast root will be assigned these css properties at runtime: - `--x` - The x position - `--y` - The y position - `--scale` - The scale - `--z-index` - The z-index - `--height` - The height - `--opacity` - The opacity - `--gap` - The gap between toasts ```css [data-scope='toast'][data-part='root'] { translate: var(--x) var(--y); scale: var(--scale); z-index: var(--z-index); height: var(--height); opacity: var(--opacity); will-change: translate, opacity, scale; transition: translate 400ms, scale 400ms, opacity 400ms, height 400ms, box-shadow 200ms; transition-timing-function: cubic-bezier(0.21, 1.02, 0.73, 1); &[data-state='closed'] { transition: translate 400ms, scale 400ms, opacity 200ms; transition-timing-function: cubic-bezier(0.06, 0.71, 0.55, 1); } } ``` #### Styling based on type You can also style based on the `data-type` attribute. ```css [data-scope='toast'][data-part='root'] { &[data-type='error'] { background: red; color: white; } &[data-type='info'] { background: blue; color: white; } &[data-type='warning'] { background: orange; } &[data-type='success'] { background: green; color: white; } } ``` #### Mobile considerations A very common use case is to adjust the toast width on mobile so it spans the full width of the screen. ```css @media (max-width: 640px) { [data-scope='toast'][data-part='group'] { width: 100%; } [data-scope='toast'][data-part='root'] { inset-inline: 0; width: calc(100% - var(--gap) * 2); } } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toast | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the toast | | `[data-align]` | | | `[data-side]` | | | `[data-mounted]` | Present when mounted | | `[data-paused]` | Present when paused | | `[data-first]` | | | `[data-sibling]` | | | `[data-stack]` | | | `[data-overlap]` | Present when overlapping | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Toaster Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `toaster` | `CreateToasterReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `getRootNode` | `() => Node | ShadowRoot | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toast | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the toast | | `[data-align]` | | | `[data-side]` | | | `[data-mounted]` | Present when mounted | | `[data-paused]` | Present when paused | | `[data-first]` | | | `[data-sibling]` | | | `[data-stack]` | | | `[data-overlap]` | Present when overlapping | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Toaster Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `toaster` | `CreateToasterReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `getRootNode` | `() => Node | ShadowRoot | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toast | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the toast | | `[data-align]` | | | `[data-side]` | | | `[data-mounted]` | Present when mounted | | `[data-paused]` | Present when paused | | `[data-first]` | | | `[data-sibling]` | | | `[data-stack]` | | | `[data-overlap]` | Present when overlapping | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Toaster Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `toaster` | `CreateToasterReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toast | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the toast | | `[data-align]` | | | `[data-side]` | | | `[data-mounted]` | Present when mounted | | `[data-paused]` | Present when paused | | `[data-first]` | | | `[data-sibling]` | | | `[data-stack]` | | | `[data-overlap]` | Present when overlapping | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseToastContext]>` | Yes | | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Toaster Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `toaster` | `CreateToasterReturn` | Yes | The toaster instance. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `getRootNode` | `() => Node | ShadowRoot | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `getCount` | `() => number` | The total number of toasts | | `getToasts` | `() => ToastProps[]` | The toasts | | `subscribe` | `(callback: (toasts: Options[]) => void) => VoidFunction` | Subscribe to the toast group | --- # Toast (SOLID) ## Anatomy ```tsx const toaster = createToaster({ placement: 'bottom-end' }) {(toast) => ( )} ``` ## Setup To use the Toast component, create the toast engine using the `createToaster` function. This function manages the placement and grouping of toasts, and provides a `toast` object needed to create toast notification. ```ts const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 24, }) ``` ## Examples Here's an example of creating a toast using the `toast.create` method. **Example: basic** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 24, }) export const Basic = () => { return (
                    {(toast) => ( {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const Basic = () => { const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 24, }) return (
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ### Types You can create different types of toasts (`success`, `error`, `warning`, `info`) with appropriate styling. For example, to create a success toast, you can do: ```ts toaster.success({ title: 'Success!', description: 'Your changes have been saved.', }) ``` **Example: types** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { CircleAlertIcon, TriangleAlertIcon, CircleCheckIcon, InfoIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) const iconMap = { success: CircleCheckIcon, error: CircleAlertIcon, warning: TriangleAlertIcon, info: InfoIcon, } export const Types = () => { return (
                    {(toast) => { const ToastIcon = toast.type ? iconMap[toast.type as keyof typeof iconMap] : undefined return ( {ToastIcon && } {toast.title} {toast.description} ) }}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { CircleAlertIcon, CircleCheckIcon, InfoIcon, TriangleAlertIcon, XIcon } from 'lucide-solid' import { Dynamic } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const iconMap = { success: CircleCheckIcon, error: CircleAlertIcon, warning: TriangleAlertIcon, info: InfoIcon, } export const Types = () => { const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) return (
                    {(toast) => { const icon = () => (toast().type ? iconMap[toast().type as keyof typeof iconMap] : InfoIcon) return ( {toast().title} {toast().description} ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {@const icon = toast().type ? iconMap[toast().type as keyof typeof iconMap] : InfoIcon} {toast().title} {toast().description} {/snippet}
                    ``` ### Promise You can use `toaster.promise()` to automatically handle the different states of an asynchronous operation. It provides options for the `success`, `error`, and `loading` states of the promise and will automatically update the toast when the promise resolves or rejects. **Example: promise-toast** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon, LoaderIcon, CircleCheckIcon, CircleAlertIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) const uploadFile = () => { return new Promise((resolve, reject) => { setTimeout(() => { Math.random() > 0.5 ? resolve() : reject(new Error('Upload failed')) }, 2000) }) } export const PromiseToast = () => { const handleUpload = async () => { toaster.promise(uploadFile, { loading: { title: 'Uploading file...', description: 'Please wait while we upload your document.', }, success: { title: 'Upload complete', description: 'Your file has been uploaded successfully.', }, error: { title: 'Upload failed', description: 'Could not upload the file. Please try again.', }, }) } const getIcon = (type: string | undefined) => { switch (type) { case 'loading': return case 'success': return case 'error': return default: return null } } return (
                    {(toast) => ( {getIcon(toast.type)} {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { CircleAlertIcon, CircleCheckIcon, InfoIcon, LoaderIcon, XIcon } from 'lucide-solid' import { Dynamic } from 'solid-js/web' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const uploadFile = () => { return new Promise((resolve, reject) => { setTimeout(() => { Math.random() > 0.5 ? resolve() : reject(new Error('Upload failed')) }, 2000) }) } const iconMap = { loading: LoaderIcon, success: CircleCheckIcon, error: CircleAlertIcon, info: InfoIcon, } export const PromiseToast = () => { const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) const handleUpload = async () => { toaster.promise(uploadFile, { loading: { title: 'Uploading file...', description: 'Please wait while we process your file.', }, success: { title: 'Upload complete', description: 'Your file has been uploaded successfully.', }, error: { title: 'Upload failed', description: 'There was an error uploading your file. Please try again.', }, }) } return (
                    {(toast) => { const icon = () => (toast().type ? iconMap[toast().type as keyof typeof iconMap] : InfoIcon) return ( {toast().title} {toast().description} ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {@const icon = toast().type ? iconMap[toast().type as keyof typeof iconMap] : InfoIcon} {toast().title} {toast().description} {/snippet}
                    ``` ### Update To update a toast, use the `toast.update` method. **Example: update** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { useRef } from 'react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 24, }) export const Update = () => { const id = useRef(undefined) const createToast = () => { id.current = toaster.create({ title: 'Sending message...', description: 'Please wait while we deliver your message.', type: 'loading', }) } const updateToast = () => { if (!id.current) { return } toaster.update(id.current, { title: 'Message sent', description: 'Your message has been delivered successfully.', type: 'success', }) } return (
                    {(toast) => ( {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const Update = () => { const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 16, }) const [id, setId] = createSignal(undefined) const createToast = () => { const newId = toaster.create({ title: 'Uploading file...', description: 'Please wait while your file is being uploaded.', type: 'loading', }) setId(newId) } const updateToast = () => { const currentId = id() if (!currentId) { return } toaster.update(currentId, { title: 'Upload complete', description: 'Your file has been uploaded successfully.', type: 'success', }) } return (
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ### Action To add an action to a toast, use the `toast.action` property. **Example: action** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ placement: 'bottom-end', gap: 24, }) export const Action = () => { return (
                    {(toast) => ( {toast.title} {toast.description} {toast.action && ( {toast.action?.label} )} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const Action = () => { const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 16, }) return (
                    {(toast) => ( {toast().title} {toast().description} {toast().action && ( {toast().action?.label} )} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {#if toast().action} {toast().action?.label} {/if} {/snippet}
                    ``` ### Duration You can control how long a toast stays visible by setting a custom `duration` in milliseconds, or use `Infinity` to keep it visible until manually dismissed. **Example: duration** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon, ClockIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) const durations = [ { label: '1s', value: 1000 }, { label: '3s', value: 3000 }, { label: '5s', value: 5000 }, { label: '∞', value: Infinity }, ] export const Duration = () => { return (
                    {durations.map((duration) => ( ))}
                    {(toast) => ( {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const durations = [ { label: '1s', value: 1000 }, { label: '3s', value: 3000 }, { label: '5s', value: 5000 }, { label: '∞', value: Infinity }, ] export const Duration = () => { const toaster = createToaster({ overlap: true, placement: 'bottom-end', gap: 16, }) return (
                    {(duration) => ( )}
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each durations as duration} {/each}
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ### Max Visible Set the `max` prop on the `createToaster` function to define the maximum number of toasts that can be rendered at any one time. Any extra toasts will be queued and rendered when a toast has been dismissed. **Example: max-toasts** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon, InfoIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ max: 3, overlap: true, placement: 'bottom-end', gap: 16, }) export const MaxToasts = () => { return (
                    {(toast) => (
                    {toast.title} {toast.description}
                    )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const MaxToasts = () => { const toaster = createToaster({ max: 3, overlap: true, placement: 'bottom-end', gap: 16, }) return (
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ### Placement Configure where toasts appear on the screen using the `placement` option in `createToaster`. Options include `top-start`, `top-end`, `bottom-start`, `bottom-end`, and more. **Example: placement** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Toast, Toaster, createToaster } from '@ark-ui/react/toast' import { XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' const toaster = createToaster({ placement: 'top-end', overlap: true, gap: 16, }) export const Placement = () => { return (
                    {(toast) => ( {toast.title} {toast.description} )}
                    ) } ``` #### Solid ```tsx import { Portal } from 'solid-js/web' import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast' import { XIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/toast.module.css' export const Placement = () => { const toaster = createToaster({ placement: 'top-end', overlap: true, gap: 16, }) return (
                    {(toast) => ( {toast().title} {toast().description} )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(toast)} {toast().title} {toast().description} {/snippet}
                    ``` ## Guides ### Toast in Effects When creating a toast inside React effects (like `useEffect`, `useLayoutEffect`, or event handlers that trigger during render), you may encounter a "flushSync" warning. To avoid this, wrap the toast call in `queueMicrotask`: ```tsx import { useEffect } from 'react' export const EffectToast = () => { useEffect(() => { // ❌ This may cause flushSync warnings // toaster.create({ title: 'Effect triggered!' }) // ✅ Wrap in queueMicrotask to avoid warnings queueMicrotask(() => { toaster.create({ title: 'Effect triggered!', description: 'This toast was called safely from an effect', type: 'success', }) }) }, []) return
                    Component content
                    } ``` This ensures the toast creation is deferred until after the current execution context, preventing React's concurrent rendering warnings. ### Styling There's a minimal styling required for the toast to work correctly. #### Toast root The toast root will be assigned these css properties at runtime: - `--x` - The x position - `--y` - The y position - `--scale` - The scale - `--z-index` - The z-index - `--height` - The height - `--opacity` - The opacity - `--gap` - The gap between toasts ```css [data-scope='toast'][data-part='root'] { translate: var(--x) var(--y); scale: var(--scale); z-index: var(--z-index); height: var(--height); opacity: var(--opacity); will-change: translate, opacity, scale; transition: translate 400ms, scale 400ms, opacity 400ms, height 400ms, box-shadow 200ms; transition-timing-function: cubic-bezier(0.21, 1.02, 0.73, 1); &[data-state='closed'] { transition: translate 400ms, scale 400ms, opacity 200ms; transition-timing-function: cubic-bezier(0.06, 0.71, 0.55, 1); } } ``` #### Styling based on type You can also style based on the `data-type` attribute. ```css [data-scope='toast'][data-part='root'] { &[data-type='error'] { background: red; color: white; } &[data-type='info'] { background: blue; color: white; } &[data-type='warning'] { background: orange; } &[data-type='success'] { background: green; color: white; } } ``` #### Mobile considerations A very common use case is to adjust the toast width on mobile so it spans the full width of the screen. ```css @media (max-width: 640px) { [data-scope='toast'][data-part='group'] { width: 100%; } [data-scope='toast'][data-part='root'] { inset-inline: 0; width: calc(100% - var(--gap) * 2); } } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toast | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the toast | | `[data-align]` | | | `[data-side]` | | | `[data-mounted]` | Present when mounted | | `[data-paused]` | Present when paused | | `[data-first]` | | | `[data-sibling]` | | | `[data-stack]` | | | `[data-overlap]` | Present when overlapping | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Toaster Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `toaster` | `CreateToasterReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `getRootNode` | `() => Node | ShadowRoot | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toast | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the toast | | `[data-align]` | | | `[data-side]` | | | `[data-mounted]` | Present when mounted | | `[data-paused]` | Present when paused | | `[data-first]` | | | `[data-sibling]` | | | `[data-stack]` | | | `[data-overlap]` | Present when overlapping | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Toaster Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `toaster` | `CreateToasterReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `getRootNode` | `() => Node | ShadowRoot | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toast | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the toast | | `[data-align]` | | | `[data-side]` | | | `[data-mounted]` | Present when mounted | | `[data-paused]` | Present when paused | | `[data-first]` | | | `[data-sibling]` | | | `[data-stack]` | | | `[data-overlap]` | Present when overlapping | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Toaster Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `toaster` | `CreateToasterReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toast | | `[data-part]` | root | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the toast | | `[data-align]` | | | `[data-side]` | | | `[data-mounted]` | Present when mounted | | `[data-paused]` | Present when paused | | `[data-first]` | | | `[data-sibling]` | | | `[data-stack]` | | | `[data-overlap]` | Present when overlapping | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseToastContext]>` | Yes | | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Toaster Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `toaster` | `CreateToasterReturn` | Yes | The toaster instance. | | `dir` | `'ltr' | 'rtl'` | No | The document's text/writing direction. | | `getRootNode` | `() => Node | ShadowRoot | Document` | No | A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `getCount` | `() => number` | The total number of toasts | | `getToasts` | `() => ToastProps[]` | The toasts | | `subscribe` | `(callback: (toasts: Options[]) => void) => VoidFunction` | Subscribe to the toast group | --- # Toggle (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Toggle } from '@ark-ui/react/toggle' import { BoldIcon } from 'lucide-react' import styles from 'styles/toggle.module.css' export const Basic = () => { return ( ) } ``` #### Solid ```tsx import { Toggle } from '@ark-ui/solid/toggle' import { BoldIcon } from 'lucide-solid' import styles from 'styles/toggle.module.css' export const Basic = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### Controlled Use the `pressed` and `onPressedChange` props to control the toggle's state. **Example: controlled** #### React ```tsx import { Toggle } from '@ark-ui/react/toggle' import { HeartIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/toggle.module.css' export const Controlled = () => { const [pressed, setPressed] = useState(false) return ( }> ) } ``` #### Solid ```tsx import { Toggle } from '@ark-ui/solid/toggle' import { HeartIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/toggle.module.css' export const Controlled = () => { const [pressed, setPressed] = createSignal(false) return ( }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet fallback()} {/snippet} ``` ### Disabled Use the `disabled` prop to disable the toggle. **Example: disabled** #### React ```tsx import { Toggle } from '@ark-ui/react/toggle' import { BoldIcon } from 'lucide-react' import styles from 'styles/toggle.module.css' export const Disabled = () => { return ( ) } ``` #### Solid ```tsx import { Toggle } from '@ark-ui/solid/toggle' import { BoldIcon } from 'lucide-solid' import styles from 'styles/toggle.module.css' export const Disabled = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### Indicator Use the `Toggle.Indicator` component to render different indicators based on the state of the toggle. **Example: indicator** #### React ```tsx import { Toggle } from '@ark-ui/react/toggle' import { HeartIcon } from 'lucide-react' import styles from 'styles/toggle.module.css' export const Indicator = () => { return ( }> ) } ``` #### Solid ```tsx import { Toggle } from '@ark-ui/solid/toggle' import { HeartIcon } from 'lucide-solid' import styles from 'styles/toggle.module.css' export const Indicator = () => { return ( }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet fallback()} {/snippet} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPressed` | `boolean` | No | The default pressed state of the toggle. | | `onPressedChange` | `(pressed: boolean) => void` | No | Event handler called when the pressed state of the toggle changes. | | `pressed` | `boolean` | No | The pressed state of the toggle. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | root | | `[data-state]` | "on" | "off" | | `[data-pressed]` | Present when pressed | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | The fallback content to render when the toggle is not pressed. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-pressed]` | Present when pressed | | `[data-state]` | "on" | "off" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPressed` | `boolean` | No | The default pressed state of the toggle. | | `onPressedChange` | `(pressed: boolean) => void` | No | Event handler called when the pressed state of the toggle changes. | | `pressed` | `boolean` | No | The pressed state of the toggle. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | root | | `[data-state]` | "on" | "off" | | `[data-pressed]` | Present when pressed | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `number | boolean | Node | ArrayElement | (string & {})` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-pressed]` | Present when pressed | | `[data-state]` | "on" | "off" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPressed` | `boolean` | No | The default pressed state of the toggle. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `pressed` | `boolean` | No | The pressed state of the toggle. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | root | | `[data-state]` | "on" | "off" | | `[data-pressed]` | Present when pressed | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-pressed]` | Present when pressed | | `[data-state]` | "on" | "off" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPressed` | `boolean` | No | The default pressed state of the toggle. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `onPressedChange` | `(pressed: boolean) => void` | No | Event handler called when the pressed state of the toggle changes. | | `pressed` | `boolean` | No | The pressed state of the toggle. | | `ref` | `Element` | No | | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | root | | `[data-state]` | "on" | "off" | | `[data-pressed]` | Present when pressed | | `[data-disabled]` | Present when disabled | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseToggleContext]>` | Yes | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `Snippet<[]>` | No | The fallback content to render when the toggle is not pressed. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-pressed]` | Present when pressed | | `[data-state]` | "on" | "off" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `pressed` | `boolean` | Whether the toggle is pressed. | | `disabled` | `boolean` | Whether the toggle is disabled. | | `setPressed` | `(pressed: boolean) => void` | Sets the pressed state of the toggle. | --- # Toggle (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Toggle } from '@ark-ui/react/toggle' import { BoldIcon } from 'lucide-react' import styles from 'styles/toggle.module.css' export const Basic = () => { return ( ) } ``` #### Solid ```tsx import { Toggle } from '@ark-ui/solid/toggle' import { BoldIcon } from 'lucide-solid' import styles from 'styles/toggle.module.css' export const Basic = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### Controlled Use the `pressed` and `onPressedChange` props to control the toggle's state. **Example: controlled** #### React ```tsx import { Toggle } from '@ark-ui/react/toggle' import { HeartIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/toggle.module.css' export const Controlled = () => { const [pressed, setPressed] = useState(false) return ( }> ) } ``` #### Solid ```tsx import { Toggle } from '@ark-ui/solid/toggle' import { HeartIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/toggle.module.css' export const Controlled = () => { const [pressed, setPressed] = createSignal(false) return ( }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet fallback()} {/snippet} ``` ### Disabled Use the `disabled` prop to disable the toggle. **Example: disabled** #### React ```tsx import { Toggle } from '@ark-ui/react/toggle' import { BoldIcon } from 'lucide-react' import styles from 'styles/toggle.module.css' export const Disabled = () => { return ( ) } ``` #### Solid ```tsx import { Toggle } from '@ark-ui/solid/toggle' import { BoldIcon } from 'lucide-solid' import styles from 'styles/toggle.module.css' export const Disabled = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### Indicator Use the `Toggle.Indicator` component to render different indicators based on the state of the toggle. **Example: indicator** #### React ```tsx import { Toggle } from '@ark-ui/react/toggle' import { HeartIcon } from 'lucide-react' import styles from 'styles/toggle.module.css' export const Indicator = () => { return ( }> ) } ``` #### Solid ```tsx import { Toggle } from '@ark-ui/solid/toggle' import { HeartIcon } from 'lucide-solid' import styles from 'styles/toggle.module.css' export const Indicator = () => { return ( }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet fallback()} {/snippet} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPressed` | `boolean` | No | The default pressed state of the toggle. | | `onPressedChange` | `(pressed: boolean) => void` | No | Event handler called when the pressed state of the toggle changes. | | `pressed` | `boolean` | No | The pressed state of the toggle. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | root | | `[data-state]` | "on" | "off" | | `[data-pressed]` | Present when pressed | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | The fallback content to render when the toggle is not pressed. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-pressed]` | Present when pressed | | `[data-state]` | "on" | "off" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPressed` | `boolean` | No | The default pressed state of the toggle. | | `onPressedChange` | `(pressed: boolean) => void` | No | Event handler called when the pressed state of the toggle changes. | | `pressed` | `boolean` | No | The pressed state of the toggle. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | root | | `[data-state]` | "on" | "off" | | `[data-pressed]` | Present when pressed | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `number | boolean | Node | ArrayElement | (string & {})` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-pressed]` | Present when pressed | | `[data-state]` | "on" | "off" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPressed` | `boolean` | No | The default pressed state of the toggle. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `pressed` | `boolean` | No | The pressed state of the toggle. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | root | | `[data-state]` | "on" | "off" | | `[data-pressed]` | Present when pressed | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-pressed]` | Present when pressed | | `[data-state]` | "on" | "off" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPressed` | `boolean` | No | The default pressed state of the toggle. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `onPressedChange` | `(pressed: boolean) => void` | No | Event handler called when the pressed state of the toggle changes. | | `pressed` | `boolean` | No | The pressed state of the toggle. | | `ref` | `Element` | No | | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | root | | `[data-state]` | "on" | "off" | | `[data-pressed]` | Present when pressed | | `[data-disabled]` | Present when disabled | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseToggleContext]>` | Yes | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `Snippet<[]>` | No | The fallback content to render when the toggle is not pressed. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-pressed]` | Present when pressed | | `[data-state]` | "on" | "off" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `pressed` | `boolean` | Whether the toggle is pressed. | | `disabled` | `boolean` | Whether the toggle is disabled. | | `setPressed` | `(pressed: boolean) => void` | Sets the pressed state of the toggle. | --- # Toggle (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Toggle } from '@ark-ui/react/toggle' import { BoldIcon } from 'lucide-react' import styles from 'styles/toggle.module.css' export const Basic = () => { return ( ) } ``` #### Solid ```tsx import { Toggle } from '@ark-ui/solid/toggle' import { BoldIcon } from 'lucide-solid' import styles from 'styles/toggle.module.css' export const Basic = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### Controlled Use the `pressed` and `onPressedChange` props to control the toggle's state. **Example: controlled** #### React ```tsx import { Toggle } from '@ark-ui/react/toggle' import { HeartIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/toggle.module.css' export const Controlled = () => { const [pressed, setPressed] = useState(false) return ( }> ) } ``` #### Solid ```tsx import { Toggle } from '@ark-ui/solid/toggle' import { HeartIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/toggle.module.css' export const Controlled = () => { const [pressed, setPressed] = createSignal(false) return ( }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet fallback()} {/snippet} ``` ### Disabled Use the `disabled` prop to disable the toggle. **Example: disabled** #### React ```tsx import { Toggle } from '@ark-ui/react/toggle' import { BoldIcon } from 'lucide-react' import styles from 'styles/toggle.module.css' export const Disabled = () => { return ( ) } ``` #### Solid ```tsx import { Toggle } from '@ark-ui/solid/toggle' import { BoldIcon } from 'lucide-solid' import styles from 'styles/toggle.module.css' export const Disabled = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### Indicator Use the `Toggle.Indicator` component to render different indicators based on the state of the toggle. **Example: indicator** #### React ```tsx import { Toggle } from '@ark-ui/react/toggle' import { HeartIcon } from 'lucide-react' import styles from 'styles/toggle.module.css' export const Indicator = () => { return ( }> ) } ``` #### Solid ```tsx import { Toggle } from '@ark-ui/solid/toggle' import { HeartIcon } from 'lucide-solid' import styles from 'styles/toggle.module.css' export const Indicator = () => { return ( }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet fallback()} {/snippet} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPressed` | `boolean` | No | The default pressed state of the toggle. | | `onPressedChange` | `(pressed: boolean) => void` | No | Event handler called when the pressed state of the toggle changes. | | `pressed` | `boolean` | No | The pressed state of the toggle. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | root | | `[data-state]` | "on" | "off" | | `[data-pressed]` | Present when pressed | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | The fallback content to render when the toggle is not pressed. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-pressed]` | Present when pressed | | `[data-state]` | "on" | "off" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPressed` | `boolean` | No | The default pressed state of the toggle. | | `onPressedChange` | `(pressed: boolean) => void` | No | Event handler called when the pressed state of the toggle changes. | | `pressed` | `boolean` | No | The pressed state of the toggle. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | root | | `[data-state]` | "on" | "off" | | `[data-pressed]` | Present when pressed | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `number | boolean | Node | ArrayElement | (string & {})` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-pressed]` | Present when pressed | | `[data-state]` | "on" | "off" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPressed` | `boolean` | No | The default pressed state of the toggle. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `pressed` | `boolean` | No | The pressed state of the toggle. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | root | | `[data-state]` | "on" | "off" | | `[data-pressed]` | Present when pressed | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-pressed]` | Present when pressed | | `[data-state]` | "on" | "off" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPressed` | `boolean` | No | The default pressed state of the toggle. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `onPressedChange` | `(pressed: boolean) => void` | No | Event handler called when the pressed state of the toggle changes. | | `pressed` | `boolean` | No | The pressed state of the toggle. | | `ref` | `Element` | No | | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | root | | `[data-state]` | "on" | "off" | | `[data-pressed]` | Present when pressed | | `[data-disabled]` | Present when disabled | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseToggleContext]>` | Yes | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `Snippet<[]>` | No | The fallback content to render when the toggle is not pressed. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-pressed]` | Present when pressed | | `[data-state]` | "on" | "off" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `pressed` | `boolean` | Whether the toggle is pressed. | | `disabled` | `boolean` | Whether the toggle is disabled. | | `setPressed` | `(pressed: boolean) => void` | Sets the pressed state of the toggle. | --- # Toggle (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Toggle } from '@ark-ui/react/toggle' import { BoldIcon } from 'lucide-react' import styles from 'styles/toggle.module.css' export const Basic = () => { return ( ) } ``` #### Solid ```tsx import { Toggle } from '@ark-ui/solid/toggle' import { BoldIcon } from 'lucide-solid' import styles from 'styles/toggle.module.css' export const Basic = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### Controlled Use the `pressed` and `onPressedChange` props to control the toggle's state. **Example: controlled** #### React ```tsx import { Toggle } from '@ark-ui/react/toggle' import { HeartIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/toggle.module.css' export const Controlled = () => { const [pressed, setPressed] = useState(false) return ( }> ) } ``` #### Solid ```tsx import { Toggle } from '@ark-ui/solid/toggle' import { HeartIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/toggle.module.css' export const Controlled = () => { const [pressed, setPressed] = createSignal(false) return ( }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet fallback()} {/snippet} ``` ### Disabled Use the `disabled` prop to disable the toggle. **Example: disabled** #### React ```tsx import { Toggle } from '@ark-ui/react/toggle' import { BoldIcon } from 'lucide-react' import styles from 'styles/toggle.module.css' export const Disabled = () => { return ( ) } ``` #### Solid ```tsx import { Toggle } from '@ark-ui/solid/toggle' import { BoldIcon } from 'lucide-solid' import styles from 'styles/toggle.module.css' export const Disabled = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### Indicator Use the `Toggle.Indicator` component to render different indicators based on the state of the toggle. **Example: indicator** #### React ```tsx import { Toggle } from '@ark-ui/react/toggle' import { HeartIcon } from 'lucide-react' import styles from 'styles/toggle.module.css' export const Indicator = () => { return ( }> ) } ``` #### Solid ```tsx import { Toggle } from '@ark-ui/solid/toggle' import { HeartIcon } from 'lucide-solid' import styles from 'styles/toggle.module.css' export const Indicator = () => { return ( }> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet fallback()} {/snippet} ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPressed` | `boolean` | No | The default pressed state of the toggle. | | `onPressedChange` | `(pressed: boolean) => void` | No | Event handler called when the pressed state of the toggle changes. | | `pressed` | `boolean` | No | The pressed state of the toggle. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | root | | `[data-state]` | "on" | "off" | | `[data-pressed]` | Present when pressed | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | The fallback content to render when the toggle is not pressed. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-pressed]` | Present when pressed | | `[data-state]` | "on" | "off" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPressed` | `boolean` | No | The default pressed state of the toggle. | | `onPressedChange` | `(pressed: boolean) => void` | No | Event handler called when the pressed state of the toggle changes. | | `pressed` | `boolean` | No | The pressed state of the toggle. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | root | | `[data-state]` | "on" | "off" | | `[data-pressed]` | Present when pressed | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `number | boolean | Node | ArrayElement | (string & {})` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-pressed]` | Present when pressed | | `[data-state]` | "on" | "off" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPressed` | `boolean` | No | The default pressed state of the toggle. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `pressed` | `boolean` | No | The pressed state of the toggle. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | root | | `[data-state]` | "on" | "off" | | `[data-pressed]` | Present when pressed | | `[data-disabled]` | Present when disabled | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-pressed]` | Present when pressed | | `[data-state]` | "on" | "off" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultPressed` | `boolean` | No | The default pressed state of the toggle. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `onPressedChange` | `(pressed: boolean) => void` | No | Event handler called when the pressed state of the toggle changes. | | `pressed` | `boolean` | No | The pressed state of the toggle. | | `ref` | `Element` | No | | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | root | | `[data-state]` | "on" | "off" | | `[data-pressed]` | Present when pressed | | `[data-disabled]` | Present when disabled | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseToggleContext]>` | Yes | | **Indicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `fallback` | `Snippet<[]>` | No | The fallback content to render when the toggle is not pressed. | | `ref` | `Element` | No | | **Indicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle | | `[data-part]` | indicator | | `[data-disabled]` | Present when disabled | | `[data-pressed]` | Present when pressed | | `[data-state]` | "on" | "off" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `pressed` | `boolean` | Whether the toggle is pressed. | | `disabled` | `boolean` | Whether the toggle is disabled. | | `setPressed` | `(pressed: boolean) => void` | Sets the pressed state of the toggle. | --- # Toggle Group (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { ToggleGroup } from '@ark-ui/react/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-react' import styles from 'styles/toggle-group.module.css' export const Basic = () => { return ( ) } ``` #### Solid ```tsx import { ToggleGroup } from '@ark-ui/solid/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-solid' import styles from 'styles/toggle-group.module.css' export const Basic = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### Controlled Use the `value` and `onValueChange` props to control the toggle group state. **Example: controlled** #### React ```tsx import { ToggleGroup } from '@ark-ui/react/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/toggle-group.module.css' export const Controlled = () => { const [value, setValue] = useState(['left']) return ( setValue(e.value)} className={styles.Root}> ) } ``` #### Solid ```tsx import { ToggleGroup } from '@ark-ui/solid/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/toggle-group.module.css' export const Controlled = () => { const [value, setValue] = createSignal(['left']) return ( setValue(e.value)} class={styles.Root}> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### Root Provider An alternative way to control the toggle group is to use the `RootProvider` component and the `useToggleGroup` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { ToggleGroup, useToggleGroup } from '@ark-ui/react/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-react' import styles from 'styles/toggle-group.module.css' export const RootProvider = () => { const toggleGroup = useToggleGroup({ defaultValue: ['left'] }) return ( <> Set to Center: {String(toggleGroup.value)} ) } ``` #### Solid ```tsx import { ToggleGroup, useToggleGroup } from '@ark-ui/solid/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-solid' import styles from 'styles/toggle-group.module.css' export const RootProvider = () => { const toggleGroup = useToggleGroup({ defaultValue: ['left'] }) return ( <> Selected: {String(toggleGroup().value)} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Selected: {String(toggleGroup().value)} ``` ### Multiple Demonstrates how to enable `multiple` selection within the group. **Example: multiple** #### React ```tsx import { ToggleGroup } from '@ark-ui/react/toggle-group' import { BoldIcon, ItalicIcon, UnderlineIcon } from 'lucide-react' import styles from 'styles/toggle-group.module.css' export const Multiple = () => { return ( ) } ``` #### Solid ```tsx import { ToggleGroup } from '@ark-ui/solid/toggle-group' import { BoldIcon, ItalicIcon, UnderlineIcon } from 'lucide-solid' import styles from 'styles/toggle-group.module.css' export const Multiple = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial selected value of the toggle group when rendered. Use when you don't need to control the selected value of the toggle group. | | `deselectable` | `boolean` | No | Whether the toggle group allows empty selection. **Note:** This is ignored if `multiple` is `true`. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; item: (value: string) => string }>` | No | The ids of the elements in the toggle. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop focus inside the toggle group. | | `multiple` | `boolean` | No | Whether to allow multiple toggles to be selected. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the toggle is clicked. | | `orientation` | `Orientation` | No | The orientation of the toggle group. | | `rovingFocus` | `boolean` | No | Whether to use roving tab index to manage focus. | | `value` | `string[]` | No | The controlled selected value of the toggle group. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the toggle-group | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | item | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "on" | "off" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseToggleGroupReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial selected value of the toggle group when rendered. Use when you don't need to control the selected value of the toggle group. | | `deselectable` | `boolean` | No | Whether the toggle group allows empty selection. **Note:** This is ignored if `multiple` is `true`. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `ids` | `Partial<{ root: string; item: (value: string) => string }>` | No | The ids of the elements in the toggle. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop focus inside the toggle group. | | `multiple` | `boolean` | No | Whether to allow multiple toggles to be selected. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the toggle is clicked. | | `orientation` | `Orientation` | No | The orientation of the toggle group. | | `rovingFocus` | `boolean` | No | Whether to use roving tab index to manage focus. | | `value` | `string[]` | No | The controlled selected value of the toggle group. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the toggle-group | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | item | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "on" | "off" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseToggleGroupReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial selected value of the toggle group when rendered. Use when you don't need to control the selected value of the toggle group. | | `deselectable` | `boolean` | No | Whether the toggle group allows empty selection. **Note:** This is ignored if `multiple` is `true`. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; item(value: string): string }>` | No | The ids of the elements in the toggle. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop focus inside the toggle group. | | `modelValue` | `string[]` | No | The v-model value of the toggle group | | `multiple` | `boolean` | No | Whether to allow multiple toggles to be selected. | | `orientation` | `Orientation` | No | The orientation of the toggle group. | | `rovingFocus` | `boolean` | No | Whether to use roving tab index to manage focus. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the toggle-group | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | item | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "on" | "off" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ToggleGroupApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial selected value of the toggle group when rendered. Use when you don't need to control the selected value of the toggle group. | | `deselectable` | `boolean` | No | Whether the toggle group allows empty selection. **Note:** This is ignored if `multiple` is `true`. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; item: (value: string) => string }>` | No | The ids of the elements in the toggle. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop focus inside the toggle group. | | `multiple` | `boolean` | No | Whether to allow multiple toggles to be selected. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the toggle is clicked. | | `orientation` | `Orientation` | No | The orientation of the toggle group. | | `ref` | `Element` | No | | | `rovingFocus` | `boolean` | No | Whether to use roving tab index to manage focus. | | `value` | `string[]` | No | The controlled selected value of the toggle group. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the toggle-group | | `[data-focus]` | Present when focused | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseToggleGroupContext]>` | Yes | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | item | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "on" | "off" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseToggleGroupReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string[]` | The value of the toggle group. | | `setValue` | `(value: string[]) => void` | Sets the value of the toggle group. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of the toggle item. | ## Accessibility ### Keyboard Support **`Tab`** Description: Moves focus to either the pressed item or the first item in the group. **`Space`** Description: Activates/deactivates the item. **`Enter`** Description: Activates/deactivates the item. **`ArrowDown`** Description: Moves focus to the next item in the group. **`ArrowRight`** Description: Moves focus to the next item in the group. **`ArrowUp`** Description: Moves focus to the previous item in the group. **`ArrowLeft`** Description: Moves focus to the previous item in the group. **`Home`** Description: Moves focus to the first item. **`End`** Description: Moves focus to the last item. --- # Toggle Group (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { ToggleGroup } from '@ark-ui/react/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-react' import styles from 'styles/toggle-group.module.css' export const Basic = () => { return ( ) } ``` #### Solid ```tsx import { ToggleGroup } from '@ark-ui/solid/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-solid' import styles from 'styles/toggle-group.module.css' export const Basic = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### Controlled Use the `value` and `onValueChange` props to control the toggle group state. **Example: controlled** #### React ```tsx import { ToggleGroup } from '@ark-ui/react/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/toggle-group.module.css' export const Controlled = () => { const [value, setValue] = useState(['left']) return ( setValue(e.value)} className={styles.Root}> ) } ``` #### Solid ```tsx import { ToggleGroup } from '@ark-ui/solid/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/toggle-group.module.css' export const Controlled = () => { const [value, setValue] = createSignal(['left']) return ( setValue(e.value)} class={styles.Root}> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### Root Provider An alternative way to control the toggle group is to use the `RootProvider` component and the `useToggleGroup` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { ToggleGroup, useToggleGroup } from '@ark-ui/react/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-react' import styles from 'styles/toggle-group.module.css' export const RootProvider = () => { const toggleGroup = useToggleGroup({ defaultValue: ['left'] }) return ( <> Set to Center: {String(toggleGroup.value)} ) } ``` #### Solid ```tsx import { ToggleGroup, useToggleGroup } from '@ark-ui/solid/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-solid' import styles from 'styles/toggle-group.module.css' export const RootProvider = () => { const toggleGroup = useToggleGroup({ defaultValue: ['left'] }) return ( <> Selected: {String(toggleGroup().value)} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Selected: {String(toggleGroup().value)} ``` ### Multiple Demonstrates how to enable `multiple` selection within the group. **Example: multiple** #### React ```tsx import { ToggleGroup } from '@ark-ui/react/toggle-group' import { BoldIcon, ItalicIcon, UnderlineIcon } from 'lucide-react' import styles from 'styles/toggle-group.module.css' export const Multiple = () => { return ( ) } ``` #### Solid ```tsx import { ToggleGroup } from '@ark-ui/solid/toggle-group' import { BoldIcon, ItalicIcon, UnderlineIcon } from 'lucide-solid' import styles from 'styles/toggle-group.module.css' export const Multiple = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial selected value of the toggle group when rendered. Use when you don't need to control the selected value of the toggle group. | | `deselectable` | `boolean` | No | Whether the toggle group allows empty selection. **Note:** This is ignored if `multiple` is `true`. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; item: (value: string) => string }>` | No | The ids of the elements in the toggle. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop focus inside the toggle group. | | `multiple` | `boolean` | No | Whether to allow multiple toggles to be selected. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the toggle is clicked. | | `orientation` | `Orientation` | No | The orientation of the toggle group. | | `rovingFocus` | `boolean` | No | Whether to use roving tab index to manage focus. | | `value` | `string[]` | No | The controlled selected value of the toggle group. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the toggle-group | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | item | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "on" | "off" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseToggleGroupReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial selected value of the toggle group when rendered. Use when you don't need to control the selected value of the toggle group. | | `deselectable` | `boolean` | No | Whether the toggle group allows empty selection. **Note:** This is ignored if `multiple` is `true`. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `ids` | `Partial<{ root: string; item: (value: string) => string }>` | No | The ids of the elements in the toggle. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop focus inside the toggle group. | | `multiple` | `boolean` | No | Whether to allow multiple toggles to be selected. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the toggle is clicked. | | `orientation` | `Orientation` | No | The orientation of the toggle group. | | `rovingFocus` | `boolean` | No | Whether to use roving tab index to manage focus. | | `value` | `string[]` | No | The controlled selected value of the toggle group. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the toggle-group | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | item | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "on" | "off" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseToggleGroupReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial selected value of the toggle group when rendered. Use when you don't need to control the selected value of the toggle group. | | `deselectable` | `boolean` | No | Whether the toggle group allows empty selection. **Note:** This is ignored if `multiple` is `true`. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; item(value: string): string }>` | No | The ids of the elements in the toggle. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop focus inside the toggle group. | | `modelValue` | `string[]` | No | The v-model value of the toggle group | | `multiple` | `boolean` | No | Whether to allow multiple toggles to be selected. | | `orientation` | `Orientation` | No | The orientation of the toggle group. | | `rovingFocus` | `boolean` | No | Whether to use roving tab index to manage focus. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the toggle-group | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | item | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "on" | "off" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ToggleGroupApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial selected value of the toggle group when rendered. Use when you don't need to control the selected value of the toggle group. | | `deselectable` | `boolean` | No | Whether the toggle group allows empty selection. **Note:** This is ignored if `multiple` is `true`. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; item: (value: string) => string }>` | No | The ids of the elements in the toggle. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop focus inside the toggle group. | | `multiple` | `boolean` | No | Whether to allow multiple toggles to be selected. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the toggle is clicked. | | `orientation` | `Orientation` | No | The orientation of the toggle group. | | `ref` | `Element` | No | | | `rovingFocus` | `boolean` | No | Whether to use roving tab index to manage focus. | | `value` | `string[]` | No | The controlled selected value of the toggle group. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the toggle-group | | `[data-focus]` | Present when focused | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseToggleGroupContext]>` | Yes | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | item | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "on" | "off" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseToggleGroupReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string[]` | The value of the toggle group. | | `setValue` | `(value: string[]) => void` | Sets the value of the toggle group. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of the toggle item. | ## Accessibility ### Keyboard Support **`Tab`** Description: Moves focus to either the pressed item or the first item in the group. **`Space`** Description: Activates/deactivates the item. **`Enter`** Description: Activates/deactivates the item. **`ArrowDown`** Description: Moves focus to the next item in the group. **`ArrowRight`** Description: Moves focus to the next item in the group. **`ArrowUp`** Description: Moves focus to the previous item in the group. **`ArrowLeft`** Description: Moves focus to the previous item in the group. **`Home`** Description: Moves focus to the first item. **`End`** Description: Moves focus to the last item. --- # Toggle Group (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { ToggleGroup } from '@ark-ui/react/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-react' import styles from 'styles/toggle-group.module.css' export const Basic = () => { return ( ) } ``` #### Solid ```tsx import { ToggleGroup } from '@ark-ui/solid/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-solid' import styles from 'styles/toggle-group.module.css' export const Basic = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### Controlled Use the `value` and `onValueChange` props to control the toggle group state. **Example: controlled** #### React ```tsx import { ToggleGroup } from '@ark-ui/react/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/toggle-group.module.css' export const Controlled = () => { const [value, setValue] = useState(['left']) return ( setValue(e.value)} className={styles.Root}> ) } ``` #### Solid ```tsx import { ToggleGroup } from '@ark-ui/solid/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/toggle-group.module.css' export const Controlled = () => { const [value, setValue] = createSignal(['left']) return ( setValue(e.value)} class={styles.Root}> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### Root Provider An alternative way to control the toggle group is to use the `RootProvider` component and the `useToggleGroup` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { ToggleGroup, useToggleGroup } from '@ark-ui/react/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-react' import styles from 'styles/toggle-group.module.css' export const RootProvider = () => { const toggleGroup = useToggleGroup({ defaultValue: ['left'] }) return ( <> Set to Center: {String(toggleGroup.value)} ) } ``` #### Solid ```tsx import { ToggleGroup, useToggleGroup } from '@ark-ui/solid/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-solid' import styles from 'styles/toggle-group.module.css' export const RootProvider = () => { const toggleGroup = useToggleGroup({ defaultValue: ['left'] }) return ( <> Selected: {String(toggleGroup().value)} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Selected: {String(toggleGroup().value)} ``` ### Multiple Demonstrates how to enable `multiple` selection within the group. **Example: multiple** #### React ```tsx import { ToggleGroup } from '@ark-ui/react/toggle-group' import { BoldIcon, ItalicIcon, UnderlineIcon } from 'lucide-react' import styles from 'styles/toggle-group.module.css' export const Multiple = () => { return ( ) } ``` #### Solid ```tsx import { ToggleGroup } from '@ark-ui/solid/toggle-group' import { BoldIcon, ItalicIcon, UnderlineIcon } from 'lucide-solid' import styles from 'styles/toggle-group.module.css' export const Multiple = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial selected value of the toggle group when rendered. Use when you don't need to control the selected value of the toggle group. | | `deselectable` | `boolean` | No | Whether the toggle group allows empty selection. **Note:** This is ignored if `multiple` is `true`. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; item: (value: string) => string }>` | No | The ids of the elements in the toggle. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop focus inside the toggle group. | | `multiple` | `boolean` | No | Whether to allow multiple toggles to be selected. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the toggle is clicked. | | `orientation` | `Orientation` | No | The orientation of the toggle group. | | `rovingFocus` | `boolean` | No | Whether to use roving tab index to manage focus. | | `value` | `string[]` | No | The controlled selected value of the toggle group. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the toggle-group | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | item | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "on" | "off" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseToggleGroupReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial selected value of the toggle group when rendered. Use when you don't need to control the selected value of the toggle group. | | `deselectable` | `boolean` | No | Whether the toggle group allows empty selection. **Note:** This is ignored if `multiple` is `true`. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `ids` | `Partial<{ root: string; item: (value: string) => string }>` | No | The ids of the elements in the toggle. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop focus inside the toggle group. | | `multiple` | `boolean` | No | Whether to allow multiple toggles to be selected. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the toggle is clicked. | | `orientation` | `Orientation` | No | The orientation of the toggle group. | | `rovingFocus` | `boolean` | No | Whether to use roving tab index to manage focus. | | `value` | `string[]` | No | The controlled selected value of the toggle group. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the toggle-group | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | item | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "on" | "off" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseToggleGroupReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial selected value of the toggle group when rendered. Use when you don't need to control the selected value of the toggle group. | | `deselectable` | `boolean` | No | Whether the toggle group allows empty selection. **Note:** This is ignored if `multiple` is `true`. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; item(value: string): string }>` | No | The ids of the elements in the toggle. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop focus inside the toggle group. | | `modelValue` | `string[]` | No | The v-model value of the toggle group | | `multiple` | `boolean` | No | Whether to allow multiple toggles to be selected. | | `orientation` | `Orientation` | No | The orientation of the toggle group. | | `rovingFocus` | `boolean` | No | Whether to use roving tab index to manage focus. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the toggle-group | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | item | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "on" | "off" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ToggleGroupApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial selected value of the toggle group when rendered. Use when you don't need to control the selected value of the toggle group. | | `deselectable` | `boolean` | No | Whether the toggle group allows empty selection. **Note:** This is ignored if `multiple` is `true`. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; item: (value: string) => string }>` | No | The ids of the elements in the toggle. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop focus inside the toggle group. | | `multiple` | `boolean` | No | Whether to allow multiple toggles to be selected. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the toggle is clicked. | | `orientation` | `Orientation` | No | The orientation of the toggle group. | | `ref` | `Element` | No | | | `rovingFocus` | `boolean` | No | Whether to use roving tab index to manage focus. | | `value` | `string[]` | No | The controlled selected value of the toggle group. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the toggle-group | | `[data-focus]` | Present when focused | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseToggleGroupContext]>` | Yes | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | item | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "on" | "off" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseToggleGroupReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string[]` | The value of the toggle group. | | `setValue` | `(value: string[]) => void` | Sets the value of the toggle group. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of the toggle item. | ## Accessibility ### Keyboard Support **`Tab`** Description: Moves focus to either the pressed item or the first item in the group. **`Space`** Description: Activates/deactivates the item. **`Enter`** Description: Activates/deactivates the item. **`ArrowDown`** Description: Moves focus to the next item in the group. **`ArrowRight`** Description: Moves focus to the next item in the group. **`ArrowUp`** Description: Moves focus to the previous item in the group. **`ArrowLeft`** Description: Moves focus to the previous item in the group. **`Home`** Description: Moves focus to the first item. **`End`** Description: Moves focus to the last item. --- # Toggle Group (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { ToggleGroup } from '@ark-ui/react/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-react' import styles from 'styles/toggle-group.module.css' export const Basic = () => { return ( ) } ``` #### Solid ```tsx import { ToggleGroup } from '@ark-ui/solid/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-solid' import styles from 'styles/toggle-group.module.css' export const Basic = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### Controlled Use the `value` and `onValueChange` props to control the toggle group state. **Example: controlled** #### React ```tsx import { ToggleGroup } from '@ark-ui/react/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/toggle-group.module.css' export const Controlled = () => { const [value, setValue] = useState(['left']) return ( setValue(e.value)} className={styles.Root}> ) } ``` #### Solid ```tsx import { ToggleGroup } from '@ark-ui/solid/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-solid' import { createSignal } from 'solid-js' import styles from 'styles/toggle-group.module.css' export const Controlled = () => { const [value, setValue] = createSignal(['left']) return ( setValue(e.value)} class={styles.Root}> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ### Root Provider An alternative way to control the toggle group is to use the `RootProvider` component and the `useToggleGroup` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { ToggleGroup, useToggleGroup } from '@ark-ui/react/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-react' import styles from 'styles/toggle-group.module.css' export const RootProvider = () => { const toggleGroup = useToggleGroup({ defaultValue: ['left'] }) return ( <> Set to Center: {String(toggleGroup.value)} ) } ``` #### Solid ```tsx import { ToggleGroup, useToggleGroup } from '@ark-ui/solid/toggle-group' import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon } from 'lucide-solid' import styles from 'styles/toggle-group.module.css' export const RootProvider = () => { const toggleGroup = useToggleGroup({ defaultValue: ['left'] }) return ( <> Selected: {String(toggleGroup().value)} ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Selected: {String(toggleGroup().value)} ``` ### Multiple Demonstrates how to enable `multiple` selection within the group. **Example: multiple** #### React ```tsx import { ToggleGroup } from '@ark-ui/react/toggle-group' import { BoldIcon, ItalicIcon, UnderlineIcon } from 'lucide-react' import styles from 'styles/toggle-group.module.css' export const Multiple = () => { return ( ) } ``` #### Solid ```tsx import { ToggleGroup } from '@ark-ui/solid/toggle-group' import { BoldIcon, ItalicIcon, UnderlineIcon } from 'lucide-solid' import styles from 'styles/toggle-group.module.css' export const Multiple = () => { return ( ) } ``` #### Vue ```vue ``` #### Svelte ```svelte ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial selected value of the toggle group when rendered. Use when you don't need to control the selected value of the toggle group. | | `deselectable` | `boolean` | No | Whether the toggle group allows empty selection. **Note:** This is ignored if `multiple` is `true`. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; item: (value: string) => string }>` | No | The ids of the elements in the toggle. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop focus inside the toggle group. | | `multiple` | `boolean` | No | Whether to allow multiple toggles to be selected. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the toggle is clicked. | | `orientation` | `Orientation` | No | The orientation of the toggle group. | | `rovingFocus` | `boolean` | No | Whether to use roving tab index to manage focus. | | `value` | `string[]` | No | The controlled selected value of the toggle group. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the toggle-group | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | item | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "on" | "off" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseToggleGroupReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial selected value of the toggle group when rendered. Use when you don't need to control the selected value of the toggle group. | | `deselectable` | `boolean` | No | Whether the toggle group allows empty selection. **Note:** This is ignored if `multiple` is `true`. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `ids` | `Partial<{ root: string; item: (value: string) => string }>` | No | The ids of the elements in the toggle. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop focus inside the toggle group. | | `multiple` | `boolean` | No | Whether to allow multiple toggles to be selected. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the toggle is clicked. | | `orientation` | `Orientation` | No | The orientation of the toggle group. | | `rovingFocus` | `boolean` | No | Whether to use roving tab index to manage focus. | | `value` | `string[]` | No | The controlled selected value of the toggle group. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the toggle-group | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | item | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "on" | "off" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseToggleGroupReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial selected value of the toggle group when rendered. Use when you don't need to control the selected value of the toggle group. | | `deselectable` | `boolean` | No | Whether the toggle group allows empty selection. **Note:** This is ignored if `multiple` is `true`. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; item(value: string): string }>` | No | The ids of the elements in the toggle. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop focus inside the toggle group. | | `modelValue` | `string[]` | No | The v-model value of the toggle group | | `multiple` | `boolean` | No | Whether to allow multiple toggles to be selected. | | `orientation` | `Orientation` | No | The orientation of the toggle group. | | `rovingFocus` | `boolean` | No | Whether to use roving tab index to manage focus. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the toggle-group | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | item | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "on" | "off" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ToggleGroupApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `defaultValue` | `string[]` | No | The initial selected value of the toggle group when rendered. Use when you don't need to control the selected value of the toggle group. | | `deselectable` | `boolean` | No | Whether the toggle group allows empty selection. **Note:** This is ignored if `multiple` is `true`. | | `disabled` | `boolean` | No | Whether the toggle is disabled. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; item: (value: string) => string }>` | No | The ids of the elements in the toggle. Useful for composition. | | `loopFocus` | `boolean` | No | Whether to loop focus inside the toggle group. | | `multiple` | `boolean` | No | Whether to allow multiple toggles to be selected. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | Function to call when the toggle is clicked. | | `orientation` | `Orientation` | No | The orientation of the toggle group. | | `ref` | `Element` | No | | | `rovingFocus` | `boolean` | No | Whether to use roving tab index to manage focus. | | `value` | `string[]` | No | The controlled selected value of the toggle group. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | root | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the toggle-group | | `[data-focus]` | Present when focused | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseToggleGroupContext]>` | Yes | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | toggle-group | | `[data-part]` | item | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "on" | "off" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseToggleGroupReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `value` | `string[]` | The value of the toggle group. | | `setValue` | `(value: string[]) => void` | Sets the value of the toggle group. | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of the toggle item. | ## Accessibility ### Keyboard Support **`Tab`** Description: Moves focus to either the pressed item or the first item in the group. **`Space`** Description: Activates/deactivates the item. **`Enter`** Description: Activates/deactivates the item. **`ArrowDown`** Description: Moves focus to the next item in the group. **`ArrowRight`** Description: Moves focus to the next item in the group. **`ArrowUp`** Description: Moves focus to the previous item in the group. **`ArrowLeft`** Description: Moves focus to the previous item in the group. **`Home`** Description: Moves focus to the first item. **`End`** Description: Moves focus to the last item. --- # Tooltip (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Tooltip } from '@ark-ui/react/tooltip' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/tooltip.module.css' export const Basic = () => ( Hover Me I am a tooltip! ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Basic = () => ( Hover Me I am a tooltip! ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Controlled To create a controlled Tooltip component, manage the state of whether the tooltip is open using the `open` prop: **Example: controlled** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tooltip } from '@ark-ui/react/tooltip' import { useState } from 'react' import styles from 'styles/tooltip.module.css' import button from 'styles/button.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return (
                    setOpen(e.open)}> Hover Me I am a tooltip!
                    ) } ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return ( <> setOpen(e.open)}> Hover Me I am a tooltip! ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Root Provider An alternative way to control the tooltip is to use the `RootProvider` component and the `useTooltip` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { Tooltip, useTooltip } from '@ark-ui/react/tooltip' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/tooltip.module.css' export const RootProvider = () => { const tooltip = useTooltip() return ( <> Open: {String(tooltip.open)} Hover Me I am a tooltip! ) } ``` #### Solid ```tsx import { Tooltip, useTooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const RootProvider = () => { const tooltip = useTooltip() return ( <> Hover Me I am a tooltip! ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Arrow To display an arrow pointing to the trigger from the tooltip, use the `Tooltip.Arrow` and `Tooltip.ArrowTip` components: **Example: arrow** #### React ```tsx import { Tooltip } from '@ark-ui/react/tooltip' import { Portal } from '@zag-js/react' import styles from 'styles/tooltip.module.css' export const Arrow = () => ( Hover Me I am a tooltip! ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Arrow = () => ( Hover Me I am a tooltip! ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Delay To configure the open and close delay for the Tooltip, use the `closeDelay` and `openDelay` props: **Example: delay** #### React ```tsx import { Tooltip } from '@ark-ui/react/tooltip' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/tooltip.module.css' export const Delay = () => ( Hover Me I am a tooltip! ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Delay = () => ( Hover Me I am a tooltip! ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Positioning To customize the position of the Tooltip relative to the trigger, use the `positioning` prop: **Example: positioning** #### React ```tsx import { Tooltip } from '@ark-ui/react/tooltip' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/tooltip.module.css' export const Positioning = () => ( Hover Me I am a tooltip! ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Positioning = () => ( Hover Me I am a tooltip! ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Context For more control over the Tooltip's functionality, you can use `Tooltip.Context` to access the Tooltip API: **Example: context** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tooltip } from '@ark-ui/react/tooltip' import styles from 'styles/tooltip.module.css' export const Context = () => ( Hover Me {(tooltip) => ( This tooltip is open: {tooltip.open.toString()} )} ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Context = () => ( Hover Me {(context) => ( This tooltip is open: {context().open.toString()} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me {#snippet render(context)} This tooltip is open: {context().open.toString()} {/snippet} ``` ### Within Fixed Containers When rendering a tooltip inside a fixed-position container, set `positioning.strategy` to `"fixed"` to ensure proper positioning. **Example: within-fixed** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tooltip } from '@ark-ui/react/tooltip' import styles from 'styles/tooltip.module.css' export const WithinFixed = () => (
                    Hover Me I am a tooltip!
                    ) ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Custom label for the tooltip. | | `closeDelay` | `number` | No | The close delay of the tooltip. | | `closeOnClick` | `boolean` | No | Whether the tooltip should close on click | | `closeOnEscape` | `boolean` | No | Whether to close the tooltip when the Escape key is pressed. | | `closeOnPointerDown` | `boolean` | No | Whether to close the tooltip on pointerdown. | | `closeOnScroll` | `boolean` | No | Whether the tooltip should close on scroll | | `defaultOpen` | `boolean` | No | The initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. | | `disabled` | `boolean` | No | Whether the tooltip is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; arrow: string; positioner: string }>` | No | The ids of the elements in the tooltip. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `interactive` | `boolean` | No | Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the tooltip is opened. | | `open` | `boolean` | No | The controlled open state of the tooltip | | `openDelay` | `number` | No | The open delay of the tooltip. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-placement]` | The placement of the content | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTooltipReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | trigger | | `[data-expanded]` | Present when expanded | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Custom label for the tooltip. | | `closeDelay` | `number` | No | The close delay of the tooltip. | | `closeOnClick` | `boolean` | No | Whether the tooltip should close on click | | `closeOnEscape` | `boolean` | No | Whether to close the tooltip when the Escape key is pressed. | | `closeOnPointerDown` | `boolean` | No | Whether to close the tooltip on pointerdown. | | `closeOnScroll` | `boolean` | No | Whether the tooltip should close on scroll | | `defaultOpen` | `boolean` | No | The initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. | | `disabled` | `boolean` | No | Whether the tooltip is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; arrow: string; positioner: string }>` | No | The ids of the elements in the tooltip. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `interactive` | `boolean` | No | Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the tooltip is opened. | | `open` | `boolean` | No | The controlled open state of the tooltip | | `openDelay` | `number` | No | The open delay of the tooltip. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-placement]` | The placement of the content | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTooltipReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | trigger | | `[data-expanded]` | Present when expanded | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Custom label for the tooltip. | | `closeDelay` | `number` | No | The close delay of the tooltip. | | `closeOnClick` | `boolean` | No | Whether the tooltip should close on click | | `closeOnEscape` | `boolean` | No | Whether to close the tooltip when the Escape key is pressed. | | `closeOnPointerDown` | `boolean` | No | Whether to close the tooltip on pointerdown. | | `closeOnScroll` | `boolean` | No | Whether the tooltip should close on scroll | | `defaultOpen` | `boolean` | No | The initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. | | `disabled` | `boolean` | No | Whether the tooltip is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; arrow: string; positioner: string }>` | No | The ids of the elements in the tooltip. Useful for composition. | | `interactive` | `boolean` | No | Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `open` | `boolean` | No | The controlled open state of the tooltip | | `openDelay` | `number` | No | The open delay of the tooltip. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-placement]` | The placement of the content | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TooltipApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | trigger | | `[data-expanded]` | Present when expanded | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | The unique identifier of the machine. | | `aria-label` | `string` | No | Custom label for the tooltip. | | `closeDelay` | `number` | No | The close delay of the tooltip. | | `closeOnClick` | `boolean` | No | Whether the tooltip should close on click | | `closeOnEscape` | `boolean` | No | Whether to close the tooltip when the Escape key is pressed. | | `closeOnPointerDown` | `boolean` | No | Whether to close the tooltip on pointerdown. | | `closeOnScroll` | `boolean` | No | Whether the tooltip should close on scroll | | `defaultOpen` | `boolean` | No | The initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. | | `disabled` | `boolean` | No | Whether the tooltip is disabled | | `ids` | `Partial<{ trigger: string; content: string; arrow: string; positioner: string }>` | No | The ids of the elements in the tooltip. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `interactive` | `boolean` | No | Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the tooltip is opened. | | `open` | `boolean` | No | The controlled open state of the tooltip | | `openDelay` | `number` | No | The open delay of the tooltip. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-placement]` | The placement of the content | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTooltipContext]>` | No | | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTooltipReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | trigger | | `[data-expanded]` | Present when expanded | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the tooltip is open. | | `setOpen` | `(open: boolean) => void` | Function to open the tooltip. | | `reposition` | `(options?: Partial) => void` | Function to reposition the popover | ## Accessibility Complies with the [Tooltip WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/). ### Keyboard Support **`Tab`** Description: Opens/closes the tooltip without delay. **`Escape`** Description: If open, closes the tooltip without delay. --- # Tooltip (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Tooltip } from '@ark-ui/react/tooltip' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/tooltip.module.css' export const Basic = () => ( Hover Me I am a tooltip! ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Basic = () => ( Hover Me I am a tooltip! ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Controlled To create a controlled Tooltip component, manage the state of whether the tooltip is open using the `open` prop: **Example: controlled** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tooltip } from '@ark-ui/react/tooltip' import { useState } from 'react' import styles from 'styles/tooltip.module.css' import button from 'styles/button.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return (
                    setOpen(e.open)}> Hover Me I am a tooltip!
                    ) } ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return ( <> setOpen(e.open)}> Hover Me I am a tooltip! ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Root Provider An alternative way to control the tooltip is to use the `RootProvider` component and the `useTooltip` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { Tooltip, useTooltip } from '@ark-ui/react/tooltip' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/tooltip.module.css' export const RootProvider = () => { const tooltip = useTooltip() return ( <> Open: {String(tooltip.open)} Hover Me I am a tooltip! ) } ``` #### Solid ```tsx import { Tooltip, useTooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const RootProvider = () => { const tooltip = useTooltip() return ( <> Hover Me I am a tooltip! ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Arrow To display an arrow pointing to the trigger from the tooltip, use the `Tooltip.Arrow` and `Tooltip.ArrowTip` components: **Example: arrow** #### React ```tsx import { Tooltip } from '@ark-ui/react/tooltip' import { Portal } from '@zag-js/react' import styles from 'styles/tooltip.module.css' export const Arrow = () => ( Hover Me I am a tooltip! ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Arrow = () => ( Hover Me I am a tooltip! ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Delay To configure the open and close delay for the Tooltip, use the `closeDelay` and `openDelay` props: **Example: delay** #### React ```tsx import { Tooltip } from '@ark-ui/react/tooltip' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/tooltip.module.css' export const Delay = () => ( Hover Me I am a tooltip! ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Delay = () => ( Hover Me I am a tooltip! ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Positioning To customize the position of the Tooltip relative to the trigger, use the `positioning` prop: **Example: positioning** #### React ```tsx import { Tooltip } from '@ark-ui/react/tooltip' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/tooltip.module.css' export const Positioning = () => ( Hover Me I am a tooltip! ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Positioning = () => ( Hover Me I am a tooltip! ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Context For more control over the Tooltip's functionality, you can use `Tooltip.Context` to access the Tooltip API: **Example: context** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tooltip } from '@ark-ui/react/tooltip' import styles from 'styles/tooltip.module.css' export const Context = () => ( Hover Me {(tooltip) => ( This tooltip is open: {tooltip.open.toString()} )} ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Context = () => ( Hover Me {(context) => ( This tooltip is open: {context().open.toString()} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me {#snippet render(context)} This tooltip is open: {context().open.toString()} {/snippet} ``` ### Within Fixed Containers When rendering a tooltip inside a fixed-position container, set `positioning.strategy` to `"fixed"` to ensure proper positioning. **Example: within-fixed** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tooltip } from '@ark-ui/react/tooltip' import styles from 'styles/tooltip.module.css' export const WithinFixed = () => (
                    Hover Me I am a tooltip!
                    ) ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Custom label for the tooltip. | | `closeDelay` | `number` | No | The close delay of the tooltip. | | `closeOnClick` | `boolean` | No | Whether the tooltip should close on click | | `closeOnEscape` | `boolean` | No | Whether to close the tooltip when the Escape key is pressed. | | `closeOnPointerDown` | `boolean` | No | Whether to close the tooltip on pointerdown. | | `closeOnScroll` | `boolean` | No | Whether the tooltip should close on scroll | | `defaultOpen` | `boolean` | No | The initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. | | `disabled` | `boolean` | No | Whether the tooltip is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; arrow: string; positioner: string }>` | No | The ids of the elements in the tooltip. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `interactive` | `boolean` | No | Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the tooltip is opened. | | `open` | `boolean` | No | The controlled open state of the tooltip | | `openDelay` | `number` | No | The open delay of the tooltip. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-placement]` | The placement of the content | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTooltipReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | trigger | | `[data-expanded]` | Present when expanded | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Custom label for the tooltip. | | `closeDelay` | `number` | No | The close delay of the tooltip. | | `closeOnClick` | `boolean` | No | Whether the tooltip should close on click | | `closeOnEscape` | `boolean` | No | Whether to close the tooltip when the Escape key is pressed. | | `closeOnPointerDown` | `boolean` | No | Whether to close the tooltip on pointerdown. | | `closeOnScroll` | `boolean` | No | Whether the tooltip should close on scroll | | `defaultOpen` | `boolean` | No | The initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. | | `disabled` | `boolean` | No | Whether the tooltip is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; arrow: string; positioner: string }>` | No | The ids of the elements in the tooltip. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `interactive` | `boolean` | No | Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the tooltip is opened. | | `open` | `boolean` | No | The controlled open state of the tooltip | | `openDelay` | `number` | No | The open delay of the tooltip. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-placement]` | The placement of the content | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTooltipReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | trigger | | `[data-expanded]` | Present when expanded | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Custom label for the tooltip. | | `closeDelay` | `number` | No | The close delay of the tooltip. | | `closeOnClick` | `boolean` | No | Whether the tooltip should close on click | | `closeOnEscape` | `boolean` | No | Whether to close the tooltip when the Escape key is pressed. | | `closeOnPointerDown` | `boolean` | No | Whether to close the tooltip on pointerdown. | | `closeOnScroll` | `boolean` | No | Whether the tooltip should close on scroll | | `defaultOpen` | `boolean` | No | The initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. | | `disabled` | `boolean` | No | Whether the tooltip is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; arrow: string; positioner: string }>` | No | The ids of the elements in the tooltip. Useful for composition. | | `interactive` | `boolean` | No | Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `open` | `boolean` | No | The controlled open state of the tooltip | | `openDelay` | `number` | No | The open delay of the tooltip. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-placement]` | The placement of the content | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TooltipApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | trigger | | `[data-expanded]` | Present when expanded | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | The unique identifier of the machine. | | `aria-label` | `string` | No | Custom label for the tooltip. | | `closeDelay` | `number` | No | The close delay of the tooltip. | | `closeOnClick` | `boolean` | No | Whether the tooltip should close on click | | `closeOnEscape` | `boolean` | No | Whether to close the tooltip when the Escape key is pressed. | | `closeOnPointerDown` | `boolean` | No | Whether to close the tooltip on pointerdown. | | `closeOnScroll` | `boolean` | No | Whether the tooltip should close on scroll | | `defaultOpen` | `boolean` | No | The initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. | | `disabled` | `boolean` | No | Whether the tooltip is disabled | | `ids` | `Partial<{ trigger: string; content: string; arrow: string; positioner: string }>` | No | The ids of the elements in the tooltip. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `interactive` | `boolean` | No | Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the tooltip is opened. | | `open` | `boolean` | No | The controlled open state of the tooltip | | `openDelay` | `number` | No | The open delay of the tooltip. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-placement]` | The placement of the content | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTooltipContext]>` | No | | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTooltipReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | trigger | | `[data-expanded]` | Present when expanded | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the tooltip is open. | | `setOpen` | `(open: boolean) => void` | Function to open the tooltip. | | `reposition` | `(options?: Partial) => void` | Function to reposition the popover | ## Accessibility Complies with the [Tooltip WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/). ### Keyboard Support **`Tab`** Description: Opens/closes the tooltip without delay. **`Escape`** Description: If open, closes the tooltip without delay. --- # Tooltip (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Tooltip } from '@ark-ui/react/tooltip' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/tooltip.module.css' export const Basic = () => ( Hover Me I am a tooltip! ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Basic = () => ( Hover Me I am a tooltip! ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Controlled To create a controlled Tooltip component, manage the state of whether the tooltip is open using the `open` prop: **Example: controlled** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tooltip } from '@ark-ui/react/tooltip' import { useState } from 'react' import styles from 'styles/tooltip.module.css' import button from 'styles/button.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return (
                    setOpen(e.open)}> Hover Me I am a tooltip!
                    ) } ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return ( <> setOpen(e.open)}> Hover Me I am a tooltip! ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Root Provider An alternative way to control the tooltip is to use the `RootProvider` component and the `useTooltip` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { Tooltip, useTooltip } from '@ark-ui/react/tooltip' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/tooltip.module.css' export const RootProvider = () => { const tooltip = useTooltip() return ( <> Open: {String(tooltip.open)} Hover Me I am a tooltip! ) } ``` #### Solid ```tsx import { Tooltip, useTooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const RootProvider = () => { const tooltip = useTooltip() return ( <> Hover Me I am a tooltip! ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Arrow To display an arrow pointing to the trigger from the tooltip, use the `Tooltip.Arrow` and `Tooltip.ArrowTip` components: **Example: arrow** #### React ```tsx import { Tooltip } from '@ark-ui/react/tooltip' import { Portal } from '@zag-js/react' import styles from 'styles/tooltip.module.css' export const Arrow = () => ( Hover Me I am a tooltip! ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Arrow = () => ( Hover Me I am a tooltip! ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Delay To configure the open and close delay for the Tooltip, use the `closeDelay` and `openDelay` props: **Example: delay** #### React ```tsx import { Tooltip } from '@ark-ui/react/tooltip' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/tooltip.module.css' export const Delay = () => ( Hover Me I am a tooltip! ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Delay = () => ( Hover Me I am a tooltip! ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Positioning To customize the position of the Tooltip relative to the trigger, use the `positioning` prop: **Example: positioning** #### React ```tsx import { Tooltip } from '@ark-ui/react/tooltip' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/tooltip.module.css' export const Positioning = () => ( Hover Me I am a tooltip! ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Positioning = () => ( Hover Me I am a tooltip! ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Context For more control over the Tooltip's functionality, you can use `Tooltip.Context` to access the Tooltip API: **Example: context** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tooltip } from '@ark-ui/react/tooltip' import styles from 'styles/tooltip.module.css' export const Context = () => ( Hover Me {(tooltip) => ( This tooltip is open: {tooltip.open.toString()} )} ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Context = () => ( Hover Me {(context) => ( This tooltip is open: {context().open.toString()} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me {#snippet render(context)} This tooltip is open: {context().open.toString()} {/snippet} ``` ### Within Fixed Containers When rendering a tooltip inside a fixed-position container, set `positioning.strategy` to `"fixed"` to ensure proper positioning. **Example: within-fixed** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tooltip } from '@ark-ui/react/tooltip' import styles from 'styles/tooltip.module.css' export const WithinFixed = () => (
                    Hover Me I am a tooltip!
                    ) ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Custom label for the tooltip. | | `closeDelay` | `number` | No | The close delay of the tooltip. | | `closeOnClick` | `boolean` | No | Whether the tooltip should close on click | | `closeOnEscape` | `boolean` | No | Whether to close the tooltip when the Escape key is pressed. | | `closeOnPointerDown` | `boolean` | No | Whether to close the tooltip on pointerdown. | | `closeOnScroll` | `boolean` | No | Whether the tooltip should close on scroll | | `defaultOpen` | `boolean` | No | The initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. | | `disabled` | `boolean` | No | Whether the tooltip is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; arrow: string; positioner: string }>` | No | The ids of the elements in the tooltip. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `interactive` | `boolean` | No | Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the tooltip is opened. | | `open` | `boolean` | No | The controlled open state of the tooltip | | `openDelay` | `number` | No | The open delay of the tooltip. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-placement]` | The placement of the content | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTooltipReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | trigger | | `[data-expanded]` | Present when expanded | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Custom label for the tooltip. | | `closeDelay` | `number` | No | The close delay of the tooltip. | | `closeOnClick` | `boolean` | No | Whether the tooltip should close on click | | `closeOnEscape` | `boolean` | No | Whether to close the tooltip when the Escape key is pressed. | | `closeOnPointerDown` | `boolean` | No | Whether to close the tooltip on pointerdown. | | `closeOnScroll` | `boolean` | No | Whether the tooltip should close on scroll | | `defaultOpen` | `boolean` | No | The initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. | | `disabled` | `boolean` | No | Whether the tooltip is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; arrow: string; positioner: string }>` | No | The ids of the elements in the tooltip. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `interactive` | `boolean` | No | Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the tooltip is opened. | | `open` | `boolean` | No | The controlled open state of the tooltip | | `openDelay` | `number` | No | The open delay of the tooltip. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-placement]` | The placement of the content | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTooltipReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | trigger | | `[data-expanded]` | Present when expanded | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Custom label for the tooltip. | | `closeDelay` | `number` | No | The close delay of the tooltip. | | `closeOnClick` | `boolean` | No | Whether the tooltip should close on click | | `closeOnEscape` | `boolean` | No | Whether to close the tooltip when the Escape key is pressed. | | `closeOnPointerDown` | `boolean` | No | Whether to close the tooltip on pointerdown. | | `closeOnScroll` | `boolean` | No | Whether the tooltip should close on scroll | | `defaultOpen` | `boolean` | No | The initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. | | `disabled` | `boolean` | No | Whether the tooltip is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; arrow: string; positioner: string }>` | No | The ids of the elements in the tooltip. Useful for composition. | | `interactive` | `boolean` | No | Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `open` | `boolean` | No | The controlled open state of the tooltip | | `openDelay` | `number` | No | The open delay of the tooltip. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-placement]` | The placement of the content | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TooltipApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | trigger | | `[data-expanded]` | Present when expanded | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | The unique identifier of the machine. | | `aria-label` | `string` | No | Custom label for the tooltip. | | `closeDelay` | `number` | No | The close delay of the tooltip. | | `closeOnClick` | `boolean` | No | Whether the tooltip should close on click | | `closeOnEscape` | `boolean` | No | Whether to close the tooltip when the Escape key is pressed. | | `closeOnPointerDown` | `boolean` | No | Whether to close the tooltip on pointerdown. | | `closeOnScroll` | `boolean` | No | Whether the tooltip should close on scroll | | `defaultOpen` | `boolean` | No | The initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. | | `disabled` | `boolean` | No | Whether the tooltip is disabled | | `ids` | `Partial<{ trigger: string; content: string; arrow: string; positioner: string }>` | No | The ids of the elements in the tooltip. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `interactive` | `boolean` | No | Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the tooltip is opened. | | `open` | `boolean` | No | The controlled open state of the tooltip | | `openDelay` | `number` | No | The open delay of the tooltip. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-placement]` | The placement of the content | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTooltipContext]>` | No | | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTooltipReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | trigger | | `[data-expanded]` | Present when expanded | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the tooltip is open. | | `setOpen` | `(open: boolean) => void` | Function to open the tooltip. | | `reposition` | `(options?: Partial) => void` | Function to reposition the popover | ## Accessibility Complies with the [Tooltip WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/). ### Keyboard Support **`Tab`** Description: Opens/closes the tooltip without delay. **`Escape`** Description: If open, closes the tooltip without delay. --- # Tooltip (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Tooltip } from '@ark-ui/react/tooltip' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/tooltip.module.css' export const Basic = () => ( Hover Me I am a tooltip! ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Basic = () => ( Hover Me I am a tooltip! ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Controlled To create a controlled Tooltip component, manage the state of whether the tooltip is open using the `open` prop: **Example: controlled** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tooltip } from '@ark-ui/react/tooltip' import { useState } from 'react' import styles from 'styles/tooltip.module.css' import button from 'styles/button.module.css' export const Controlled = () => { const [open, setOpen] = useState(false) return (
                    setOpen(e.open)}> Hover Me I am a tooltip!
                    ) } ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { createSignal } from 'solid-js' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Controlled = () => { const [open, setOpen] = createSignal(false) return ( <> setOpen(e.open)}> Hover Me I am a tooltip! ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Root Provider An alternative way to control the tooltip is to use the `RootProvider` component and the `useTooltip` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { Tooltip, useTooltip } from '@ark-ui/react/tooltip' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/tooltip.module.css' export const RootProvider = () => { const tooltip = useTooltip() return ( <> Open: {String(tooltip.open)} Hover Me I am a tooltip! ) } ``` #### Solid ```tsx import { Tooltip, useTooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const RootProvider = () => { const tooltip = useTooltip() return ( <> Hover Me I am a tooltip! ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Arrow To display an arrow pointing to the trigger from the tooltip, use the `Tooltip.Arrow` and `Tooltip.ArrowTip` components: **Example: arrow** #### React ```tsx import { Tooltip } from '@ark-ui/react/tooltip' import { Portal } from '@zag-js/react' import styles from 'styles/tooltip.module.css' export const Arrow = () => ( Hover Me I am a tooltip! ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Arrow = () => ( Hover Me I am a tooltip! ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Delay To configure the open and close delay for the Tooltip, use the `closeDelay` and `openDelay` props: **Example: delay** #### React ```tsx import { Tooltip } from '@ark-ui/react/tooltip' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/tooltip.module.css' export const Delay = () => ( Hover Me I am a tooltip! ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Delay = () => ( Hover Me I am a tooltip! ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Positioning To customize the position of the Tooltip relative to the trigger, use the `positioning` prop: **Example: positioning** #### React ```tsx import { Tooltip } from '@ark-ui/react/tooltip' import { Portal } from '@ark-ui/react/portal' import styles from 'styles/tooltip.module.css' export const Positioning = () => ( Hover Me I am a tooltip! ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Positioning = () => ( Hover Me I am a tooltip! ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me I am a tooltip! ``` ### Context For more control over the Tooltip's functionality, you can use `Tooltip.Context` to access the Tooltip API: **Example: context** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tooltip } from '@ark-ui/react/tooltip' import styles from 'styles/tooltip.module.css' export const Context = () => ( Hover Me {(tooltip) => ( This tooltip is open: {tooltip.open.toString()} )} ) ``` #### Solid ```tsx import { Tooltip } from '@ark-ui/solid/tooltip' import { Portal } from 'solid-js/web' import styles from 'styles/tooltip.module.css' export const Context = () => ( Hover Me {(context) => ( This tooltip is open: {context().open.toString()} )} ) ``` #### Vue ```vue ``` #### Svelte ```svelte Hover Me {#snippet render(context)} This tooltip is open: {context().open.toString()} {/snippet} ``` ### Within Fixed Containers When rendering a tooltip inside a fixed-position container, set `positioning.strategy` to `"fixed"` to ensure proper positioning. **Example: within-fixed** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tooltip } from '@ark-ui/react/tooltip' import styles from 'styles/tooltip.module.css' export const WithinFixed = () => (
                    Hover Me I am a tooltip!
                    ) ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Custom label for the tooltip. | | `closeDelay` | `number` | No | The close delay of the tooltip. | | `closeOnClick` | `boolean` | No | Whether the tooltip should close on click | | `closeOnEscape` | `boolean` | No | Whether to close the tooltip when the Escape key is pressed. | | `closeOnPointerDown` | `boolean` | No | Whether to close the tooltip on pointerdown. | | `closeOnScroll` | `boolean` | No | Whether the tooltip should close on scroll | | `defaultOpen` | `boolean` | No | The initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. | | `disabled` | `boolean` | No | Whether the tooltip is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; arrow: string; positioner: string }>` | No | The ids of the elements in the tooltip. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `interactive` | `boolean` | No | Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the tooltip is opened. | | `open` | `boolean` | No | The controlled open state of the tooltip | | `openDelay` | `number` | No | The open delay of the tooltip. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-placement]` | The placement of the content | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTooltipReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | trigger | | `[data-expanded]` | Present when expanded | | `[data-state]` | "open" | "closed" | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Custom label for the tooltip. | | `closeDelay` | `number` | No | The close delay of the tooltip. | | `closeOnClick` | `boolean` | No | Whether the tooltip should close on click | | `closeOnEscape` | `boolean` | No | Whether to close the tooltip when the Escape key is pressed. | | `closeOnPointerDown` | `boolean` | No | Whether to close the tooltip on pointerdown. | | `closeOnScroll` | `boolean` | No | Whether the tooltip should close on scroll | | `defaultOpen` | `boolean` | No | The initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. | | `disabled` | `boolean` | No | Whether the tooltip is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; arrow: string; positioner: string }>` | No | The ids of the elements in the tooltip. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `interactive` | `boolean` | No | Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the tooltip is opened. | | `open` | `boolean` | No | The controlled open state of the tooltip | | `openDelay` | `number` | No | The open delay of the tooltip. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-placement]` | The placement of the content | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTooltipReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | trigger | | `[data-expanded]` | Present when expanded | | `[data-state]` | "open" | "closed" | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `aria-label` | `string` | No | Custom label for the tooltip. | | `closeDelay` | `number` | No | The close delay of the tooltip. | | `closeOnClick` | `boolean` | No | Whether the tooltip should close on click | | `closeOnEscape` | `boolean` | No | Whether to close the tooltip when the Escape key is pressed. | | `closeOnPointerDown` | `boolean` | No | Whether to close the tooltip on pointerdown. | | `closeOnScroll` | `boolean` | No | Whether the tooltip should close on scroll | | `defaultOpen` | `boolean` | No | The initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. | | `disabled` | `boolean` | No | Whether the tooltip is disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ trigger: string; content: string; arrow: string; positioner: string }>` | No | The ids of the elements in the tooltip. Useful for composition. | | `interactive` | `boolean` | No | Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `open` | `boolean` | No | The controlled open state of the tooltip | | `openDelay` | `number` | No | The open delay of the tooltip. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-placement]` | The placement of the content | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TooltipApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | trigger | | `[data-expanded]` | Present when expanded | | `[data-state]` | "open" | "closed" | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `id` | `string` | Yes | The unique identifier of the machine. | | `aria-label` | `string` | No | Custom label for the tooltip. | | `closeDelay` | `number` | No | The close delay of the tooltip. | | `closeOnClick` | `boolean` | No | Whether the tooltip should close on click | | `closeOnEscape` | `boolean` | No | Whether to close the tooltip when the Escape key is pressed. | | `closeOnPointerDown` | `boolean` | No | Whether to close the tooltip on pointerdown. | | `closeOnScroll` | `boolean` | No | Whether the tooltip should close on scroll | | `defaultOpen` | `boolean` | No | The initial open state of the tooltip when rendered. Use when you don't need to control the open state of the tooltip. | | `disabled` | `boolean` | No | Whether the tooltip is disabled | | `ids` | `Partial<{ trigger: string; content: string; arrow: string; positioner: string }>` | No | The ids of the elements in the tooltip. Useful for composition. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `interactive` | `boolean` | No | Whether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function called when the tooltip is opened. | | `open` | `boolean` | No | The controlled open state of the tooltip | | `openDelay` | `number` | No | The open delay of the tooltip. | | `positioning` | `PositioningOptions` | No | The user provided options used to position the popover content | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-placement]` | The placement of the content | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTooltipContext]>` | No | | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTooltipReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Trigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Trigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tooltip | | `[data-part]` | trigger | | `[data-expanded]` | Present when expanded | | `[data-state]` | "open" | "closed" | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the tooltip is open. | | `setOpen` | `(open: boolean) => void` | Function to open the tooltip. | | `reposition` | `(options?: Partial) => void` | Function to reposition the popover | ## Accessibility Complies with the [Tooltip WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/). ### Keyboard Support **`Tab`** Description: Opens/closes the tooltip without delay. **`Escape`** Description: If open, closes the tooltip without delay. --- # Tour (REACT) ## Anatomy ```tsx const tour = useTour({ steps: [...] }) ``` ## Examples **Example: basic** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { MoreHorizontalIcon, SaveIcon, SparklesIcon, UploadIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'welcome', type: 'dialog', title: 'Welcome to the App!', description: "Let's take a quick tour to get you started with the main features.", actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'upload', type: 'tooltip', title: 'Upload Files', description: 'Click here to upload your files to the cloud.', target: () => document.querySelector('#btn-upload'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'save', type: 'tooltip', title: 'Save Changes', description: 'Save your work to keep your progress.', target: () => document.querySelector('#btn-save'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'more', type: 'tooltip', title: 'More Options', description: 'Access additional settings and actions from this menu.', target: () => document.querySelector('#btn-more'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: "You're all set!", description: 'You now know the basics. Enjoy using the app!', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const Basic = () => { const tour = useTour({ steps }) return (
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { MoreHorizontalIcon, SaveIcon, SparklesIcon, UploadIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'welcome', type: 'dialog', title: 'Welcome to the App!', description: "Let's take a quick tour to get you started with the main features.", actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'upload', type: 'tooltip', title: 'Upload Files', description: 'Click here to upload your files to the cloud.', target: () => document.querySelector('#btn-upload'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'save', type: 'tooltip', title: 'Save Changes', description: 'Save your work to keep your progress.', target: () => document.querySelector('#btn-save'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'more', type: 'tooltip', title: 'More Options', description: 'Access additional settings and actions from this menu.', target: () => document.querySelector('#btn-more'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: "You're all set!", description: 'You now know the basics. Enjoy using the app!', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const Basic = () => { const tour = useTour({ steps }) return (
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Step Types Demonstrate all three step types in a single tour: `dialog` for welcome/completion, `tooltip` anchored to elements, and `floating` for fixed-position content. **Example: mixed-types** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'welcome', type: 'dialog', title: 'Welcome!', description: 'This tour demonstrates different step types: dialog, tooltip, and floating.', actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'tooltip-step', type: 'tooltip', title: 'Tooltip Step', description: 'This step appears as a tooltip anchored to a specific element.', target: () => document.querySelector('#target-element'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'floating-step', type: 'floating', placement: 'bottom-end', title: 'Floating Step', description: 'This step floats at a fixed position on the screen, independent of any target.', actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: 'Tour Complete!', description: 'You have seen all the different step types available.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const MixedTypes = () => { const tour = useTour({ steps }) return (
                    Target Element
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'welcome', type: 'dialog', title: 'Welcome!', description: 'This tour demonstrates different step types: dialog, tooltip, and floating.', actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'tooltip-step', type: 'tooltip', title: 'Tooltip Step', description: 'This step appears as a tooltip anchored to a specific element.', target: () => document.querySelector('#target-element'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'floating-step', type: 'floating', placement: 'bottom-end', title: 'Floating Step', description: 'This step floats at a fixed position on the screen, independent of any target.', actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: 'Tour Complete!', description: 'You have seen all the different step types available.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const MixedTypes = () => { const tour = useTour({ steps }) return (
                    Target Element
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Target Element
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Progress Display a visual progress indicator at the bottom of the tour content showing how far along the user is. **Example: progress-bar** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'Progress Tracking', description: 'Watch the progress bar at the bottom as you navigate.', target: () => document.querySelector('#progress-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Halfway There', description: 'The progress bar shows how far along you are.', target: () => document.querySelector('#progress-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Almost Done', description: 'One more step to complete the tour.', target: () => document.querySelector('#progress-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-4', type: 'tooltip', title: 'Complete!', description: 'You have completed all the steps.', target: () => document.querySelector('#progress-4'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const ProgressBar = () => { const tour = useTour({ steps }) return (
                    Step 1
                    Step 2
                    Step 3
                    Step 4
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'Progress Tracking', description: 'Watch the progress bar at the bottom as you navigate.', target: () => document.querySelector('#progress-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Halfway There', description: 'The progress bar shows how far along you are.', target: () => document.querySelector('#progress-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Almost Done', description: 'One more step to complete the tour.', target: () => document.querySelector('#progress-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-4', type: 'tooltip', title: 'Complete!', description: 'You have completed all the steps.', target: () => document.querySelector('#progress-4'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const ProgressBar = () => { const tour = useTour({ steps }) return (
                    Step 1
                    Step 2
                    Step 3
                    Step 4
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Step 1
                    Step 2
                    Step 3
                    Step 4
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Skip Allow users to skip the entire tour at any step by adding a skip action. **Example: skip-tour** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'First Feature', description: 'You can skip this tour at any time using the Skip button.', target: () => document.querySelector('#item-1'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-2', type: 'tooltip', title: 'Second Feature', description: 'Continue or skip to end the tour early.', target: () => document.querySelector('#item-2'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Feature', description: 'This is the last step of the tour.', target: () => document.querySelector('#item-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const SkipTour = () => { const tour = useTour({ steps }) return (
                    Item 1
                    Item 2
                    Item 3
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'First Feature', description: 'You can skip this tour at any time using the Skip button.', target: () => document.querySelector('#item-1'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-2', type: 'tooltip', title: 'Second Feature', description: 'Continue or skip to end the tour early.', target: () => document.querySelector('#item-2'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Feature', description: 'This is the last step of the tour.', target: () => document.querySelector('#item-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const SkipTour = () => { const tour = useTour({ steps }) return (
                    Item 1
                    Item 2
                    Item 3
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Item 1
                    Item 2
                    Item 3
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Keyboard Navigation Enable arrow key navigation between tour steps using the `keyboardNavigation` prop. **Example: keyboard-navigation** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { KeyboardIcon, SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'Keyboard Navigation', description: 'Press the right arrow key (→) to go to the next step.', target: () => document.querySelector('#key-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Go Back', description: 'Press the left arrow key (←) to go back.', target: () => document.querySelector('#key-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Close Tour', description: 'Press Escape to close the tour at any time.', target: () => document.querySelector('#key-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const KeyboardNavigation = () => { const tour = useTour({ steps, keyboardNavigation: true }) return (

                    Use arrow keys to navigate, Escape to close

                    Step 1
                    Step 2
                    Step 3
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { KeyboardIcon, SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'Keyboard Navigation', description: 'Press the right arrow key to go to the next step.', target: () => document.querySelector('#key-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Go Back', description: 'Press the left arrow key to go back.', target: () => document.querySelector('#key-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Close Tour', description: 'Press Escape to close the tour at any time.', target: () => document.querySelector('#key-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const KeyboardNavigation = () => { const tour = useTour({ steps, keyboardNavigation: true }) return (

                    Use arrow keys to navigate, Escape to close

                    Step 1
                    Step 2
                    Step 3
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Use arrow keys to navigate, Escape to close

                    Step 1
                    Step 2
                    Step 3
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Events Listen to tour lifecycle events like `onStepChange` and `onStatusChange` to track user progress. **Example: events** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'First Step', description: 'Watch the event log below as you navigate.', target: () => document.querySelector('#event-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Second Step', description: 'Each step change triggers an event.', target: () => document.querySelector('#event-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Step', description: 'Complete the tour to see the status change.', target: () => document.querySelector('#event-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const Events = () => { const [logs, setLogs] = useState([]) const addLog = (message: string) => { setLogs((prev) => [...prev, message]) } const tour = useTour({ steps, onStepChange(details) { addLog(`Step changed: ${details.stepId}`) }, onStatusChange(details) { addLog(`Status: ${details.status}`) }, }) return (
                    Step 1
                    Step 2
                    Step 3
                    Event Log: {logs.length === 0 ? (
                    Start the tour to see events
                    ) : ( logs.map((log, i) => (
                    {log}
                    )) )}
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For, Show, createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'First Step', description: 'Watch the event log below as you navigate.', target: () => document.querySelector('#event-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Second Step', description: 'Each step change triggers an event.', target: () => document.querySelector('#event-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Step', description: 'Complete the tour to see the status change.', target: () => document.querySelector('#event-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const Events = () => { const [logs, setLogs] = createSignal([]) const addLog = (message: string) => { setLogs((prev) => [...prev, message]) } const tour = useTour({ steps, onStepChange(details) { addLog(`Step changed: ${details.stepId}`) }, onStatusChange(details) { addLog(`Status: ${details.status}`) }, }) return (
                    Step 1
                    Step 2
                    Step 3
                    Event Log: 0} fallback={
                    Start the tour to see events
                    }> {(log) =>
                    {log}
                    }
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Step 1
                    Step 2
                    Step 3
                    Event Log: {#if logs.length === 0}
                    Start the tour to see events
                    {:else} {#each logs as log, i (i)}
                    {log}
                    {/each} {/if}
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Wait for Click Use the `effect` function with `waitForEvent` to wait for user interaction before proceeding to the next step. **Example: wait-for-click** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour, waitForEvent } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Interactive Tutorial', description: 'This tour will guide you through actions. You must complete each step to proceed.', actions: [{ label: 'Begin', action: 'next' }], }, { id: 'click-add', type: 'tooltip', title: 'Click the Add Button', description: 'Click the "Add Item" button to continue.', target: () => document.querySelector('#btn-add'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'click-edit', type: 'tooltip', title: 'Click the Edit Button', description: 'Now click the "Edit" button.', target: () => document.querySelector('#btn-edit'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'click-delete', type: 'tooltip', title: 'Click the Delete Button', description: 'Finally, click the "Delete" button.', target: () => document.querySelector('#btn-delete'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'complete', type: 'dialog', title: 'Well Done!', description: 'You completed all the interactive steps.', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const WaitForClick = () => { const tour = useTour({ steps }) return (
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour, waitForEvent } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Interactive Tutorial', description: 'This tour will guide you through actions. You must complete each step to proceed.', actions: [{ label: 'Begin', action: 'next' }], }, { id: 'click-add', type: 'tooltip', title: 'Click the Add Button', description: 'Click the "Add Item" button to continue.', target: () => document.querySelector('#btn-add'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'click-edit', type: 'tooltip', title: 'Click the Edit Button', description: 'Now click the "Edit" button.', target: () => document.querySelector('#btn-edit'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'click-delete', type: 'tooltip', title: 'Click the Delete Button', description: 'Finally, click the "Delete" button.', target: () => document.querySelector('#btn-delete'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'complete', type: 'dialog', title: 'Well Done!', description: 'You completed all the interactive steps.', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const WaitForClick = () => { const tour = useTour({ steps }) return (
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Wait for Input Create form tutorials that wait for users to enter valid input before advancing. **Example: wait-for-input** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour, waitForEvent } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Form Tutorial', description: 'Learn how to fill out the form by following the guided steps.', actions: [{ label: 'Start', action: 'next' }], }, { id: 'enter-name', type: 'tooltip', title: 'Enter Your Name', description: 'Type your name in the input field to continue.', target: () => document.querySelector('#input-name'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'input', { predicate: (el) => el.value.trim().length >= 2, }) promise.then(() => next()) return cancel }, }, { id: 'enter-email', type: 'tooltip', title: 'Enter Your Email', description: 'Now enter a valid email address.', target: () => document.querySelector('#input-email'), effect({ next, target, show }) { show() const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ const [promise, cancel] = waitForEvent(target, 'input', { predicate: (el) => emailRegex.test(el.value), }) promise.then(() => next()) return cancel }, }, { id: 'check-terms', type: 'tooltip', title: 'Accept Terms', description: 'Check the checkbox to accept the terms.', target: () => document.querySelector('#checkbox-terms'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'change', { predicate: (el) => el.checked, }) promise.then(() => next()) return cancel }, }, { id: 'complete', type: 'dialog', title: 'Form Complete!', description: 'You have successfully filled out the form.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const WaitForInput = () => { const tour = useTour({ steps }) return (
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour, waitForEvent } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Form Tutorial', description: 'Learn how to fill out the form by following the guided steps.', actions: [{ label: 'Start', action: 'next' }], }, { id: 'enter-name', type: 'tooltip', title: 'Enter Your Name', description: 'Type your name in the input field to continue.', target: () => document.querySelector('#input-name'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'input', { predicate: (el) => el.value.trim().length >= 2, }) promise.then(() => next()) return cancel }, }, { id: 'enter-email', type: 'tooltip', title: 'Enter Your Email', description: 'Now enter a valid email address.', target: () => document.querySelector('#input-email'), effect({ next, target, show }) { show() const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ const [promise, cancel] = waitForEvent(target, 'input', { predicate: (el) => emailRegex.test(el.value), }) promise.then(() => next()) return cancel }, }, { id: 'check-terms', type: 'tooltip', title: 'Accept Terms', description: 'Check the checkbox to accept the terms.', target: () => document.querySelector('#checkbox-terms'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'change', { predicate: (el) => el.checked, }) promise.then(() => next()) return cancel }, }, { id: 'complete', type: 'dialog', title: 'Form Complete!', description: 'You have successfully filled out the form.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const WaitForInput = () => { const tour = useTour({ steps }) return (
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Wait for Element Wait for dynamically rendered elements to appear in the DOM before showing a step. **Example: wait-for-element** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour, waitForElement, waitForEvent } from '@ark-ui/react/tour' import { PlusIcon, SparklesIcon, XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Dynamic Elements', description: 'This tour demonstrates waiting for elements that appear dynamically.', actions: [{ label: 'Start', action: 'next' }], }, { id: 'add-item', type: 'tooltip', title: 'Add an Item', description: 'Click the button to add a new item to the list.', target: () => document.querySelector('#btn-add-item'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'new-item', type: 'tooltip', title: 'New Item Added!', description: 'The tour waited for this element to appear before showing this step.', target: () => document.querySelector('[data-item="new"]'), effect({ show }) { const [promise, cancel] = waitForElement(() => document.querySelector('[data-item="new"]'), { timeout: 5000, }) promise.then(() => show()) return () => cancel() }, actions: [{ label: 'Next', action: 'next' }], }, { id: 'complete', type: 'dialog', title: 'Tour Complete', description: 'You learned how to use waitForElement for dynamic content.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const WaitForElement = () => { const tour = useTour({ steps }) const [items, setItems] = useState(['Item 1', 'Item 2']) const addItem = () => { setItems((prev) => [...prev, `Item ${prev.length + 1}`]) } return (
                    {items.map((item, index) => (
                    2 ? 'new' : undefined} > {item}
                    ))}
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour, waitForElement, waitForEvent } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { PlusIcon, SparklesIcon, XIcon } from 'lucide-solid' import { For, createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Dynamic Elements', description: 'This tour demonstrates waiting for elements that appear dynamically.', actions: [{ label: 'Start', action: 'next' }], }, { id: 'add-item', type: 'tooltip', title: 'Add an Item', description: 'Click the button to add a new item to the list.', target: () => document.querySelector('#btn-add-item'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'new-item', type: 'tooltip', title: 'New Item Added!', description: 'The tour waited for this element to appear before showing this step.', target: () => document.querySelector('[data-item="new"]'), effect({ show }) { const [promise, cancel] = waitForElement(() => document.querySelector('[data-item="new"]'), { timeout: 5000, }) promise.then(() => show()) return () => cancel() }, actions: [{ label: 'Next', action: 'next' }], }, { id: 'complete', type: 'dialog', title: 'Tour Complete', description: 'You learned how to use waitForElement for dynamic content.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const WaitForElement = () => { const tour = useTour({ steps }) const [items, setItems] = createSignal(['Item 1', 'Item 2']) const addItem = () => { setItems((prev) => [...prev, `Item ${prev.length + 1}`]) } return (
                    {(item, index) => (
                    2 ? 'new' : undefined} > {item}
                    )}
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each items as item, index (item)}
                    2 ? 'new' : undefined}> {item}
                    {/each}
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Async Load data asynchronously and update step content before displaying it using the `effect` function with `show()` and `update()`. **Example: async-step** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Async Data Loading', description: 'This tour demonstrates loading data before showing a step.', actions: [{ label: 'Next', action: 'next' }], }, { id: 'user-info', type: 'tooltip', title: 'Loading...', description: 'Fetching user data...', target: () => document.querySelector('#user-card'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], effect({ show, update }) { const controller = new AbortController() fetch('https://api.github.com/users/segunadebayo', { signal: controller.signal }) .then((res) => res.json()) .then((data) => { update({ title: `Welcome, ${data.name || data.login}!`, description: `You have ${data.public_repos} public repositories and ${data.followers} followers.`, }) show() }) .catch(() => { update({ title: 'User Profile', description: 'Could not load user data. Please try again.', }) show() }) return () => controller.abort() }, }, { id: 'complete', type: 'dialog', title: 'Tour Complete', description: 'The async step loaded data from the GitHub API before displaying.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const AsyncStep = () => { const tour = useTour({ steps }) return (
                    User Profile Card
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Async Data Loading', description: 'This tour demonstrates loading data before showing a step.', actions: [{ label: 'Next', action: 'next' }], }, { id: 'user-info', type: 'tooltip', title: 'Loading...', description: 'Fetching user data...', target: () => document.querySelector('#user-card'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], effect({ show, update }) { const controller = new AbortController() fetch('https://api.github.com/users/segunadebayo', { signal: controller.signal }) .then((res) => res.json()) .then((data) => { update({ title: `Welcome, ${data.name || data.login}!`, description: `You have ${data.public_repos} public repositories and ${data.followers} followers.`, }) show() }) .catch(() => { update({ title: 'User Profile', description: 'Could not load user data. Please try again.', }) show() }) return () => controller.abort() }, }, { id: 'complete', type: 'dialog', title: 'Tour Complete', description: 'The async step loaded data from the GitHub API before displaying.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const AsyncStep = () => { const tour = useTour({ steps }) return (
                    User Profile Card
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    User Profile Card
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ## Guides ### Step Types The tour machine supports different types of steps, allowing you to create a diverse and interactive tour experience. The available step types are defined in the `StepType` type: - `tooltip`: Displays the step content as a tooltip, typically positioned near the target element. - `dialog`: Shows the step content in a modal dialog centered on screen, useful for starting or ending the tour. This usually don't have a `target` defined. - `floating`: Presents the step content as a floating element, which can be positioned flexibly on the screen. This usually don't have a `target` defined. - `wait`: A special type that waits for a specific condition before proceeding to the next step. ```tsx const steps: TourStepDetails[] = [ { id: 'step-1', type: 'tooltip', placement: 'top-start', target: () => document.querySelector('#target-1'), title: 'Tooltip Step', description: 'This is a tooltip step', }, { id: 'step-2', type: 'dialog', title: 'Dialog Step', description: 'This is a dialog step', }, { id: 'step-3', type: 'floating', placement: 'top-start', title: 'Floating Step', description: 'This is a floating step', }, { id: 'step-4', type: 'wait', title: 'Wait Step', description: 'This is a wait step', effect({ next }) { // do something and go next // you can also return a cleanup }, }, ] ``` ### Actions Every step supports a list of actions that are rendered in the step footer.Use the `actions` property to define each action. ```tsx const steps: TourStepDetails[] = [ { id: 'step-1', type: 'dialog', title: 'Dialog Step', description: 'This is a dialog step', actions: [{ label: 'Show me a tour!', action: 'next' }], }, ] ``` ### Tooltip Placement Use the `placement` property to define the placement of the tooltip. ```tsx {5} const steps: TourStepDetails[] = [ { id: 'step-1', type: 'tooltip', placement: 'top-start', // ... }, ] ``` ### Hide Arrow Set `arrow: false` in the step property to hide the tooltip arrow. This is only useful for tooltip steps. ```tsx {5} const steps: TourStepDetails[] = [ { id: 'step-1', type: 'tooltip', arrow: false, }, ] ``` ### Hide Backdrop Set `backdrop: false` in the step property to hide the backdrop. This applies to all step types except the `wait` step. ```tsx {5} const steps: TourStepDetails[] = [ { id: 'step-1', type: 'dialog', backdrop: false, }, ] ``` ### Effects Step effects are functions that are called before a step is opened. They are useful for adding custom logic to a step. This function provides the following methods: - `next()`: Call this method to move to the next step. - `show()`: Call this method to show the current step. - `update(details: StepDetails)`: Call this method to update the details of the current step (say, after data has been fetched). ```tsx const steps: TourStepDetails[] = [ { id: 'step-1', type: 'tooltip', effect({ next, show, update }) { fetchData().then((res) => { // update the step details update({ title: res.title }) // then show show the step show() }) return () => { // cleanup fetch data } }, }, ] ``` ### Wait Wait steps are useful when you need to wait for a specific condition before proceeding to the next step. Use the step `effect` function to perform an action and then call `next()` to move to the next step. > **Note:** You cannot call `show()` in a wait step. ```tsx const steps: TourStepDetails[] = [ { id: 'step-1', type: 'wait', effect({ next }) { const button = document.querySelector('#button') const listener = () => next() button.addEventListener('click', listener) return () => button.removeEventListener('click', listener) }, }, ] ``` ### Styling Ensure the `box-sizing` is set to `border-box` for the means of measuring the tour target. ```css * { box-sizing: border-box; } ``` Ensure the `body` has a `position` of `relative`. ```css body { position: relative; } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `tour` | `UseTourReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `StepAction` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ActionTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | action-trigger | | `[data-type]` | The type of the item | | `[data-disabled]` | Present when disabled | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Backdrop | | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | close-trigger | | `[data-type]` | The type of the item | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the content | | `[data-step]` | | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested tours | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | description | | `[data-placement]` | The placement of the description | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | positioner | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the positioner | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Positioner | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Spotlight | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | title | | `[data-placement]` | The placement of the title | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `tour` | `UseTourReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `StepAction` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ActionTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | action-trigger | | `[data-type]` | The type of the item | | `[data-disabled]` | Present when disabled | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Backdrop | | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | close-trigger | | `[data-type]` | The type of the item | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the content | | `[data-step]` | | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested tours | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | description | | `[data-placement]` | The placement of the description | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | positioner | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the positioner | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Positioner | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Spotlight | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'h2'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | title | | `[data-placement]` | The placement of the title | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `tour` | `TourApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `StepAction` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ActionTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | action-trigger | | `[data-type]` | The type of the item | | `[data-disabled]` | Present when disabled | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Backdrop | | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | close-trigger | | `[data-type]` | The type of the item | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the content | | `[data-step]` | | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested tours | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | description | | `[data-placement]` | The placement of the description | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | positioner | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the positioner | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Positioner | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Spotlight | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | title | | `[data-placement]` | The placement of the title | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `tour` | `UseTourReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `StepAction` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ActionTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | action-trigger | | `[data-type]` | The type of the item | | `[data-disabled]` | Present when disabled | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Backdrop | | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **CloseTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | close-trigger | | `[data-type]` | The type of the item | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the content | | `[data-step]` | | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested tours | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTourContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Description Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | description | | `[data-placement]` | The placement of the description | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | positioner | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the positioner | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Positioner | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Spotlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Spotlight CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Spotlight | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Title Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | title | | `[data-placement]` | The placement of the title | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the tour is open | | `totalSteps` | `number` | The total number of steps | | `stepIndex` | `number` | The index of the current step | | `step` | `StepDetails` | The current step details | | `hasNextStep` | `boolean` | Whether there is a next step | | `hasPrevStep` | `boolean` | Whether there is a previous step | | `firstStep` | `boolean` | Whether the current step is the first step | | `lastStep` | `boolean` | Whether the current step is the last step | | `addStep` | `(step: StepDetails) => void` | Add a new step to the tour | | `removeStep` | `(id: string) => void` | Remove a step from the tour | | `updateStep` | `(id: string, stepOverrides: Partial) => void` | Update a step in the tour with partial details | | `setSteps` | `(steps: StepDetails[]) => void` | Set the steps of the tour | | `setStep` | `(id: string) => void` | Set the current step of the tour | | `start` | `(id?: string) => void` | Start the tour at a specific step (or the first step if not provided) | | `isValidStep` | `(id: string) => boolean` | Check if a step is valid | | `isCurrentStep` | `(id: string) => boolean` | Check if a step is visible | | `next` | `VoidFunction` | Move to the next step | | `prev` | `VoidFunction` | Move to the previous step | | `getProgressText` | `() => string` | Returns the progress text | | `getProgressPercent` | `() => number` | Returns the progress percent | --- # Tour (VUE) ## Anatomy ```tsx const tour = useTour({ steps: [...] }) ``` ## Examples **Example: basic** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { MoreHorizontalIcon, SaveIcon, SparklesIcon, UploadIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'welcome', type: 'dialog', title: 'Welcome to the App!', description: "Let's take a quick tour to get you started with the main features.", actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'upload', type: 'tooltip', title: 'Upload Files', description: 'Click here to upload your files to the cloud.', target: () => document.querySelector('#btn-upload'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'save', type: 'tooltip', title: 'Save Changes', description: 'Save your work to keep your progress.', target: () => document.querySelector('#btn-save'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'more', type: 'tooltip', title: 'More Options', description: 'Access additional settings and actions from this menu.', target: () => document.querySelector('#btn-more'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: "You're all set!", description: 'You now know the basics. Enjoy using the app!', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const Basic = () => { const tour = useTour({ steps }) return (
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { MoreHorizontalIcon, SaveIcon, SparklesIcon, UploadIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'welcome', type: 'dialog', title: 'Welcome to the App!', description: "Let's take a quick tour to get you started with the main features.", actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'upload', type: 'tooltip', title: 'Upload Files', description: 'Click here to upload your files to the cloud.', target: () => document.querySelector('#btn-upload'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'save', type: 'tooltip', title: 'Save Changes', description: 'Save your work to keep your progress.', target: () => document.querySelector('#btn-save'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'more', type: 'tooltip', title: 'More Options', description: 'Access additional settings and actions from this menu.', target: () => document.querySelector('#btn-more'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: "You're all set!", description: 'You now know the basics. Enjoy using the app!', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const Basic = () => { const tour = useTour({ steps }) return (
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Step Types Demonstrate all three step types in a single tour: `dialog` for welcome/completion, `tooltip` anchored to elements, and `floating` for fixed-position content. **Example: mixed-types** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'welcome', type: 'dialog', title: 'Welcome!', description: 'This tour demonstrates different step types: dialog, tooltip, and floating.', actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'tooltip-step', type: 'tooltip', title: 'Tooltip Step', description: 'This step appears as a tooltip anchored to a specific element.', target: () => document.querySelector('#target-element'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'floating-step', type: 'floating', placement: 'bottom-end', title: 'Floating Step', description: 'This step floats at a fixed position on the screen, independent of any target.', actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: 'Tour Complete!', description: 'You have seen all the different step types available.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const MixedTypes = () => { const tour = useTour({ steps }) return (
                    Target Element
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'welcome', type: 'dialog', title: 'Welcome!', description: 'This tour demonstrates different step types: dialog, tooltip, and floating.', actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'tooltip-step', type: 'tooltip', title: 'Tooltip Step', description: 'This step appears as a tooltip anchored to a specific element.', target: () => document.querySelector('#target-element'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'floating-step', type: 'floating', placement: 'bottom-end', title: 'Floating Step', description: 'This step floats at a fixed position on the screen, independent of any target.', actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: 'Tour Complete!', description: 'You have seen all the different step types available.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const MixedTypes = () => { const tour = useTour({ steps }) return (
                    Target Element
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Target Element
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Progress Display a visual progress indicator at the bottom of the tour content showing how far along the user is. **Example: progress-bar** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'Progress Tracking', description: 'Watch the progress bar at the bottom as you navigate.', target: () => document.querySelector('#progress-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Halfway There', description: 'The progress bar shows how far along you are.', target: () => document.querySelector('#progress-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Almost Done', description: 'One more step to complete the tour.', target: () => document.querySelector('#progress-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-4', type: 'tooltip', title: 'Complete!', description: 'You have completed all the steps.', target: () => document.querySelector('#progress-4'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const ProgressBar = () => { const tour = useTour({ steps }) return (
                    Step 1
                    Step 2
                    Step 3
                    Step 4
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'Progress Tracking', description: 'Watch the progress bar at the bottom as you navigate.', target: () => document.querySelector('#progress-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Halfway There', description: 'The progress bar shows how far along you are.', target: () => document.querySelector('#progress-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Almost Done', description: 'One more step to complete the tour.', target: () => document.querySelector('#progress-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-4', type: 'tooltip', title: 'Complete!', description: 'You have completed all the steps.', target: () => document.querySelector('#progress-4'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const ProgressBar = () => { const tour = useTour({ steps }) return (
                    Step 1
                    Step 2
                    Step 3
                    Step 4
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Step 1
                    Step 2
                    Step 3
                    Step 4
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Skip Allow users to skip the entire tour at any step by adding a skip action. **Example: skip-tour** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'First Feature', description: 'You can skip this tour at any time using the Skip button.', target: () => document.querySelector('#item-1'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-2', type: 'tooltip', title: 'Second Feature', description: 'Continue or skip to end the tour early.', target: () => document.querySelector('#item-2'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Feature', description: 'This is the last step of the tour.', target: () => document.querySelector('#item-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const SkipTour = () => { const tour = useTour({ steps }) return (
                    Item 1
                    Item 2
                    Item 3
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'First Feature', description: 'You can skip this tour at any time using the Skip button.', target: () => document.querySelector('#item-1'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-2', type: 'tooltip', title: 'Second Feature', description: 'Continue or skip to end the tour early.', target: () => document.querySelector('#item-2'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Feature', description: 'This is the last step of the tour.', target: () => document.querySelector('#item-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const SkipTour = () => { const tour = useTour({ steps }) return (
                    Item 1
                    Item 2
                    Item 3
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Item 1
                    Item 2
                    Item 3
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Keyboard Navigation Enable arrow key navigation between tour steps using the `keyboardNavigation` prop. **Example: keyboard-navigation** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { KeyboardIcon, SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'Keyboard Navigation', description: 'Press the right arrow key (→) to go to the next step.', target: () => document.querySelector('#key-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Go Back', description: 'Press the left arrow key (←) to go back.', target: () => document.querySelector('#key-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Close Tour', description: 'Press Escape to close the tour at any time.', target: () => document.querySelector('#key-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const KeyboardNavigation = () => { const tour = useTour({ steps, keyboardNavigation: true }) return (

                    Use arrow keys to navigate, Escape to close

                    Step 1
                    Step 2
                    Step 3
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { KeyboardIcon, SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'Keyboard Navigation', description: 'Press the right arrow key to go to the next step.', target: () => document.querySelector('#key-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Go Back', description: 'Press the left arrow key to go back.', target: () => document.querySelector('#key-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Close Tour', description: 'Press Escape to close the tour at any time.', target: () => document.querySelector('#key-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const KeyboardNavigation = () => { const tour = useTour({ steps, keyboardNavigation: true }) return (

                    Use arrow keys to navigate, Escape to close

                    Step 1
                    Step 2
                    Step 3
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Use arrow keys to navigate, Escape to close

                    Step 1
                    Step 2
                    Step 3
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Events Listen to tour lifecycle events like `onStepChange` and `onStatusChange` to track user progress. **Example: events** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'First Step', description: 'Watch the event log below as you navigate.', target: () => document.querySelector('#event-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Second Step', description: 'Each step change triggers an event.', target: () => document.querySelector('#event-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Step', description: 'Complete the tour to see the status change.', target: () => document.querySelector('#event-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const Events = () => { const [logs, setLogs] = useState([]) const addLog = (message: string) => { setLogs((prev) => [...prev, message]) } const tour = useTour({ steps, onStepChange(details) { addLog(`Step changed: ${details.stepId}`) }, onStatusChange(details) { addLog(`Status: ${details.status}`) }, }) return (
                    Step 1
                    Step 2
                    Step 3
                    Event Log: {logs.length === 0 ? (
                    Start the tour to see events
                    ) : ( logs.map((log, i) => (
                    {log}
                    )) )}
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For, Show, createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'First Step', description: 'Watch the event log below as you navigate.', target: () => document.querySelector('#event-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Second Step', description: 'Each step change triggers an event.', target: () => document.querySelector('#event-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Step', description: 'Complete the tour to see the status change.', target: () => document.querySelector('#event-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const Events = () => { const [logs, setLogs] = createSignal([]) const addLog = (message: string) => { setLogs((prev) => [...prev, message]) } const tour = useTour({ steps, onStepChange(details) { addLog(`Step changed: ${details.stepId}`) }, onStatusChange(details) { addLog(`Status: ${details.status}`) }, }) return (
                    Step 1
                    Step 2
                    Step 3
                    Event Log: 0} fallback={
                    Start the tour to see events
                    }> {(log) =>
                    {log}
                    }
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Step 1
                    Step 2
                    Step 3
                    Event Log: {#if logs.length === 0}
                    Start the tour to see events
                    {:else} {#each logs as log, i (i)}
                    {log}
                    {/each} {/if}
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Wait for Click Use the `effect` function with `waitForEvent` to wait for user interaction before proceeding to the next step. **Example: wait-for-click** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour, waitForEvent } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Interactive Tutorial', description: 'This tour will guide you through actions. You must complete each step to proceed.', actions: [{ label: 'Begin', action: 'next' }], }, { id: 'click-add', type: 'tooltip', title: 'Click the Add Button', description: 'Click the "Add Item" button to continue.', target: () => document.querySelector('#btn-add'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'click-edit', type: 'tooltip', title: 'Click the Edit Button', description: 'Now click the "Edit" button.', target: () => document.querySelector('#btn-edit'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'click-delete', type: 'tooltip', title: 'Click the Delete Button', description: 'Finally, click the "Delete" button.', target: () => document.querySelector('#btn-delete'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'complete', type: 'dialog', title: 'Well Done!', description: 'You completed all the interactive steps.', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const WaitForClick = () => { const tour = useTour({ steps }) return (
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour, waitForEvent } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Interactive Tutorial', description: 'This tour will guide you through actions. You must complete each step to proceed.', actions: [{ label: 'Begin', action: 'next' }], }, { id: 'click-add', type: 'tooltip', title: 'Click the Add Button', description: 'Click the "Add Item" button to continue.', target: () => document.querySelector('#btn-add'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'click-edit', type: 'tooltip', title: 'Click the Edit Button', description: 'Now click the "Edit" button.', target: () => document.querySelector('#btn-edit'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'click-delete', type: 'tooltip', title: 'Click the Delete Button', description: 'Finally, click the "Delete" button.', target: () => document.querySelector('#btn-delete'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'complete', type: 'dialog', title: 'Well Done!', description: 'You completed all the interactive steps.', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const WaitForClick = () => { const tour = useTour({ steps }) return (
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Wait for Input Create form tutorials that wait for users to enter valid input before advancing. **Example: wait-for-input** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour, waitForEvent } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Form Tutorial', description: 'Learn how to fill out the form by following the guided steps.', actions: [{ label: 'Start', action: 'next' }], }, { id: 'enter-name', type: 'tooltip', title: 'Enter Your Name', description: 'Type your name in the input field to continue.', target: () => document.querySelector('#input-name'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'input', { predicate: (el) => el.value.trim().length >= 2, }) promise.then(() => next()) return cancel }, }, { id: 'enter-email', type: 'tooltip', title: 'Enter Your Email', description: 'Now enter a valid email address.', target: () => document.querySelector('#input-email'), effect({ next, target, show }) { show() const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ const [promise, cancel] = waitForEvent(target, 'input', { predicate: (el) => emailRegex.test(el.value), }) promise.then(() => next()) return cancel }, }, { id: 'check-terms', type: 'tooltip', title: 'Accept Terms', description: 'Check the checkbox to accept the terms.', target: () => document.querySelector('#checkbox-terms'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'change', { predicate: (el) => el.checked, }) promise.then(() => next()) return cancel }, }, { id: 'complete', type: 'dialog', title: 'Form Complete!', description: 'You have successfully filled out the form.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const WaitForInput = () => { const tour = useTour({ steps }) return (
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour, waitForEvent } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Form Tutorial', description: 'Learn how to fill out the form by following the guided steps.', actions: [{ label: 'Start', action: 'next' }], }, { id: 'enter-name', type: 'tooltip', title: 'Enter Your Name', description: 'Type your name in the input field to continue.', target: () => document.querySelector('#input-name'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'input', { predicate: (el) => el.value.trim().length >= 2, }) promise.then(() => next()) return cancel }, }, { id: 'enter-email', type: 'tooltip', title: 'Enter Your Email', description: 'Now enter a valid email address.', target: () => document.querySelector('#input-email'), effect({ next, target, show }) { show() const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ const [promise, cancel] = waitForEvent(target, 'input', { predicate: (el) => emailRegex.test(el.value), }) promise.then(() => next()) return cancel }, }, { id: 'check-terms', type: 'tooltip', title: 'Accept Terms', description: 'Check the checkbox to accept the terms.', target: () => document.querySelector('#checkbox-terms'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'change', { predicate: (el) => el.checked, }) promise.then(() => next()) return cancel }, }, { id: 'complete', type: 'dialog', title: 'Form Complete!', description: 'You have successfully filled out the form.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const WaitForInput = () => { const tour = useTour({ steps }) return (
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Wait for Element Wait for dynamically rendered elements to appear in the DOM before showing a step. **Example: wait-for-element** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour, waitForElement, waitForEvent } from '@ark-ui/react/tour' import { PlusIcon, SparklesIcon, XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Dynamic Elements', description: 'This tour demonstrates waiting for elements that appear dynamically.', actions: [{ label: 'Start', action: 'next' }], }, { id: 'add-item', type: 'tooltip', title: 'Add an Item', description: 'Click the button to add a new item to the list.', target: () => document.querySelector('#btn-add-item'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'new-item', type: 'tooltip', title: 'New Item Added!', description: 'The tour waited for this element to appear before showing this step.', target: () => document.querySelector('[data-item="new"]'), effect({ show }) { const [promise, cancel] = waitForElement(() => document.querySelector('[data-item="new"]'), { timeout: 5000, }) promise.then(() => show()) return () => cancel() }, actions: [{ label: 'Next', action: 'next' }], }, { id: 'complete', type: 'dialog', title: 'Tour Complete', description: 'You learned how to use waitForElement for dynamic content.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const WaitForElement = () => { const tour = useTour({ steps }) const [items, setItems] = useState(['Item 1', 'Item 2']) const addItem = () => { setItems((prev) => [...prev, `Item ${prev.length + 1}`]) } return (
                    {items.map((item, index) => (
                    2 ? 'new' : undefined} > {item}
                    ))}
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour, waitForElement, waitForEvent } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { PlusIcon, SparklesIcon, XIcon } from 'lucide-solid' import { For, createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Dynamic Elements', description: 'This tour demonstrates waiting for elements that appear dynamically.', actions: [{ label: 'Start', action: 'next' }], }, { id: 'add-item', type: 'tooltip', title: 'Add an Item', description: 'Click the button to add a new item to the list.', target: () => document.querySelector('#btn-add-item'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'new-item', type: 'tooltip', title: 'New Item Added!', description: 'The tour waited for this element to appear before showing this step.', target: () => document.querySelector('[data-item="new"]'), effect({ show }) { const [promise, cancel] = waitForElement(() => document.querySelector('[data-item="new"]'), { timeout: 5000, }) promise.then(() => show()) return () => cancel() }, actions: [{ label: 'Next', action: 'next' }], }, { id: 'complete', type: 'dialog', title: 'Tour Complete', description: 'You learned how to use waitForElement for dynamic content.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const WaitForElement = () => { const tour = useTour({ steps }) const [items, setItems] = createSignal(['Item 1', 'Item 2']) const addItem = () => { setItems((prev) => [...prev, `Item ${prev.length + 1}`]) } return (
                    {(item, index) => (
                    2 ? 'new' : undefined} > {item}
                    )}
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each items as item, index (item)}
                    2 ? 'new' : undefined}> {item}
                    {/each}
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Async Load data asynchronously and update step content before displaying it using the `effect` function with `show()` and `update()`. **Example: async-step** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Async Data Loading', description: 'This tour demonstrates loading data before showing a step.', actions: [{ label: 'Next', action: 'next' }], }, { id: 'user-info', type: 'tooltip', title: 'Loading...', description: 'Fetching user data...', target: () => document.querySelector('#user-card'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], effect({ show, update }) { const controller = new AbortController() fetch('https://api.github.com/users/segunadebayo', { signal: controller.signal }) .then((res) => res.json()) .then((data) => { update({ title: `Welcome, ${data.name || data.login}!`, description: `You have ${data.public_repos} public repositories and ${data.followers} followers.`, }) show() }) .catch(() => { update({ title: 'User Profile', description: 'Could not load user data. Please try again.', }) show() }) return () => controller.abort() }, }, { id: 'complete', type: 'dialog', title: 'Tour Complete', description: 'The async step loaded data from the GitHub API before displaying.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const AsyncStep = () => { const tour = useTour({ steps }) return (
                    User Profile Card
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Async Data Loading', description: 'This tour demonstrates loading data before showing a step.', actions: [{ label: 'Next', action: 'next' }], }, { id: 'user-info', type: 'tooltip', title: 'Loading...', description: 'Fetching user data...', target: () => document.querySelector('#user-card'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], effect({ show, update }) { const controller = new AbortController() fetch('https://api.github.com/users/segunadebayo', { signal: controller.signal }) .then((res) => res.json()) .then((data) => { update({ title: `Welcome, ${data.name || data.login}!`, description: `You have ${data.public_repos} public repositories and ${data.followers} followers.`, }) show() }) .catch(() => { update({ title: 'User Profile', description: 'Could not load user data. Please try again.', }) show() }) return () => controller.abort() }, }, { id: 'complete', type: 'dialog', title: 'Tour Complete', description: 'The async step loaded data from the GitHub API before displaying.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const AsyncStep = () => { const tour = useTour({ steps }) return (
                    User Profile Card
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    User Profile Card
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ## Guides ### Step Types The tour machine supports different types of steps, allowing you to create a diverse and interactive tour experience. The available step types are defined in the `StepType` type: - `tooltip`: Displays the step content as a tooltip, typically positioned near the target element. - `dialog`: Shows the step content in a modal dialog centered on screen, useful for starting or ending the tour. This usually don't have a `target` defined. - `floating`: Presents the step content as a floating element, which can be positioned flexibly on the screen. This usually don't have a `target` defined. - `wait`: A special type that waits for a specific condition before proceeding to the next step. ```tsx const steps: TourStepDetails[] = [ { id: 'step-1', type: 'tooltip', placement: 'top-start', target: () => document.querySelector('#target-1'), title: 'Tooltip Step', description: 'This is a tooltip step', }, { id: 'step-2', type: 'dialog', title: 'Dialog Step', description: 'This is a dialog step', }, { id: 'step-3', type: 'floating', placement: 'top-start', title: 'Floating Step', description: 'This is a floating step', }, { id: 'step-4', type: 'wait', title: 'Wait Step', description: 'This is a wait step', effect({ next }) { // do something and go next // you can also return a cleanup }, }, ] ``` ### Actions Every step supports a list of actions that are rendered in the step footer.Use the `actions` property to define each action. ```tsx const steps: TourStepDetails[] = [ { id: 'step-1', type: 'dialog', title: 'Dialog Step', description: 'This is a dialog step', actions: [{ label: 'Show me a tour!', action: 'next' }], }, ] ``` ### Tooltip Placement Use the `placement` property to define the placement of the tooltip. ```tsx {5} const steps: TourStepDetails[] = [ { id: 'step-1', type: 'tooltip', placement: 'top-start', // ... }, ] ``` ### Hide Arrow Set `arrow: false` in the step property to hide the tooltip arrow. This is only useful for tooltip steps. ```tsx {5} const steps: TourStepDetails[] = [ { id: 'step-1', type: 'tooltip', arrow: false, }, ] ``` ### Hide Backdrop Set `backdrop: false` in the step property to hide the backdrop. This applies to all step types except the `wait` step. ```tsx {5} const steps: TourStepDetails[] = [ { id: 'step-1', type: 'dialog', backdrop: false, }, ] ``` ### Effects Step effects are functions that are called before a step is opened. They are useful for adding custom logic to a step. This function provides the following methods: - `next()`: Call this method to move to the next step. - `show()`: Call this method to show the current step. - `update(details: StepDetails)`: Call this method to update the details of the current step (say, after data has been fetched). ```tsx const steps: TourStepDetails[] = [ { id: 'step-1', type: 'tooltip', effect({ next, show, update }) { fetchData().then((res) => { // update the step details update({ title: res.title }) // then show show the step show() }) return () => { // cleanup fetch data } }, }, ] ``` ### Wait Wait steps are useful when you need to wait for a specific condition before proceeding to the next step. Use the step `effect` function to perform an action and then call `next()` to move to the next step. > **Note:** You cannot call `show()` in a wait step. ```tsx const steps: TourStepDetails[] = [ { id: 'step-1', type: 'wait', effect({ next }) { const button = document.querySelector('#button') const listener = () => next() button.addEventListener('click', listener) return () => button.removeEventListener('click', listener) }, }, ] ``` ### Styling Ensure the `box-sizing` is set to `border-box` for the means of measuring the tour target. ```css * { box-sizing: border-box; } ``` Ensure the `body` has a `position` of `relative`. ```css body { position: relative; } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `tour` | `UseTourReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `StepAction` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ActionTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | action-trigger | | `[data-type]` | The type of the item | | `[data-disabled]` | Present when disabled | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Backdrop | | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | close-trigger | | `[data-type]` | The type of the item | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the content | | `[data-step]` | | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested tours | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | description | | `[data-placement]` | The placement of the description | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | positioner | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the positioner | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Positioner | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Spotlight | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | title | | `[data-placement]` | The placement of the title | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `tour` | `UseTourReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `StepAction` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ActionTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | action-trigger | | `[data-type]` | The type of the item | | `[data-disabled]` | Present when disabled | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Backdrop | | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | close-trigger | | `[data-type]` | The type of the item | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the content | | `[data-step]` | | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested tours | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | description | | `[data-placement]` | The placement of the description | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | positioner | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the positioner | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Positioner | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Spotlight | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'h2'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | title | | `[data-placement]` | The placement of the title | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `tour` | `TourApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `StepAction` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ActionTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | action-trigger | | `[data-type]` | The type of the item | | `[data-disabled]` | Present when disabled | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Backdrop | | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | close-trigger | | `[data-type]` | The type of the item | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the content | | `[data-step]` | | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested tours | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | description | | `[data-placement]` | The placement of the description | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | positioner | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the positioner | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Positioner | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Spotlight | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | title | | `[data-placement]` | The placement of the title | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `tour` | `UseTourReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `StepAction` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ActionTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | action-trigger | | `[data-type]` | The type of the item | | `[data-disabled]` | Present when disabled | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Backdrop | | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **CloseTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | close-trigger | | `[data-type]` | The type of the item | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the content | | `[data-step]` | | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested tours | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTourContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Description Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | description | | `[data-placement]` | The placement of the description | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | positioner | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the positioner | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Positioner | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Spotlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Spotlight CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Spotlight | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Title Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | title | | `[data-placement]` | The placement of the title | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the tour is open | | `totalSteps` | `number` | The total number of steps | | `stepIndex` | `number` | The index of the current step | | `step` | `StepDetails` | The current step details | | `hasNextStep` | `boolean` | Whether there is a next step | | `hasPrevStep` | `boolean` | Whether there is a previous step | | `firstStep` | `boolean` | Whether the current step is the first step | | `lastStep` | `boolean` | Whether the current step is the last step | | `addStep` | `(step: StepDetails) => void` | Add a new step to the tour | | `removeStep` | `(id: string) => void` | Remove a step from the tour | | `updateStep` | `(id: string, stepOverrides: Partial) => void` | Update a step in the tour with partial details | | `setSteps` | `(steps: StepDetails[]) => void` | Set the steps of the tour | | `setStep` | `(id: string) => void` | Set the current step of the tour | | `start` | `(id?: string) => void` | Start the tour at a specific step (or the first step if not provided) | | `isValidStep` | `(id: string) => boolean` | Check if a step is valid | | `isCurrentStep` | `(id: string) => boolean` | Check if a step is visible | | `next` | `VoidFunction` | Move to the next step | | `prev` | `VoidFunction` | Move to the previous step | | `getProgressText` | `() => string` | Returns the progress text | | `getProgressPercent` | `() => number` | Returns the progress percent | --- # Tour (SVELTE) ## Anatomy ```tsx const tour = useTour({ steps: [...] }) ``` ## Examples **Example: basic** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { MoreHorizontalIcon, SaveIcon, SparklesIcon, UploadIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'welcome', type: 'dialog', title: 'Welcome to the App!', description: "Let's take a quick tour to get you started with the main features.", actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'upload', type: 'tooltip', title: 'Upload Files', description: 'Click here to upload your files to the cloud.', target: () => document.querySelector('#btn-upload'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'save', type: 'tooltip', title: 'Save Changes', description: 'Save your work to keep your progress.', target: () => document.querySelector('#btn-save'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'more', type: 'tooltip', title: 'More Options', description: 'Access additional settings and actions from this menu.', target: () => document.querySelector('#btn-more'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: "You're all set!", description: 'You now know the basics. Enjoy using the app!', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const Basic = () => { const tour = useTour({ steps }) return (
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { MoreHorizontalIcon, SaveIcon, SparklesIcon, UploadIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'welcome', type: 'dialog', title: 'Welcome to the App!', description: "Let's take a quick tour to get you started with the main features.", actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'upload', type: 'tooltip', title: 'Upload Files', description: 'Click here to upload your files to the cloud.', target: () => document.querySelector('#btn-upload'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'save', type: 'tooltip', title: 'Save Changes', description: 'Save your work to keep your progress.', target: () => document.querySelector('#btn-save'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'more', type: 'tooltip', title: 'More Options', description: 'Access additional settings and actions from this menu.', target: () => document.querySelector('#btn-more'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: "You're all set!", description: 'You now know the basics. Enjoy using the app!', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const Basic = () => { const tour = useTour({ steps }) return (
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Step Types Demonstrate all three step types in a single tour: `dialog` for welcome/completion, `tooltip` anchored to elements, and `floating` for fixed-position content. **Example: mixed-types** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'welcome', type: 'dialog', title: 'Welcome!', description: 'This tour demonstrates different step types: dialog, tooltip, and floating.', actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'tooltip-step', type: 'tooltip', title: 'Tooltip Step', description: 'This step appears as a tooltip anchored to a specific element.', target: () => document.querySelector('#target-element'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'floating-step', type: 'floating', placement: 'bottom-end', title: 'Floating Step', description: 'This step floats at a fixed position on the screen, independent of any target.', actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: 'Tour Complete!', description: 'You have seen all the different step types available.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const MixedTypes = () => { const tour = useTour({ steps }) return (
                    Target Element
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'welcome', type: 'dialog', title: 'Welcome!', description: 'This tour demonstrates different step types: dialog, tooltip, and floating.', actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'tooltip-step', type: 'tooltip', title: 'Tooltip Step', description: 'This step appears as a tooltip anchored to a specific element.', target: () => document.querySelector('#target-element'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'floating-step', type: 'floating', placement: 'bottom-end', title: 'Floating Step', description: 'This step floats at a fixed position on the screen, independent of any target.', actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: 'Tour Complete!', description: 'You have seen all the different step types available.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const MixedTypes = () => { const tour = useTour({ steps }) return (
                    Target Element
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Target Element
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Progress Display a visual progress indicator at the bottom of the tour content showing how far along the user is. **Example: progress-bar** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'Progress Tracking', description: 'Watch the progress bar at the bottom as you navigate.', target: () => document.querySelector('#progress-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Halfway There', description: 'The progress bar shows how far along you are.', target: () => document.querySelector('#progress-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Almost Done', description: 'One more step to complete the tour.', target: () => document.querySelector('#progress-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-4', type: 'tooltip', title: 'Complete!', description: 'You have completed all the steps.', target: () => document.querySelector('#progress-4'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const ProgressBar = () => { const tour = useTour({ steps }) return (
                    Step 1
                    Step 2
                    Step 3
                    Step 4
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'Progress Tracking', description: 'Watch the progress bar at the bottom as you navigate.', target: () => document.querySelector('#progress-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Halfway There', description: 'The progress bar shows how far along you are.', target: () => document.querySelector('#progress-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Almost Done', description: 'One more step to complete the tour.', target: () => document.querySelector('#progress-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-4', type: 'tooltip', title: 'Complete!', description: 'You have completed all the steps.', target: () => document.querySelector('#progress-4'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const ProgressBar = () => { const tour = useTour({ steps }) return (
                    Step 1
                    Step 2
                    Step 3
                    Step 4
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Step 1
                    Step 2
                    Step 3
                    Step 4
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Skip Allow users to skip the entire tour at any step by adding a skip action. **Example: skip-tour** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'First Feature', description: 'You can skip this tour at any time using the Skip button.', target: () => document.querySelector('#item-1'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-2', type: 'tooltip', title: 'Second Feature', description: 'Continue or skip to end the tour early.', target: () => document.querySelector('#item-2'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Feature', description: 'This is the last step of the tour.', target: () => document.querySelector('#item-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const SkipTour = () => { const tour = useTour({ steps }) return (
                    Item 1
                    Item 2
                    Item 3
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'First Feature', description: 'You can skip this tour at any time using the Skip button.', target: () => document.querySelector('#item-1'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-2', type: 'tooltip', title: 'Second Feature', description: 'Continue or skip to end the tour early.', target: () => document.querySelector('#item-2'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Feature', description: 'This is the last step of the tour.', target: () => document.querySelector('#item-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const SkipTour = () => { const tour = useTour({ steps }) return (
                    Item 1
                    Item 2
                    Item 3
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Item 1
                    Item 2
                    Item 3
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Keyboard Navigation Enable arrow key navigation between tour steps using the `keyboardNavigation` prop. **Example: keyboard-navigation** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { KeyboardIcon, SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'Keyboard Navigation', description: 'Press the right arrow key (→) to go to the next step.', target: () => document.querySelector('#key-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Go Back', description: 'Press the left arrow key (←) to go back.', target: () => document.querySelector('#key-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Close Tour', description: 'Press Escape to close the tour at any time.', target: () => document.querySelector('#key-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const KeyboardNavigation = () => { const tour = useTour({ steps, keyboardNavigation: true }) return (

                    Use arrow keys to navigate, Escape to close

                    Step 1
                    Step 2
                    Step 3
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { KeyboardIcon, SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'Keyboard Navigation', description: 'Press the right arrow key to go to the next step.', target: () => document.querySelector('#key-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Go Back', description: 'Press the left arrow key to go back.', target: () => document.querySelector('#key-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Close Tour', description: 'Press Escape to close the tour at any time.', target: () => document.querySelector('#key-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const KeyboardNavigation = () => { const tour = useTour({ steps, keyboardNavigation: true }) return (

                    Use arrow keys to navigate, Escape to close

                    Step 1
                    Step 2
                    Step 3
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Use arrow keys to navigate, Escape to close

                    Step 1
                    Step 2
                    Step 3
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Events Listen to tour lifecycle events like `onStepChange` and `onStatusChange` to track user progress. **Example: events** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'First Step', description: 'Watch the event log below as you navigate.', target: () => document.querySelector('#event-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Second Step', description: 'Each step change triggers an event.', target: () => document.querySelector('#event-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Step', description: 'Complete the tour to see the status change.', target: () => document.querySelector('#event-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const Events = () => { const [logs, setLogs] = useState([]) const addLog = (message: string) => { setLogs((prev) => [...prev, message]) } const tour = useTour({ steps, onStepChange(details) { addLog(`Step changed: ${details.stepId}`) }, onStatusChange(details) { addLog(`Status: ${details.status}`) }, }) return (
                    Step 1
                    Step 2
                    Step 3
                    Event Log: {logs.length === 0 ? (
                    Start the tour to see events
                    ) : ( logs.map((log, i) => (
                    {log}
                    )) )}
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For, Show, createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'First Step', description: 'Watch the event log below as you navigate.', target: () => document.querySelector('#event-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Second Step', description: 'Each step change triggers an event.', target: () => document.querySelector('#event-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Step', description: 'Complete the tour to see the status change.', target: () => document.querySelector('#event-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const Events = () => { const [logs, setLogs] = createSignal([]) const addLog = (message: string) => { setLogs((prev) => [...prev, message]) } const tour = useTour({ steps, onStepChange(details) { addLog(`Step changed: ${details.stepId}`) }, onStatusChange(details) { addLog(`Status: ${details.status}`) }, }) return (
                    Step 1
                    Step 2
                    Step 3
                    Event Log: 0} fallback={
                    Start the tour to see events
                    }> {(log) =>
                    {log}
                    }
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Step 1
                    Step 2
                    Step 3
                    Event Log: {#if logs.length === 0}
                    Start the tour to see events
                    {:else} {#each logs as log, i (i)}
                    {log}
                    {/each} {/if}
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Wait for Click Use the `effect` function with `waitForEvent` to wait for user interaction before proceeding to the next step. **Example: wait-for-click** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour, waitForEvent } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Interactive Tutorial', description: 'This tour will guide you through actions. You must complete each step to proceed.', actions: [{ label: 'Begin', action: 'next' }], }, { id: 'click-add', type: 'tooltip', title: 'Click the Add Button', description: 'Click the "Add Item" button to continue.', target: () => document.querySelector('#btn-add'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'click-edit', type: 'tooltip', title: 'Click the Edit Button', description: 'Now click the "Edit" button.', target: () => document.querySelector('#btn-edit'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'click-delete', type: 'tooltip', title: 'Click the Delete Button', description: 'Finally, click the "Delete" button.', target: () => document.querySelector('#btn-delete'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'complete', type: 'dialog', title: 'Well Done!', description: 'You completed all the interactive steps.', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const WaitForClick = () => { const tour = useTour({ steps }) return (
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour, waitForEvent } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Interactive Tutorial', description: 'This tour will guide you through actions. You must complete each step to proceed.', actions: [{ label: 'Begin', action: 'next' }], }, { id: 'click-add', type: 'tooltip', title: 'Click the Add Button', description: 'Click the "Add Item" button to continue.', target: () => document.querySelector('#btn-add'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'click-edit', type: 'tooltip', title: 'Click the Edit Button', description: 'Now click the "Edit" button.', target: () => document.querySelector('#btn-edit'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'click-delete', type: 'tooltip', title: 'Click the Delete Button', description: 'Finally, click the "Delete" button.', target: () => document.querySelector('#btn-delete'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'complete', type: 'dialog', title: 'Well Done!', description: 'You completed all the interactive steps.', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const WaitForClick = () => { const tour = useTour({ steps }) return (
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Wait for Input Create form tutorials that wait for users to enter valid input before advancing. **Example: wait-for-input** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour, waitForEvent } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Form Tutorial', description: 'Learn how to fill out the form by following the guided steps.', actions: [{ label: 'Start', action: 'next' }], }, { id: 'enter-name', type: 'tooltip', title: 'Enter Your Name', description: 'Type your name in the input field to continue.', target: () => document.querySelector('#input-name'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'input', { predicate: (el) => el.value.trim().length >= 2, }) promise.then(() => next()) return cancel }, }, { id: 'enter-email', type: 'tooltip', title: 'Enter Your Email', description: 'Now enter a valid email address.', target: () => document.querySelector('#input-email'), effect({ next, target, show }) { show() const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ const [promise, cancel] = waitForEvent(target, 'input', { predicate: (el) => emailRegex.test(el.value), }) promise.then(() => next()) return cancel }, }, { id: 'check-terms', type: 'tooltip', title: 'Accept Terms', description: 'Check the checkbox to accept the terms.', target: () => document.querySelector('#checkbox-terms'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'change', { predicate: (el) => el.checked, }) promise.then(() => next()) return cancel }, }, { id: 'complete', type: 'dialog', title: 'Form Complete!', description: 'You have successfully filled out the form.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const WaitForInput = () => { const tour = useTour({ steps }) return (
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour, waitForEvent } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Form Tutorial', description: 'Learn how to fill out the form by following the guided steps.', actions: [{ label: 'Start', action: 'next' }], }, { id: 'enter-name', type: 'tooltip', title: 'Enter Your Name', description: 'Type your name in the input field to continue.', target: () => document.querySelector('#input-name'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'input', { predicate: (el) => el.value.trim().length >= 2, }) promise.then(() => next()) return cancel }, }, { id: 'enter-email', type: 'tooltip', title: 'Enter Your Email', description: 'Now enter a valid email address.', target: () => document.querySelector('#input-email'), effect({ next, target, show }) { show() const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ const [promise, cancel] = waitForEvent(target, 'input', { predicate: (el) => emailRegex.test(el.value), }) promise.then(() => next()) return cancel }, }, { id: 'check-terms', type: 'tooltip', title: 'Accept Terms', description: 'Check the checkbox to accept the terms.', target: () => document.querySelector('#checkbox-terms'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'change', { predicate: (el) => el.checked, }) promise.then(() => next()) return cancel }, }, { id: 'complete', type: 'dialog', title: 'Form Complete!', description: 'You have successfully filled out the form.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const WaitForInput = () => { const tour = useTour({ steps }) return (
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Wait for Element Wait for dynamically rendered elements to appear in the DOM before showing a step. **Example: wait-for-element** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour, waitForElement, waitForEvent } from '@ark-ui/react/tour' import { PlusIcon, SparklesIcon, XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Dynamic Elements', description: 'This tour demonstrates waiting for elements that appear dynamically.', actions: [{ label: 'Start', action: 'next' }], }, { id: 'add-item', type: 'tooltip', title: 'Add an Item', description: 'Click the button to add a new item to the list.', target: () => document.querySelector('#btn-add-item'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'new-item', type: 'tooltip', title: 'New Item Added!', description: 'The tour waited for this element to appear before showing this step.', target: () => document.querySelector('[data-item="new"]'), effect({ show }) { const [promise, cancel] = waitForElement(() => document.querySelector('[data-item="new"]'), { timeout: 5000, }) promise.then(() => show()) return () => cancel() }, actions: [{ label: 'Next', action: 'next' }], }, { id: 'complete', type: 'dialog', title: 'Tour Complete', description: 'You learned how to use waitForElement for dynamic content.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const WaitForElement = () => { const tour = useTour({ steps }) const [items, setItems] = useState(['Item 1', 'Item 2']) const addItem = () => { setItems((prev) => [...prev, `Item ${prev.length + 1}`]) } return (
                    {items.map((item, index) => (
                    2 ? 'new' : undefined} > {item}
                    ))}
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour, waitForElement, waitForEvent } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { PlusIcon, SparklesIcon, XIcon } from 'lucide-solid' import { For, createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Dynamic Elements', description: 'This tour demonstrates waiting for elements that appear dynamically.', actions: [{ label: 'Start', action: 'next' }], }, { id: 'add-item', type: 'tooltip', title: 'Add an Item', description: 'Click the button to add a new item to the list.', target: () => document.querySelector('#btn-add-item'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'new-item', type: 'tooltip', title: 'New Item Added!', description: 'The tour waited for this element to appear before showing this step.', target: () => document.querySelector('[data-item="new"]'), effect({ show }) { const [promise, cancel] = waitForElement(() => document.querySelector('[data-item="new"]'), { timeout: 5000, }) promise.then(() => show()) return () => cancel() }, actions: [{ label: 'Next', action: 'next' }], }, { id: 'complete', type: 'dialog', title: 'Tour Complete', description: 'You learned how to use waitForElement for dynamic content.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const WaitForElement = () => { const tour = useTour({ steps }) const [items, setItems] = createSignal(['Item 1', 'Item 2']) const addItem = () => { setItems((prev) => [...prev, `Item ${prev.length + 1}`]) } return (
                    {(item, index) => (
                    2 ? 'new' : undefined} > {item}
                    )}
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each items as item, index (item)}
                    2 ? 'new' : undefined}> {item}
                    {/each}
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Async Load data asynchronously and update step content before displaying it using the `effect` function with `show()` and `update()`. **Example: async-step** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Async Data Loading', description: 'This tour demonstrates loading data before showing a step.', actions: [{ label: 'Next', action: 'next' }], }, { id: 'user-info', type: 'tooltip', title: 'Loading...', description: 'Fetching user data...', target: () => document.querySelector('#user-card'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], effect({ show, update }) { const controller = new AbortController() fetch('https://api.github.com/users/segunadebayo', { signal: controller.signal }) .then((res) => res.json()) .then((data) => { update({ title: `Welcome, ${data.name || data.login}!`, description: `You have ${data.public_repos} public repositories and ${data.followers} followers.`, }) show() }) .catch(() => { update({ title: 'User Profile', description: 'Could not load user data. Please try again.', }) show() }) return () => controller.abort() }, }, { id: 'complete', type: 'dialog', title: 'Tour Complete', description: 'The async step loaded data from the GitHub API before displaying.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const AsyncStep = () => { const tour = useTour({ steps }) return (
                    User Profile Card
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Async Data Loading', description: 'This tour demonstrates loading data before showing a step.', actions: [{ label: 'Next', action: 'next' }], }, { id: 'user-info', type: 'tooltip', title: 'Loading...', description: 'Fetching user data...', target: () => document.querySelector('#user-card'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], effect({ show, update }) { const controller = new AbortController() fetch('https://api.github.com/users/segunadebayo', { signal: controller.signal }) .then((res) => res.json()) .then((data) => { update({ title: `Welcome, ${data.name || data.login}!`, description: `You have ${data.public_repos} public repositories and ${data.followers} followers.`, }) show() }) .catch(() => { update({ title: 'User Profile', description: 'Could not load user data. Please try again.', }) show() }) return () => controller.abort() }, }, { id: 'complete', type: 'dialog', title: 'Tour Complete', description: 'The async step loaded data from the GitHub API before displaying.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const AsyncStep = () => { const tour = useTour({ steps }) return (
                    User Profile Card
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    User Profile Card
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ## Guides ### Step Types The tour machine supports different types of steps, allowing you to create a diverse and interactive tour experience. The available step types are defined in the `StepType` type: - `tooltip`: Displays the step content as a tooltip, typically positioned near the target element. - `dialog`: Shows the step content in a modal dialog centered on screen, useful for starting or ending the tour. This usually don't have a `target` defined. - `floating`: Presents the step content as a floating element, which can be positioned flexibly on the screen. This usually don't have a `target` defined. - `wait`: A special type that waits for a specific condition before proceeding to the next step. ```tsx const steps: TourStepDetails[] = [ { id: 'step-1', type: 'tooltip', placement: 'top-start', target: () => document.querySelector('#target-1'), title: 'Tooltip Step', description: 'This is a tooltip step', }, { id: 'step-2', type: 'dialog', title: 'Dialog Step', description: 'This is a dialog step', }, { id: 'step-3', type: 'floating', placement: 'top-start', title: 'Floating Step', description: 'This is a floating step', }, { id: 'step-4', type: 'wait', title: 'Wait Step', description: 'This is a wait step', effect({ next }) { // do something and go next // you can also return a cleanup }, }, ] ``` ### Actions Every step supports a list of actions that are rendered in the step footer.Use the `actions` property to define each action. ```tsx const steps: TourStepDetails[] = [ { id: 'step-1', type: 'dialog', title: 'Dialog Step', description: 'This is a dialog step', actions: [{ label: 'Show me a tour!', action: 'next' }], }, ] ``` ### Tooltip Placement Use the `placement` property to define the placement of the tooltip. ```tsx {5} const steps: TourStepDetails[] = [ { id: 'step-1', type: 'tooltip', placement: 'top-start', // ... }, ] ``` ### Hide Arrow Set `arrow: false` in the step property to hide the tooltip arrow. This is only useful for tooltip steps. ```tsx {5} const steps: TourStepDetails[] = [ { id: 'step-1', type: 'tooltip', arrow: false, }, ] ``` ### Hide Backdrop Set `backdrop: false` in the step property to hide the backdrop. This applies to all step types except the `wait` step. ```tsx {5} const steps: TourStepDetails[] = [ { id: 'step-1', type: 'dialog', backdrop: false, }, ] ``` ### Effects Step effects are functions that are called before a step is opened. They are useful for adding custom logic to a step. This function provides the following methods: - `next()`: Call this method to move to the next step. - `show()`: Call this method to show the current step. - `update(details: StepDetails)`: Call this method to update the details of the current step (say, after data has been fetched). ```tsx const steps: TourStepDetails[] = [ { id: 'step-1', type: 'tooltip', effect({ next, show, update }) { fetchData().then((res) => { // update the step details update({ title: res.title }) // then show show the step show() }) return () => { // cleanup fetch data } }, }, ] ``` ### Wait Wait steps are useful when you need to wait for a specific condition before proceeding to the next step. Use the step `effect` function to perform an action and then call `next()` to move to the next step. > **Note:** You cannot call `show()` in a wait step. ```tsx const steps: TourStepDetails[] = [ { id: 'step-1', type: 'wait', effect({ next }) { const button = document.querySelector('#button') const listener = () => next() button.addEventListener('click', listener) return () => button.removeEventListener('click', listener) }, }, ] ``` ### Styling Ensure the `box-sizing` is set to `border-box` for the means of measuring the tour target. ```css * { box-sizing: border-box; } ``` Ensure the `body` has a `position` of `relative`. ```css body { position: relative; } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `tour` | `UseTourReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `StepAction` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ActionTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | action-trigger | | `[data-type]` | The type of the item | | `[data-disabled]` | Present when disabled | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Backdrop | | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | close-trigger | | `[data-type]` | The type of the item | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the content | | `[data-step]` | | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested tours | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | description | | `[data-placement]` | The placement of the description | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | positioner | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the positioner | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Positioner | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Spotlight | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | title | | `[data-placement]` | The placement of the title | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `tour` | `UseTourReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `StepAction` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ActionTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | action-trigger | | `[data-type]` | The type of the item | | `[data-disabled]` | Present when disabled | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Backdrop | | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | close-trigger | | `[data-type]` | The type of the item | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the content | | `[data-step]` | | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested tours | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | description | | `[data-placement]` | The placement of the description | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | positioner | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the positioner | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Positioner | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Spotlight | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'h2'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | title | | `[data-placement]` | The placement of the title | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `tour` | `TourApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `StepAction` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ActionTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | action-trigger | | `[data-type]` | The type of the item | | `[data-disabled]` | Present when disabled | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Backdrop | | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | close-trigger | | `[data-type]` | The type of the item | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the content | | `[data-step]` | | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested tours | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | description | | `[data-placement]` | The placement of the description | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | positioner | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the positioner | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Positioner | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Spotlight | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | title | | `[data-placement]` | The placement of the title | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `tour` | `UseTourReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `StepAction` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ActionTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | action-trigger | | `[data-type]` | The type of the item | | `[data-disabled]` | Present when disabled | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Backdrop | | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **CloseTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | close-trigger | | `[data-type]` | The type of the item | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the content | | `[data-step]` | | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested tours | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTourContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Description Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | description | | `[data-placement]` | The placement of the description | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | positioner | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the positioner | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Positioner | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Spotlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Spotlight CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Spotlight | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Title Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | title | | `[data-placement]` | The placement of the title | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the tour is open | | `totalSteps` | `number` | The total number of steps | | `stepIndex` | `number` | The index of the current step | | `step` | `StepDetails` | The current step details | | `hasNextStep` | `boolean` | Whether there is a next step | | `hasPrevStep` | `boolean` | Whether there is a previous step | | `firstStep` | `boolean` | Whether the current step is the first step | | `lastStep` | `boolean` | Whether the current step is the last step | | `addStep` | `(step: StepDetails) => void` | Add a new step to the tour | | `removeStep` | `(id: string) => void` | Remove a step from the tour | | `updateStep` | `(id: string, stepOverrides: Partial) => void` | Update a step in the tour with partial details | | `setSteps` | `(steps: StepDetails[]) => void` | Set the steps of the tour | | `setStep` | `(id: string) => void` | Set the current step of the tour | | `start` | `(id?: string) => void` | Start the tour at a specific step (or the first step if not provided) | | `isValidStep` | `(id: string) => boolean` | Check if a step is valid | | `isCurrentStep` | `(id: string) => boolean` | Check if a step is visible | | `next` | `VoidFunction` | Move to the next step | | `prev` | `VoidFunction` | Move to the previous step | | `getProgressText` | `() => string` | Returns the progress text | | `getProgressPercent` | `() => number` | Returns the progress percent | --- # Tour (SOLID) ## Anatomy ```tsx const tour = useTour({ steps: [...] }) ``` ## Examples **Example: basic** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { MoreHorizontalIcon, SaveIcon, SparklesIcon, UploadIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'welcome', type: 'dialog', title: 'Welcome to the App!', description: "Let's take a quick tour to get you started with the main features.", actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'upload', type: 'tooltip', title: 'Upload Files', description: 'Click here to upload your files to the cloud.', target: () => document.querySelector('#btn-upload'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'save', type: 'tooltip', title: 'Save Changes', description: 'Save your work to keep your progress.', target: () => document.querySelector('#btn-save'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'more', type: 'tooltip', title: 'More Options', description: 'Access additional settings and actions from this menu.', target: () => document.querySelector('#btn-more'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: "You're all set!", description: 'You now know the basics. Enjoy using the app!', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const Basic = () => { const tour = useTour({ steps }) return (
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { MoreHorizontalIcon, SaveIcon, SparklesIcon, UploadIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'welcome', type: 'dialog', title: 'Welcome to the App!', description: "Let's take a quick tour to get you started with the main features.", actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'upload', type: 'tooltip', title: 'Upload Files', description: 'Click here to upload your files to the cloud.', target: () => document.querySelector('#btn-upload'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'save', type: 'tooltip', title: 'Save Changes', description: 'Save your work to keep your progress.', target: () => document.querySelector('#btn-save'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'more', type: 'tooltip', title: 'More Options', description: 'Access additional settings and actions from this menu.', target: () => document.querySelector('#btn-more'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: "You're all set!", description: 'You now know the basics. Enjoy using the app!', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const Basic = () => { const tour = useTour({ steps }) return (
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Step Types Demonstrate all three step types in a single tour: `dialog` for welcome/completion, `tooltip` anchored to elements, and `floating` for fixed-position content. **Example: mixed-types** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'welcome', type: 'dialog', title: 'Welcome!', description: 'This tour demonstrates different step types: dialog, tooltip, and floating.', actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'tooltip-step', type: 'tooltip', title: 'Tooltip Step', description: 'This step appears as a tooltip anchored to a specific element.', target: () => document.querySelector('#target-element'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'floating-step', type: 'floating', placement: 'bottom-end', title: 'Floating Step', description: 'This step floats at a fixed position on the screen, independent of any target.', actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: 'Tour Complete!', description: 'You have seen all the different step types available.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const MixedTypes = () => { const tour = useTour({ steps }) return (
                    Target Element
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'welcome', type: 'dialog', title: 'Welcome!', description: 'This tour demonstrates different step types: dialog, tooltip, and floating.', actions: [{ label: 'Start Tour', action: 'next' }], }, { id: 'tooltip-step', type: 'tooltip', title: 'Tooltip Step', description: 'This step appears as a tooltip anchored to a specific element.', target: () => document.querySelector('#target-element'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'floating-step', type: 'floating', placement: 'bottom-end', title: 'Floating Step', description: 'This step floats at a fixed position on the screen, independent of any target.', actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'complete', type: 'dialog', title: 'Tour Complete!', description: 'You have seen all the different step types available.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const MixedTypes = () => { const tour = useTour({ steps }) return (
                    Target Element
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Target Element
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Progress Display a visual progress indicator at the bottom of the tour content showing how far along the user is. **Example: progress-bar** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'Progress Tracking', description: 'Watch the progress bar at the bottom as you navigate.', target: () => document.querySelector('#progress-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Halfway There', description: 'The progress bar shows how far along you are.', target: () => document.querySelector('#progress-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Almost Done', description: 'One more step to complete the tour.', target: () => document.querySelector('#progress-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-4', type: 'tooltip', title: 'Complete!', description: 'You have completed all the steps.', target: () => document.querySelector('#progress-4'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const ProgressBar = () => { const tour = useTour({ steps }) return (
                    Step 1
                    Step 2
                    Step 3
                    Step 4
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'Progress Tracking', description: 'Watch the progress bar at the bottom as you navigate.', target: () => document.querySelector('#progress-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Halfway There', description: 'The progress bar shows how far along you are.', target: () => document.querySelector('#progress-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Almost Done', description: 'One more step to complete the tour.', target: () => document.querySelector('#progress-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-4', type: 'tooltip', title: 'Complete!', description: 'You have completed all the steps.', target: () => document.querySelector('#progress-4'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const ProgressBar = () => { const tour = useTour({ steps }) return (
                    Step 1
                    Step 2
                    Step 3
                    Step 4
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Step 1
                    Step 2
                    Step 3
                    Step 4
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Skip Allow users to skip the entire tour at any step by adding a skip action. **Example: skip-tour** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'First Feature', description: 'You can skip this tour at any time using the Skip button.', target: () => document.querySelector('#item-1'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-2', type: 'tooltip', title: 'Second Feature', description: 'Continue or skip to end the tour early.', target: () => document.querySelector('#item-2'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Feature', description: 'This is the last step of the tour.', target: () => document.querySelector('#item-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const SkipTour = () => { const tour = useTour({ steps }) return (
                    Item 1
                    Item 2
                    Item 3
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'First Feature', description: 'You can skip this tour at any time using the Skip button.', target: () => document.querySelector('#item-1'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-2', type: 'tooltip', title: 'Second Feature', description: 'Continue or skip to end the tour early.', target: () => document.querySelector('#item-2'), actions: [ { label: 'Skip', action: 'dismiss' }, { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Feature', description: 'This is the last step of the tour.', target: () => document.querySelector('#item-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const SkipTour = () => { const tour = useTour({ steps }) return (
                    Item 1
                    Item 2
                    Item 3
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Item 1
                    Item 2
                    Item 3
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Keyboard Navigation Enable arrow key navigation between tour steps using the `keyboardNavigation` prop. **Example: keyboard-navigation** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { KeyboardIcon, SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'Keyboard Navigation', description: 'Press the right arrow key (→) to go to the next step.', target: () => document.querySelector('#key-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Go Back', description: 'Press the left arrow key (←) to go back.', target: () => document.querySelector('#key-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Close Tour', description: 'Press Escape to close the tour at any time.', target: () => document.querySelector('#key-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const KeyboardNavigation = () => { const tour = useTour({ steps, keyboardNavigation: true }) return (

                    Use arrow keys to navigate, Escape to close

                    Step 1
                    Step 2
                    Step 3
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { KeyboardIcon, SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'Keyboard Navigation', description: 'Press the right arrow key to go to the next step.', target: () => document.querySelector('#key-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Go Back', description: 'Press the left arrow key to go back.', target: () => document.querySelector('#key-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Close Tour', description: 'Press Escape to close the tour at any time.', target: () => document.querySelector('#key-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const KeyboardNavigation = () => { const tour = useTour({ steps, keyboardNavigation: true }) return (

                    Use arrow keys to navigate, Escape to close

                    Step 1
                    Step 2
                    Step 3
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte

                    Use arrow keys to navigate, Escape to close

                    Step 1
                    Step 2
                    Step 3
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Events Listen to tour lifecycle events like `onStepChange` and `onStatusChange` to track user progress. **Example: events** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'First Step', description: 'Watch the event log below as you navigate.', target: () => document.querySelector('#event-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Second Step', description: 'Each step change triggers an event.', target: () => document.querySelector('#event-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Step', description: 'Complete the tour to see the status change.', target: () => document.querySelector('#event-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const Events = () => { const [logs, setLogs] = useState([]) const addLog = (message: string) => { setLogs((prev) => [...prev, message]) } const tour = useTour({ steps, onStepChange(details) { addLog(`Step changed: ${details.stepId}`) }, onStatusChange(details) { addLog(`Status: ${details.status}`) }, }) return (
                    Step 1
                    Step 2
                    Step 3
                    Event Log: {logs.length === 0 ? (
                    Start the tour to see events
                    ) : ( logs.map((log, i) => (
                    {log}
                    )) )}
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For, Show, createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'step-1', type: 'tooltip', title: 'First Step', description: 'Watch the event log below as you navigate.', target: () => document.querySelector('#event-1'), actions: [{ label: 'Next', action: 'next' }], }, { id: 'step-2', type: 'tooltip', title: 'Second Step', description: 'Each step change triggers an event.', target: () => document.querySelector('#event-2'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], }, { id: 'step-3', type: 'tooltip', title: 'Final Step', description: 'Complete the tour to see the status change.', target: () => document.querySelector('#event-3'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Finish', action: 'dismiss' }, ], }, ] export const Events = () => { const [logs, setLogs] = createSignal([]) const addLog = (message: string) => { setLogs((prev) => [...prev, message]) } const tour = useTour({ steps, onStepChange(details) { addLog(`Step changed: ${details.stepId}`) }, onStatusChange(details) { addLog(`Status: ${details.status}`) }, }) return (
                    Step 1
                    Step 2
                    Step 3
                    Event Log: 0} fallback={
                    Start the tour to see events
                    }> {(log) =>
                    {log}
                    }
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Step 1
                    Step 2
                    Step 3
                    Event Log: {#if logs.length === 0}
                    Start the tour to see events
                    {:else} {#each logs as log, i (i)}
                    {log}
                    {/each} {/if}
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Wait for Click Use the `effect` function with `waitForEvent` to wait for user interaction before proceeding to the next step. **Example: wait-for-click** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour, waitForEvent } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Interactive Tutorial', description: 'This tour will guide you through actions. You must complete each step to proceed.', actions: [{ label: 'Begin', action: 'next' }], }, { id: 'click-add', type: 'tooltip', title: 'Click the Add Button', description: 'Click the "Add Item" button to continue.', target: () => document.querySelector('#btn-add'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'click-edit', type: 'tooltip', title: 'Click the Edit Button', description: 'Now click the "Edit" button.', target: () => document.querySelector('#btn-edit'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'click-delete', type: 'tooltip', title: 'Click the Delete Button', description: 'Finally, click the "Delete" button.', target: () => document.querySelector('#btn-delete'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'complete', type: 'dialog', title: 'Well Done!', description: 'You completed all the interactive steps.', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const WaitForClick = () => { const tour = useTour({ steps }) return (
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour, waitForEvent } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Interactive Tutorial', description: 'This tour will guide you through actions. You must complete each step to proceed.', actions: [{ label: 'Begin', action: 'next' }], }, { id: 'click-add', type: 'tooltip', title: 'Click the Add Button', description: 'Click the "Add Item" button to continue.', target: () => document.querySelector('#btn-add'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'click-edit', type: 'tooltip', title: 'Click the Edit Button', description: 'Now click the "Edit" button.', target: () => document.querySelector('#btn-edit'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'click-delete', type: 'tooltip', title: 'Click the Delete Button', description: 'Finally, click the "Delete" button.', target: () => document.querySelector('#btn-delete'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'complete', type: 'dialog', title: 'Well Done!', description: 'You completed all the interactive steps.', actions: [{ label: 'Finish', action: 'dismiss' }], }, ] export const WaitForClick = () => { const tour = useTour({ steps }) return (
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Wait for Input Create form tutorials that wait for users to enter valid input before advancing. **Example: wait-for-input** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour, waitForEvent } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Form Tutorial', description: 'Learn how to fill out the form by following the guided steps.', actions: [{ label: 'Start', action: 'next' }], }, { id: 'enter-name', type: 'tooltip', title: 'Enter Your Name', description: 'Type your name in the input field to continue.', target: () => document.querySelector('#input-name'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'input', { predicate: (el) => el.value.trim().length >= 2, }) promise.then(() => next()) return cancel }, }, { id: 'enter-email', type: 'tooltip', title: 'Enter Your Email', description: 'Now enter a valid email address.', target: () => document.querySelector('#input-email'), effect({ next, target, show }) { show() const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ const [promise, cancel] = waitForEvent(target, 'input', { predicate: (el) => emailRegex.test(el.value), }) promise.then(() => next()) return cancel }, }, { id: 'check-terms', type: 'tooltip', title: 'Accept Terms', description: 'Check the checkbox to accept the terms.', target: () => document.querySelector('#checkbox-terms'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'change', { predicate: (el) => el.checked, }) promise.then(() => next()) return cancel }, }, { id: 'complete', type: 'dialog', title: 'Form Complete!', description: 'You have successfully filled out the form.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const WaitForInput = () => { const tour = useTour({ steps }) return (
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour, waitForEvent } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Form Tutorial', description: 'Learn how to fill out the form by following the guided steps.', actions: [{ label: 'Start', action: 'next' }], }, { id: 'enter-name', type: 'tooltip', title: 'Enter Your Name', description: 'Type your name in the input field to continue.', target: () => document.querySelector('#input-name'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'input', { predicate: (el) => el.value.trim().length >= 2, }) promise.then(() => next()) return cancel }, }, { id: 'enter-email', type: 'tooltip', title: 'Enter Your Email', description: 'Now enter a valid email address.', target: () => document.querySelector('#input-email'), effect({ next, target, show }) { show() const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ const [promise, cancel] = waitForEvent(target, 'input', { predicate: (el) => emailRegex.test(el.value), }) promise.then(() => next()) return cancel }, }, { id: 'check-terms', type: 'tooltip', title: 'Accept Terms', description: 'Check the checkbox to accept the terms.', target: () => document.querySelector('#checkbox-terms'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'change', { predicate: (el) => el.checked, }) promise.then(() => next()) return cancel }, }, { id: 'complete', type: 'dialog', title: 'Form Complete!', description: 'You have successfully filled out the form.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const WaitForInput = () => { const tour = useTour({ steps }) return (
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Wait for Element Wait for dynamically rendered elements to appear in the DOM before showing a step. **Example: wait-for-element** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour, waitForElement, waitForEvent } from '@ark-ui/react/tour' import { PlusIcon, SparklesIcon, XIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Dynamic Elements', description: 'This tour demonstrates waiting for elements that appear dynamically.', actions: [{ label: 'Start', action: 'next' }], }, { id: 'add-item', type: 'tooltip', title: 'Add an Item', description: 'Click the button to add a new item to the list.', target: () => document.querySelector('#btn-add-item'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'new-item', type: 'tooltip', title: 'New Item Added!', description: 'The tour waited for this element to appear before showing this step.', target: () => document.querySelector('[data-item="new"]'), effect({ show }) { const [promise, cancel] = waitForElement(() => document.querySelector('[data-item="new"]'), { timeout: 5000, }) promise.then(() => show()) return () => cancel() }, actions: [{ label: 'Next', action: 'next' }], }, { id: 'complete', type: 'dialog', title: 'Tour Complete', description: 'You learned how to use waitForElement for dynamic content.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const WaitForElement = () => { const tour = useTour({ steps }) const [items, setItems] = useState(['Item 1', 'Item 2']) const addItem = () => { setItems((prev) => [...prev, `Item ${prev.length + 1}`]) } return (
                    {items.map((item, index) => (
                    2 ? 'new' : undefined} > {item}
                    ))}
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour, waitForElement, waitForEvent } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { PlusIcon, SparklesIcon, XIcon } from 'lucide-solid' import { For, createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Dynamic Elements', description: 'This tour demonstrates waiting for elements that appear dynamically.', actions: [{ label: 'Start', action: 'next' }], }, { id: 'add-item', type: 'tooltip', title: 'Add an Item', description: 'Click the button to add a new item to the list.', target: () => document.querySelector('#btn-add-item'), effect({ next, target, show }) { show() const [promise, cancel] = waitForEvent(target, 'click') promise.then(() => next()) return cancel }, }, { id: 'new-item', type: 'tooltip', title: 'New Item Added!', description: 'The tour waited for this element to appear before showing this step.', target: () => document.querySelector('[data-item="new"]'), effect({ show }) { const [promise, cancel] = waitForElement(() => document.querySelector('[data-item="new"]'), { timeout: 5000, }) promise.then(() => show()) return () => cancel() }, actions: [{ label: 'Next', action: 'next' }], }, { id: 'complete', type: 'dialog', title: 'Tour Complete', description: 'You learned how to use waitForElement for dynamic content.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const WaitForElement = () => { const tour = useTour({ steps }) const [items, setItems] = createSignal(['Item 1', 'Item 2']) const addItem = () => { setItems((prev) => [...prev, `Item ${prev.length + 1}`]) } return (
                    {(item, index) => (
                    2 ? 'new' : undefined} > {item}
                    )}
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#each items as item, index (item)}
                    2 ? 'new' : undefined}> {item}
                    {/each}
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ### Async Load data asynchronously and update step content before displaying it using the `effect` function with `show()` and `update()`. **Example: async-step** #### React ```tsx import { Portal } from '@ark-ui/react/portal' import { Tour, useTour } from '@ark-ui/react/tour' import { SparklesIcon, XIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Async Data Loading', description: 'This tour demonstrates loading data before showing a step.', actions: [{ label: 'Next', action: 'next' }], }, { id: 'user-info', type: 'tooltip', title: 'Loading...', description: 'Fetching user data...', target: () => document.querySelector('#user-card'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], effect({ show, update }) { const controller = new AbortController() fetch('https://api.github.com/users/segunadebayo', { signal: controller.signal }) .then((res) => res.json()) .then((data) => { update({ title: `Welcome, ${data.name || data.login}!`, description: `You have ${data.public_repos} public repositories and ${data.followers} followers.`, }) show() }) .catch(() => { update({ title: 'User Profile', description: 'Could not load user data. Please try again.', }) show() }) return () => controller.abort() }, }, { id: 'complete', type: 'dialog', title: 'Tour Complete', description: 'The async step loaded data from the GitHub API before displaying.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const AsyncStep = () => { const tour = useTour({ steps }) return (
                    User Profile Card
                    {(actions) => actions.map((action) => ( )) }
                    ) } ``` #### Solid ```tsx import { Tour, useTour } from '@ark-ui/solid/tour' import { Portal } from 'solid-js/web' import { SparklesIcon, XIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tour.module.css' const steps: Tour.StepDetails[] = [ { id: 'intro', type: 'dialog', title: 'Async Data Loading', description: 'This tour demonstrates loading data before showing a step.', actions: [{ label: 'Next', action: 'next' }], }, { id: 'user-info', type: 'tooltip', title: 'Loading...', description: 'Fetching user data...', target: () => document.querySelector('#user-card'), actions: [ { label: 'Back', action: 'prev' }, { label: 'Next', action: 'next' }, ], effect({ show, update }) { const controller = new AbortController() fetch('https://api.github.com/users/segunadebayo', { signal: controller.signal }) .then((res) => res.json()) .then((data) => { update({ title: `Welcome, ${data.name || data.login}!`, description: `You have ${data.public_repos} public repositories and ${data.followers} followers.`, }) show() }) .catch(() => { update({ title: 'User Profile', description: 'Could not load user data. Please try again.', }) show() }) return () => controller.abort() }, }, { id: 'complete', type: 'dialog', title: 'Tour Complete', description: 'The async step loaded data from the GitHub API before displaying.', actions: [{ label: 'Done', action: 'dismiss' }], }, ] export const AsyncStep = () => { const tour = useTour({ steps }) return (
                    User Profile Card
                    {(actions) => ( {(action) => } )}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    User Profile Card
                    {#snippet children(actions)} {#each actions() as action (action.label)} {/each} {/snippet}
                    ``` ## Guides ### Step Types The tour machine supports different types of steps, allowing you to create a diverse and interactive tour experience. The available step types are defined in the `StepType` type: - `tooltip`: Displays the step content as a tooltip, typically positioned near the target element. - `dialog`: Shows the step content in a modal dialog centered on screen, useful for starting or ending the tour. This usually don't have a `target` defined. - `floating`: Presents the step content as a floating element, which can be positioned flexibly on the screen. This usually don't have a `target` defined. - `wait`: A special type that waits for a specific condition before proceeding to the next step. ```tsx const steps: TourStepDetails[] = [ { id: 'step-1', type: 'tooltip', placement: 'top-start', target: () => document.querySelector('#target-1'), title: 'Tooltip Step', description: 'This is a tooltip step', }, { id: 'step-2', type: 'dialog', title: 'Dialog Step', description: 'This is a dialog step', }, { id: 'step-3', type: 'floating', placement: 'top-start', title: 'Floating Step', description: 'This is a floating step', }, { id: 'step-4', type: 'wait', title: 'Wait Step', description: 'This is a wait step', effect({ next }) { // do something and go next // you can also return a cleanup }, }, ] ``` ### Actions Every step supports a list of actions that are rendered in the step footer.Use the `actions` property to define each action. ```tsx const steps: TourStepDetails[] = [ { id: 'step-1', type: 'dialog', title: 'Dialog Step', description: 'This is a dialog step', actions: [{ label: 'Show me a tour!', action: 'next' }], }, ] ``` ### Tooltip Placement Use the `placement` property to define the placement of the tooltip. ```tsx {5} const steps: TourStepDetails[] = [ { id: 'step-1', type: 'tooltip', placement: 'top-start', // ... }, ] ``` ### Hide Arrow Set `arrow: false` in the step property to hide the tooltip arrow. This is only useful for tooltip steps. ```tsx {5} const steps: TourStepDetails[] = [ { id: 'step-1', type: 'tooltip', arrow: false, }, ] ``` ### Hide Backdrop Set `backdrop: false` in the step property to hide the backdrop. This applies to all step types except the `wait` step. ```tsx {5} const steps: TourStepDetails[] = [ { id: 'step-1', type: 'dialog', backdrop: false, }, ] ``` ### Effects Step effects are functions that are called before a step is opened. They are useful for adding custom logic to a step. This function provides the following methods: - `next()`: Call this method to move to the next step. - `show()`: Call this method to show the current step. - `update(details: StepDetails)`: Call this method to update the details of the current step (say, after data has been fetched). ```tsx const steps: TourStepDetails[] = [ { id: 'step-1', type: 'tooltip', effect({ next, show, update }) { fetchData().then((res) => { // update the step details update({ title: res.title }) // then show show the step show() }) return () => { // cleanup fetch data } }, }, ] ``` ### Wait Wait steps are useful when you need to wait for a specific condition before proceeding to the next step. Use the step `effect` function to perform an action and then call `next()` to move to the next step. > **Note:** You cannot call `show()` in a wait step. ```tsx const steps: TourStepDetails[] = [ { id: 'step-1', type: 'wait', effect({ next }) { const button = document.querySelector('#button') const listener = () => next() button.addEventListener('click', listener) return () => button.removeEventListener('click', listener) }, }, ] ``` ### Styling Ensure the `box-sizing` is set to `border-box` for the means of measuring the tour target. ```css * { box-sizing: border-box; } ``` Ensure the `body` has a `position` of `relative`. ```css body { position: relative; } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `tour` | `UseTourReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `StepAction` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ActionTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | action-trigger | | `[data-type]` | The type of the item | | `[data-disabled]` | Present when disabled | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Backdrop | | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | close-trigger | | `[data-type]` | The type of the item | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the content | | `[data-step]` | | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested tours | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | description | | `[data-placement]` | The placement of the description | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | positioner | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the positioner | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Positioner | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Spotlight | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | title | | `[data-placement]` | The placement of the title | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `tour` | `UseTourReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `StepAction` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ActionTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | action-trigger | | `[data-type]` | The type of the item | | `[data-disabled]` | Present when disabled | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Backdrop | | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | close-trigger | | `[data-type]` | The type of the item | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the content | | `[data-step]` | | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested tours | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | description | | `[data-placement]` | The placement of the description | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | positioner | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the positioner | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Positioner | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Spotlight | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'h2'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | title | | `[data-placement]` | The placement of the title | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `tour` | `TourApi` | Yes | | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `StepAction` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ActionTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | action-trigger | | `[data-type]` | The type of the item | | `[data-disabled]` | Present when disabled | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Backdrop | | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **CloseTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | close-trigger | | `[data-type]` | The type of the item | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the content | | `[data-step]` | | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested tours | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Description Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | description | | `[data-placement]` | The placement of the description | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Positioner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | positioner | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the positioner | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Positioner | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Spotlight CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Spotlight | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Title Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | title | | `[data-placement]` | The placement of the title | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `tour` | `UseTourReturn` | Yes | | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **ActionTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `action` | `StepAction` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ActionTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | action-trigger | | `[data-type]` | The type of the item | | `[data-disabled]` | Present when disabled | **Arrow Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Arrow CSS Variables:** | Variable | Description | |----------|-------------| | `--arrow-size` | The size of the arrow | | `--arrow-size-half` | Half the size of the arrow | | `--arrow-background` | Use this variable to style the arrow background | | `--arrow-offset` | The offset position of the arrow | **ArrowTip Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Backdrop Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Backdrop Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | backdrop | | `[data-state]` | "open" | "closed" | | `[data-type]` | The type of the item | **Backdrop CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Backdrop | | `--layer-index` | The index of the dismissable in the layer stack | **CloseTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **CloseTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | close-trigger | | `[data-type]` | The type of the item | **Content Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Content Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | content | | `[data-state]` | "open" | "closed" | | `[data-nested]` | popover | | `[data-has-nested]` | popover | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the content | | `[data-step]` | | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--layer-index` | The index of the dismissable in the layer stack | | `--nested-layer-count` | The number of nested tours | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTourContext]>` | Yes | | **Control Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Description Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Description Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | description | | `[data-placement]` | The placement of the description | **Positioner Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Positioner Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | positioner | | `[data-type]` | The type of the item | | `[data-placement]` | The placement of the positioner | **Positioner CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Positioner | | `--reference-width` | The width of the reference element | | `--reference-height` | The height of the root | | `--available-width` | The available width in viewport | | `--available-height` | The available height in viewport | | `--x` | The x position for transform | | `--y` | The y position for transform | | `--z-index` | The z-index value | | `--transform-origin` | The transform origin for animations | **ProgressText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Spotlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Spotlight CSS Variables:** | Variable | Description | |----------|-------------| | `--tour-layer` | The tour layer value for the Spotlight | **Title Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Title Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tour | | `[data-part]` | title | | `[data-placement]` | The placement of the title | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `open` | `boolean` | Whether the tour is open | | `totalSteps` | `number` | The total number of steps | | `stepIndex` | `number` | The index of the current step | | `step` | `StepDetails` | The current step details | | `hasNextStep` | `boolean` | Whether there is a next step | | `hasPrevStep` | `boolean` | Whether there is a previous step | | `firstStep` | `boolean` | Whether the current step is the first step | | `lastStep` | `boolean` | Whether the current step is the last step | | `addStep` | `(step: StepDetails) => void` | Add a new step to the tour | | `removeStep` | `(id: string) => void` | Remove a step from the tour | | `updateStep` | `(id: string, stepOverrides: Partial) => void` | Update a step in the tour with partial details | | `setSteps` | `(steps: StepDetails[]) => void` | Set the steps of the tour | | `setStep` | `(id: string) => void` | Set the current step of the tour | | `start` | `(id?: string) => void` | Start the tour at a specific step (or the first step if not provided) | | `isValidStep` | `(id: string) => boolean` | Check if a step is valid | | `isCurrentStep` | `(id: string) => boolean` | Check if a step is visible | | `next` | `VoidFunction` | Move to the next step | | `prev` | `VoidFunction` | Move to the previous step | | `getProgressText` | `() => string` | Returns the progress text | | `getProgressPercent` | `() => number` | Returns the progress percent | --- # Tree View (REACT) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import styles from 'styles/tree-view.module.css' export const Basic = () => { return ( Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/tree-view.module.css' export const Basic = () => { return ( Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => props.node.children ? ( {nodeState().expanded ? : } {props.node.name} {(child, index) => } ) : ( {props.node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Controlled Expanded Pass the `expandedValue` and `onExpandedChange` props to the `TreeView.Root` component to control the expanded state of the tree view. **Example: controlled-expanded** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' export const ControlledExpanded = () => { const [expandedValue, setExpandedValue] = useState(['node_modules']) return ( setExpandedValue(expandedValue)} > Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For, createSignal } from 'solid-js' import styles from 'styles/tree-view.module.css' export const ControlledExpanded = () => { const [expandedValue, setExpandedValue] = createSignal(['node_modules']) return ( setExpandedValue(expandedValue)} > Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => props.node.children ? ( {nodeState().expanded ? : } {props.node.name} {(child, index) => } ) : ( {props.node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Controlled Selection Pass the `selectedValue` and `onSelectionChange` props to the `TreeView.Root` component to control the selected state of the tree view. **Example: controlled-selected** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' export const ControlledSelected = () => { const [selectedValue, setSelectedValue] = useState(['package.json']) return ( setSelectedValue(selectedValue)} > Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For, createSignal } from 'solid-js' import styles from 'styles/tree-view.module.css' export const ControlledSelected = () => { const [selectedValue, setSelectedValue] = createSignal(['package.json']) return ( setSelectedValue(selectedValue)} > Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => props.node.children ? ( {nodeState().expanded ? : } {props.node.name} {(child, index) => } ) : ( {props.node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Selected: {JSON.stringify(selectedValue)}
                    Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Root Provider An alternative way to control the tree view is to use the `RootProvider` component and the `useTreeView` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { TreeView, createTreeCollection, useTreeView } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import styles from 'styles/tree-view.module.css' export const RootProvider = () => { const treeView = useTreeView({ collection }) return (
                    selected: {JSON.stringify(treeView.selectedValue)} Tree {collection.rootNode.children?.map((node, index) => ( ))}
                    ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection, useTreeView } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/tree-view.module.css' export const RootProvider = () => { const treeView = useTreeView({ collection }) return ( Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => props.node.children ? ( {nodeState().expanded ? : } {props.node.name} {(child, index) => } ) : ( {props.node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Root Provider Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Lazy Loading Lazy loading is a feature that allows the tree view to load children of a node on demand (or async). This helps to improve the initial load time and memory usage. To use this, you need to provide the following: - `loadChildren` — A function that is used to load the children of a node. - `onLoadChildrenComplete` — A callback that is called when the children of a node are loaded. Used to update the tree collection. - `childrenCount` — A number that indicates the number of children of a branch node. **Example: async-loading** #### React ```tsx import { TreeView, createTreeCollection, useTreeViewNodeContext } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon, LoaderIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' // mock api result const response: Record = { node_modules: [ { id: 'zag-js', name: 'zag-js' }, { id: 'pandacss', name: 'panda' }, { id: '@types', name: '@types', childrenCount: 2 }, ], 'node_modules/@types': [ { id: 'react', name: 'react' }, { id: 'react-dom', name: 'react-dom' }, ], src: [ { id: 'app.tsx', name: 'app.tsx' }, { id: 'index.ts', name: 'index.ts' }, ], } // function to load children of a node function loadChildren(details: TreeView.LoadChildrenDetails): Promise { const value = details.valuePath.join('/') return new Promise((resolve) => { setTimeout(() => { resolve(response[value] ?? []) }, 500) }) } export const AsyncLoading = () => { const [collection, setCollection] = useState(initialCollection) return ( setCollection(e.collection)} > Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } function TreeBranchIcon() { const nodeState = useTreeViewNodeContext() if (nodeState.loading) return return nodeState.expanded ? : } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children || node.childrenCount ? ( {node.name} {node.children?.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] childrenCount?: number } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', childrenCount: 3 }, { id: 'src', name: 'src', childrenCount: 2 }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { SquareCheckBigIcon, ChevronRightIcon, FileIcon, FolderIcon, LoaderCircleIcon } from 'lucide-solid' import { For, createSignal } from 'solid-js' import { useTreeViewNodeContext } from '../use-tree-view-node-context' // mock api result const response: Record = { node_modules: [ { id: 'zag-js', name: 'zag-js' }, { id: 'pandacss', name: 'panda' }, { id: '@types', name: '@types', childrenCount: 2 }, ], 'node_modules/@types': [ { id: 'react', name: 'react' }, { id: 'react-dom', name: 'react-dom' }, ], src: [ { id: 'app.tsx', name: 'app.tsx' }, { id: 'index.ts', name: 'index.ts' }, ], } // function to load children of a node function loadChildren(details: TreeView.LoadChildrenDetails): Promise { const value = details.valuePath.join('/') return new Promise((resolve) => { setTimeout(() => { resolve(response[value] ?? []) }, 1200) }) } export const AsyncLoading = () => { const [collection, setCollection] = createSignal(initialCollection) return ( setCollection(e.collection)} > Tree {(node, index) => } ) } function TreeNodeIndicator() { const nodeState = useTreeViewNodeContext() return nodeState().loading ? : } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children || node.childrenCount ? ( {node.name} {(child, index) => } ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] childrenCount?: number } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', childrenCount: 3 }, { id: 'src', name: 'src', childrenCount: 2 }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte (collection = e.collection)} > Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children || node.childrenCount} {#if nodeState().loading} {:else} {/if} {node.name} {#each node.children ?? [] as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Lazy Mount Lazy mounting is a feature that allows the content of a tree view to be rendered only when it is expanded. This is useful for performance optimization, especially when tree content is large or complex. To enable lazy mounting, use the `lazyMount` prop on the `TreeView.Root` component. In addition, the `unmountOnExit` prop can be used in conjunction with `lazyMount` to unmount the tree view content when branches are collapsed, freeing up resources. The next time a branch is expanded, its content will be re-rendered. **Example: lazy-mount** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useTreeViewNodeContext } from '../use-tree-view-node-context' import styles from 'styles/tree-view.module.css' export const LazyMount = () => { return ( Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeBranchIcon = () => { const { expanded } = useTreeViewNodeContext() return expanded ? : } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children ? ( {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { SquareCheckBigIcon, ChevronRightIcon, FileIcon, FolderIcon } from 'lucide-solid' import { For, Show } from 'solid-js' interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) export const LazyMount = () => { return ( Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.name} } > {node.name} {(child, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Filtering Filtering is useful when you have a large tree and you want to filter the nodes to only show the ones that match the search query. Here's an example that composes the `filter` method from the `TreeCollection` and `useFilter` hook to filter the nodes. **Example: filtering** #### React ```tsx import { useFilter } from '@ark-ui/react/locale' import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' import fieldStyles from 'styles/field.module.css' export const Filtering = () => { const { contains } = useFilter({ sensitivity: 'base' }) const [collection, setCollection] = useState(initialCollection) const filter = (value: string) => { const filtered = value.length > 0 ? initialCollection.filter((node) => contains(node.name, value)) : initialCollection setCollection(filtered) } return (
                    filter(e.target.value)} /> {collection.rootNode.children?.map((node, index) => ( ))}
                    ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props const tree = useTreeViewContext() const nodeState = tree.getNodeState(props) return ( {nodeState.isBranch ? ( {nodeState.expanded ? : } {node.name} {node.children?.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { useFilter } from '@ark-ui/solid/locale' import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { SquareCheckBigIcon, ChevronRightIcon, FileIcon, FolderIcon } from 'lucide-solid' import { For, Show, createSignal } from 'solid-js' export const Filtering = () => { const filterFn = useFilter({ sensitivity: 'base' }) const [collection, setCollection] = createSignal(initialCollection) const filter = (value: string) => { const filtered = value.length > 0 ? initialCollection.filter((node) => filterFn().contains(node.name, value)) : initialCollection setCollection(filtered) } return (
                    filter(e.currentTarget.value)} /> {(node, index) => }
                    ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.name} } > {node.name} {(child, index) => } ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    filter(e.currentTarget.value)} /> {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each}
                    {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Links Tree items can be rendered as links to another page or website. This could be useful for documentation sites. Here's an example that modifies the tree collection to represent an hierarchical link structure. It uses the `asChild` prop to render the tree items as links, passing the `href` prop to a `` element. **Example: links** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, ExternalLinkIcon, FileIcon } from 'lucide-react' import styles from 'styles/tree-view.module.css' export const Links = () => { return ( Docs {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children ? ( {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} {node.href?.startsWith('http') && } )} ) } interface Node { id: string name: string href?: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'docs', name: 'Documentation', children: [ { id: 'docs/getting-started', name: 'Getting Started', href: '/docs/getting-started' }, { id: 'docs/installation', name: 'Installation', href: '/docs/installation' }, { id: 'docs/components', name: 'Components', children: [ { id: 'docs/components/accordion', name: 'Accordion', href: '/docs/components/accordion' }, { id: 'docs/components/dialog', name: 'Dialog', href: '/docs/components/dialog' }, { id: 'docs/components/menu', name: 'Menu', href: '/docs/components/menu' }, ], }, ], }, { id: 'examples', name: 'Examples', children: [ { id: 'examples/react', name: 'React Examples', href: '/examples/react' }, { id: 'examples/vue', name: 'Vue Examples', href: '/examples/vue' }, { id: 'examples/solid', name: 'Solid Examples', href: '/examples/solid' }, ], }, { id: 'external', name: 'External Links', children: [ { id: 'external/github', name: 'GitHub Repository', href: 'https://github.com/chakra-ui/zag' }, { id: 'external/npm', name: 'NPM Package', href: 'https://www.npmjs.com/package/@zag-js/core' }, { id: 'external/docs', name: 'Official Docs', href: 'https://zagjs.com' }, ], }, { id: 'readme.md', name: 'README.md', href: '/readme' }, { id: 'license', name: 'LICENSE', href: '/license' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, ExternalLinkIcon, FileIcon } from 'lucide-solid' import { For, Show } from 'solid-js' export const Links = () => { return ( Docs {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( }> {node.name} } > {node.name} {(child, index) => } ) } interface Node { id: string name: string href?: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'docs', name: 'Documentation', children: [ { id: 'docs/getting-started', name: 'Getting Started', href: '/docs/getting-started' }, { id: 'docs/installation', name: 'Installation', href: '/docs/installation' }, { id: 'docs/components', name: 'Components', children: [ { id: 'docs/components/accordion', name: 'Accordion', href: '/docs/components/accordion' }, { id: 'docs/components/dialog', name: 'Dialog', href: '/docs/components/dialog' }, { id: 'docs/components/menu', name: 'Menu', href: '/docs/components/menu' }, ], }, ], }, { id: 'examples', name: 'Examples', children: [ { id: 'examples/react', name: 'React Examples', href: '/examples/react' }, { id: 'examples/vue', name: 'Vue Examples', href: '/examples/vue' }, { id: 'examples/solid', name: 'Solid Examples', href: '/examples/solid' }, ], }, { id: 'external', name: 'External Links', children: [ { id: 'external/github', name: 'GitHub Repository', href: 'https://github.com/chakra-ui/zag' }, { id: 'external/npm', name: 'NPM Package', href: 'https://www.npmjs.com/package/@zag-js/core' }, { id: 'external/docs', name: 'Official Docs', href: 'https://zagjs.com' }, ], }, { id: 'readme.md', name: 'README.md', href: '/readme' }, { id: 'license', name: 'LICENSE', href: '/license' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Docs {#each collection.rootNode.children ?? [] as node, index (node.id)} {/each} ``` ### Virtualized For large tree views with thousands of nodes, virtualization can significantly improve performance by only rendering visible nodes. Key implementation details: - Use `useTreeView` hook with `TreeView.RootProvider` for programmatic control - Pass `scrollToIndexFn` to enable keyboard navigation within the virtualized list - Use `getVisibleNodes()` to get the flattened list of currently visible nodes **Example: virtualized** #### React ```tsx import { TreeView, createTreeCollection, useTreeView } from '@ark-ui/react/tree-view' import { useVirtualizer, type Virtualizer } from '@tanstack/react-virtual' import { ChevronRightIcon, FileIcon, FolderIcon } from 'lucide-react' import { useRef } from 'react' import { flushSync } from 'react-dom' import button from 'styles/button.module.css' import styles from 'styles/tree-view.module.css' interface Node { id: string name: string children?: Node[] } function generateLargeTree(): Node { const folders: Node[] = [] for (let i = 0; i < 50; i++) { const children: Node[] = [] for (let j = 0; j < 20; j++) { children.push({ id: `folder-${i}/file-${i}-${j}.ts`, name: `file-${i}-${j}.ts` }) } folders.push({ id: `folder-${i}`, name: `folder-${i}`, children }) } return { id: 'ROOT', name: '', children: folders, } } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: generateLargeTree(), }) const ROW_HEIGHT = 32 export const Virtualized = () => { const treeRef = useRef(null) const virtualizerRef = useRef | null>(null) const tree = useTreeView({ collection, scrollToIndexFn(details) { flushSync(() => { virtualizerRef.current?.scrollToIndex(details.index, { align: 'auto' }) }) }, }) const visibleNodes = tree.getVisibleNodes() const virtualizer = useVirtualizer({ count: visibleNodes.length, getScrollElement: () => treeRef.current, estimateSize: () => ROW_HEIGHT, overscan: 10, }) virtualizerRef.current = virtualizer return ( Virtualized Tree ({visibleNodes.length} visible nodes)
                    {virtualizer.getVirtualItems().map((virtualItem) => { const { node, indexPath } = visibleNodes[virtualItem.index] const nodeState = tree.getNodeState({ node, indexPath }) return (
                    { if (e.button !== 0) return tree.focus(node.id) }} style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: `${virtualItem.size}px`, transform: `translateY(${virtualItem.start}px)`, }} > {nodeState.isBranch ? ( {node.name} ) : ( {node.name} )}
                    ) })}
                    ) } ``` #### Solid ```tsx import { TreeView, createTreeCollection, useTreeView } from '@ark-ui/solid/tree-view' import { createVirtualizer, type Virtualizer } from '@tanstack/solid-virtual' import { ChevronRightIcon, FileIcon, FolderIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tree-view.module.css' interface Node { id: string name: string children?: Node[] } function generateLargeTree(): Node { const folders: Node[] = [] for (let i = 0; i < 50; i++) { const children: Node[] = [] for (let j = 0; j < 20; j++) { children.push({ id: `folder-${i}/file-${i}-${j}.ts`, name: `file-${i}-${j}.ts` }) } folders.push({ id: `folder-${i}`, name: `folder-${i}`, children }) } return { id: 'ROOT', name: '', children: folders, } } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: generateLargeTree(), }) const ROW_HEIGHT = 32 export const Virtualized = () => { let treeRef: HTMLDivElement | undefined let virtualizerRef: Virtualizer | undefined const tree = useTreeView({ collection, scrollToIndexFn(details) { virtualizerRef?.scrollToIndex(details.index, { align: 'auto' }) }, }) const visibleNodes = () => tree().getVisibleNodes() const virtualizer = createVirtualizer({ get count() { return visibleNodes().length }, getScrollElement: () => treeRef ?? null, estimateSize: () => ROW_HEIGHT, overscan: 10, }) virtualizerRef = virtualizer return ( Virtualized Tree ({visibleNodes().length} visible nodes)
                    {(virtualItem) => { const visibleNode = () => visibleNodes()[virtualItem.index] const nodeState = () => tree().getNodeState({ node: visibleNode().node, indexPath: visibleNode().indexPath }) return (
                    { if (e.button !== 0) return tree().focus(visibleNode().node.id) }} style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: `${virtualItem.size}px`, transform: `translateY(${virtualItem.start}px)`, }} > {nodeState().isBranch ? ( {visibleNode().node.name} ) : ( {visibleNode().node.name} )}
                    ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Virtualized Tree ({visibleNodes.length} visible nodes)
                    {#each $virtualizer.getVirtualItems() as virtualItem (visibleNodes[virtualItem.index].node.id)} {@const visibleNode = visibleNodes[virtualItem.index]} {@const nodeState = tree().getNodeState({ node: visibleNode.node, indexPath: visibleNode.indexPath })}
                    { if (e.button !== 0) return tree().focus(visibleNode.node.id) }} style="position: absolute; top: 0; left: 0; width: 100%; height: {virtualItem.size}px; transform: translateY({virtualItem.start}px);" > {#if nodeState.isBranch} {visibleNode.node.name} {:else} {visibleNode.node.name} {/if}
                    {/each}
                    ``` ### Checkbox Tree Use the `defaultCheckedValue` prop to enable checkbox selection mode. This allows users to select multiple nodes with checkboxes, including parent-child selection relationships. **Example: checkbox-tree** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { CheckIcon, ChevronRightIcon, MinusIcon } from 'lucide-react' import styles from 'styles/tree-view.module.css' export const CheckboxTree = () => { return ( Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNodeCheckbox = (props: TreeView.NodeCheckboxProps) => { return ( }> ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children ? ( {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { SquareCheckBigIcon, ChevronRightIcon, SquareMinusIcon, SquareIcon } from 'lucide-solid' import { For } from 'solid-js' export const CheckboxTree = () => { return ( Tree {(node, index) => } ) } const TreeNodeCheckbox = () => { return ( } fallback={}> ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children ? ( {node.name} {(child, index) => } ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet treeNodeCheckbox()} {#snippet indeterminate()} {/snippet} {#snippet fallback()} {/snippet} {/snippet} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#if node.children} {@render treeNodeCheckbox()} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {@render treeNodeCheckbox()} {node.name} {/if} {/snippet} ``` ### Expand and Collapse All Use the `expand()` and `collapse()` methods from the tree view context to programmatically expand or collapse all branches. **Example: expand-collapse-all** #### React ```tsx import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useMemo } from 'react' import button from 'styles/button.module.css' import styles from 'styles/tree-view.module.css' const ExpandCollapseButtons = () => { const tree = useTreeViewContext() const branchValues = useMemo(() => tree.collection.getBranchValues(), [tree.collection]) const isAllExpanded = useMemo( () => branchValues.every((value) => tree.expandedValue.includes(value)), [tree.expandedValue, branchValues], ) return (
                    {isAllExpanded ? ( ) : ( )}
                    ) } export const ExpandCollapseAll = () => { return ( {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For, Show, createMemo } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tree-view.module.css' const ExpandCollapseButtons = () => { const tree = useTreeViewContext() const branchValues = createMemo(() => tree().collection.getBranchValues()) const isAllExpanded = createMemo(() => branchValues().every((value) => tree().expandedValue.includes(value))) return (
                    tree().expand()}> Expand all } >
                    ) } export const ExpandCollapseAll = () => { return ( {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => ( {props.node.name} } > }> {props.node.name} {(child, index) => } )} ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tree)}
                    {#if branchValues.every((value) => tree().expandedValue.includes(value))} {:else} {/if}
                    {/snippet}
                    {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each}
                    {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Mutation Use the collection's `remove()` and `replace()` methods to dynamically add and remove nodes from the tree. This is useful for building file explorer interfaces where users can create and delete files. **Example: mutation** #### React ```tsx import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/react/tree-view' import { ChevronRightIcon, PlusIcon, TrashIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' export const Mutation = () => { const [collection, setCollection] = useState(initialCollection) const removeNode = (props: TreeNodeProps) => { setCollection(collection.remove([props.indexPath])) } const addNode = (props: TreeNodeProps) => { const { node, indexPath } = props if (!collection.isBranchNode(node)) return const children = [{ id: `untitled-${Date.now()}`, name: 'untitled.tsx' }, ...(node.children || [])] setCollection(collection.replace(indexPath, { ...node, children })) } return ( {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNodeActions = (props: TreeNodeProps) => { const { onRemove, onAdd, node } = props const tree = useTreeViewContext() const isBranch = tree.collection.isBranchNode(node) return (
                    {isBranch && ( )}
                    ) } interface TreeNodeProps extends TreeView.NodeProviderProps { onRemove?: (props: TreeView.NodeProviderProps) => void onAdd?: (props: TreeView.NodeProviderProps) => void } const TreeNode = (props: TreeNodeProps) => { const { node, indexPath } = props const tree = useTreeViewContext() const nodeState = tree.getNodeState(props) return ( {nodeState.isBranch ? ( {node.name} {node.children?.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, PlusIcon, TrashIcon } from 'lucide-solid' import { For, Show, createSignal } from 'solid-js' import styles from 'styles/tree-view.module.css' export const Mutation = () => { const [collection, setCollection] = createSignal(initialCollection) const removeNode = (props: TreeNodeProps) => { setCollection((prev) => prev.remove([props.indexPath])) } const addNode = (props: TreeNodeProps) => { const { node, indexPath } = props const col = collection() if (!col.isBranchNode(node)) return const children = [{ id: `untitled-${Date.now()}`, name: 'untitled.tsx' }, ...(node.children || [])] setCollection(col.replace(indexPath, { ...node, children })) } return ( {(node, index) => } ) } const TreeNodeActions = (props: TreeNodeProps) => { const tree = useTreeViewContext() const isBranch = () => tree().collection.isBranchNode(props.node) return (
                    ) } interface TreeNodeProps extends TreeView.NodeProviderProps { onRemove?: (props: TreeView.NodeProviderProps) => void onAdd?: (props: TreeView.NodeProviderProps) => void } const TreeNode = (props: TreeNodeProps) => { const tree = useTreeViewContext() const nodeState = () => tree().getNodeState(props) return ( {props.node.name} } > {props.node.name} {(child, index) => ( )} ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tree)} {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index], tree)} {/each} {/snippet} {#snippet renderNode(node: TreeNode, indexPath: number[], tree: any)} {#if node.children} {node.name}
                    {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index], tree)} {/each}
                    {:else} {node.name}
                    {/if}
                    {/snippet} ``` ### Rename Node Enable inline renaming of nodes using the `canRename` prop and `onRenameComplete` callback. Press F2 to activate rename mode on the focused node. **Example: rename-node** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' export const RenameNode = () => { const [collection, setCollection] = useState(initialCollection) return ( true} onRenameComplete={(details) => { setCollection((prev) => { const node = prev.at(details.indexPath) if (!node) return prev return prev.replace(details.indexPath, { ...node, name: details.label }) }) }} > Tree (Press F2 to rename) {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.renaming ? ( ) : ( {nodeState.expanded ? : } {node.name} )} {node.children.map((child, index) => ( ))} ) : ( {nodeState.renaming ? ( ) : ( {node.name} )} ) } ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For, Show, createSignal } from 'solid-js' import styles from 'styles/tree-view.module.css' export const RenameNode = () => { const [collection, setCollection] = createSignal(initialCollection) return ( true} onRenameComplete={(details) => { setCollection((prev) => { const node = prev.at(details.indexPath) if (!node) return prev return prev.replace(details.indexPath, { ...node, name: details.label }) }) }} > Tree (Press F2 to rename) {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => ( {props.node.name}} > } > }> {props.node.name} } > {(child, index) => } )} ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte true} onRenameComplete={handleRenameComplete}> Tree (Press F2 to rename) {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().renaming} {:else} {#if nodeState().expanded} {:else} {/if} {node.name} {/if} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {#if nodeState().renaming} {:else} {node.name} {/if} {/if} {/snippet} {/snippet} ``` ## Guides ### Type Safety The `TreeView.RootComponent` type enables you to create typed wrapper components that maintain full type safety for tree nodes. ```tsx import { TreeView as ArkTreeView } from '@ark-ui/react/tree-view' const TreeView: ArkTreeView.RootComponent = (props) => { return {/* ... */} } ``` Use the wrapper with full type inference on `onSelectionChange` and other callbacks: ```tsx const App = () => { const collection = createTreeCollection({ initialItems: [ { id: '1', label: 'React', children: [] }, { id: '2', label: 'Vue', children: [] }, ], }) return ( { // e.items is typed as Array<{ id: string, label: string, children: [] }> console.log(e.items) }} > {/* ... */} ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `TreeCollection` | Yes | The collection of tree nodes | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: T, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails) => void` | No | Called when the selection changes | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'multiple' | 'single'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **BranchContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-content | | `[data-state]` | "open" | "closed" | | `[data-depth]` | The depth of the item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | **BranchControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-control | | `[data-path]` | The path of the item | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-renaming]` | | | `[data-value]` | The value of the item | | `[data-depth]` | The depth of the item | | `[data-loading]` | Present when loading | **BranchIndentGuide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndentGuide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indent-guide | | `[data-depth]` | The depth of the item | **BranchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-loading]` | Present when loading | **Branch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Branch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch | | `[data-depth]` | The depth of the item | | `[data-branch]` | | | `[data-value]` | The value of the item | | `[data-path]` | The path of the item | | `[data-selected]` | Present when selected | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-loading]` | Present when loading | **Branch CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Branch | **BranchText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-text | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-loading]` | Present when loading | **BranchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-trigger | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-value]` | The value of the item | | `[data-loading]` | Present when loading | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | | `[data-focus]` | Present when focused | | `[data-selected]` | Present when selected | | `[data-disabled]` | Present when disabled | | `[data-renaming]` | | | `[data-depth]` | The depth of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckboxIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | | | `indeterminate` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | | **NodeCheckbox Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckbox Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | node-checkbox | | `[data-state]` | "checked" | "unchecked" | "indeterminate" | | `[data-disabled]` | Present when disabled | **NodeProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `indexPath` | `number[]` | Yes | The index path of the tree node | | `node` | `NonNullable` | No | The tree node | **NodeRenameInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Tree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `TreeCollection` | Yes | The collection of tree nodes | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: any, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails) => void` | No | Called when the selection changes | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'multiple' | 'single'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **BranchContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-content | | `[data-state]` | "open" | "closed" | | `[data-depth]` | The depth of the item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | **BranchControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-control | | `[data-path]` | The path of the item | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-renaming]` | | | `[data-value]` | The value of the item | | `[data-depth]` | The depth of the item | | `[data-loading]` | Present when loading | **BranchIndentGuide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndentGuide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indent-guide | | `[data-depth]` | The depth of the item | **BranchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-loading]` | Present when loading | **Branch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Branch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch | | `[data-depth]` | The depth of the item | | `[data-branch]` | | | `[data-value]` | The value of the item | | `[data-path]` | The path of the item | | `[data-selected]` | Present when selected | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-loading]` | Present when loading | **Branch CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Branch | **BranchText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-text | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-loading]` | Present when loading | **BranchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-trigger | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-value]` | The value of the item | | `[data-loading]` | Present when loading | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | | `[data-focus]` | Present when focused | | `[data-selected]` | Present when selected | | `[data-disabled]` | Present when disabled | | `[data-renaming]` | | | `[data-depth]` | The depth of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'h3'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckboxIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `number | boolean | Node | (string & {}) | ArrayElement` | No | | | `indeterminate` | `number | boolean | Node | (string & {}) | ArrayElement` | No | | **NodeCheckbox Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckbox Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | node-checkbox | | `[data-state]` | "checked" | "unchecked" | "indeterminate" | | `[data-disabled]` | Present when disabled | **NodeProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `indexPath` | `number[]` | Yes | The index path of the tree node | | `node` | `NonNullable` | No | The tree node | **NodeRenameInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Tree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `TreeCollection` | Yes | The collection of tree nodes | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: T, indexPath: number[]) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node values | | `defaultCheckedValue` | `string[]` | No | The initial checked node values when rendered. Use when you don't need to control the checked node values. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node values when rendered. Use when you don't need to control the expanded node values. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node values when rendered. Use when you don't need to control the selected node values. | | `expandedValue` | `string[]` | No | The controlled expanded node values | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The id of the focused node | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node(value: string): string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | A function that loads the children of a node. | | `selectedValue` | `string[]` | No | The controlled selected node values | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **BranchContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-content | | `[data-state]` | "open" | "closed" | | `[data-depth]` | The depth of the item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | **BranchControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-control | | `[data-path]` | The path of the item | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-renaming]` | | | `[data-value]` | The value of the item | | `[data-depth]` | The depth of the item | | `[data-loading]` | Present when loading | **BranchIndentGuide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndentGuide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indent-guide | | `[data-depth]` | The depth of the item | **BranchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-loading]` | Present when loading | **Branch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Branch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch | | `[data-depth]` | The depth of the item | | `[data-branch]` | | | `[data-value]` | The value of the item | | `[data-path]` | The path of the item | | `[data-selected]` | Present when selected | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-loading]` | Present when loading | **Branch CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Branch | **BranchText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-text | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-loading]` | Present when loading | **BranchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-trigger | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-value]` | The value of the item | | `[data-loading]` | Present when loading | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | | `[data-focus]` | Present when focused | | `[data-selected]` | Present when selected | | `[data-disabled]` | Present when disabled | | `[data-renaming]` | | | `[data-depth]` | The depth of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckboxIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `{}` | No | | | `indeterminate` | `{}` | No | | **NodeCheckbox Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckbox Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | node-checkbox | | `[data-state]` | "checked" | "unchecked" | "indeterminate" | | `[data-disabled]` | Present when disabled | **NodeProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `indexPath` | `number[]` | Yes | The index path of the tree node | | `node` | `NonNullable` | No | The tree node | **NodeRenameInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TreeViewApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Tree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: T, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `collection` | `TreeCollection` | No | The tree collection data | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails) => void` | No | Called when the selection changes | | `ref` | `Element` | No | | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'multiple' | 'single'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **BranchContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'ul'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-content | | `[data-state]` | "open" | "closed" | | `[data-depth]` | The depth of the item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | **BranchControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-control | | `[data-path]` | The path of the item | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-renaming]` | | | `[data-value]` | The value of the item | | `[data-depth]` | The depth of the item | | `[data-loading]` | Present when loading | **BranchIndentGuide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchIndentGuide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indent-guide | | `[data-depth]` | The depth of the item | **BranchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-loading]` | Present when loading | **Branch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'li'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Branch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch | | `[data-depth]` | The depth of the item | | `[data-branch]` | | | `[data-value]` | The value of the item | | `[data-path]` | The path of the item | | `[data-selected]` | Present when selected | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-loading]` | Present when loading | **Branch CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Branch | **BranchText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-text | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-loading]` | Present when loading | **BranchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-trigger | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-value]` | The value of the item | | `[data-loading]` | Present when loading | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTreeViewContext]>` | Yes | | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'li'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | | `[data-focus]` | Present when focused | | `[data-selected]` | Present when selected | | `[data-disabled]` | Present when disabled | | `[data-renaming]` | | | `[data-depth]` | The depth of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h3'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NodeCheckboxIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `Snippet<[]>` | No | | | `indeterminate` | `Snippet<[]>` | No | | **NodeCheckbox Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NodeCheckbox Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | node-checkbox | | `[data-state]` | "checked" | "unchecked" | "indeterminate" | | `[data-disabled]` | Present when disabled | **NodeContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTreeViewNodeContext]>` | Yes | | **NodeProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `indexPath` | `number[]` | Yes | | | `node` | `NonNullable` | No | | **NodeRenameInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Tree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'ul'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `collection` | `TreeCollection` | The tree collection data | | `expandedValue` | `string[]` | The value of the expanded nodes. | | `setExpandedValue` | `(value: string[]) => void` | Sets the expanded value | | `selectedValue` | `string[]` | The value of the selected nodes. | | `setSelectedValue` | `(value: string[]) => void` | Sets the selected value | | `checkedValue` | `string[]` | The value of the checked nodes | | `toggleChecked` | `(value: string, isBranch: boolean) => void` | Toggles the checked value of a node | | `setChecked` | `(value: string[]) => void` | Sets the checked value of a node | | `clearChecked` | `VoidFunction` | Clears the checked value of a node | | `getCheckedMap` | `() => CheckedValueMap` | Returns the checked details of branch and leaf nodes | | `getVisibleNodes` | `() => V[]` | Returns the visible nodes as a flat array of nodes and their index path | | `expand` | `(value?: string[]) => void` | Function to expand nodes. If no value is provided, all nodes will be expanded | | `collapse` | `(value?: string[]) => void` | Function to collapse nodes If no value is provided, all nodes will be collapsed | | `select` | `(value?: string[]) => void` | Function to select nodes If no value is provided, all nodes will be selected | | `deselect` | `(value?: string[]) => void` | Function to deselect nodes If no value is provided, all nodes will be deselected | | `focus` | `(value: string) => void` | Function to focus a node by value | | `selectParent` | `(value: string) => void` | Function to select the parent node of the focused node | | `expandParent` | `(value: string) => void` | Function to expand the parent node of the focused node | | `startRenaming` | `(value: string) => void` | Function to start renaming a node by value | | `submitRenaming` | `(value: string, label: string) => void` | Function to submit the rename and update the node label | | `cancelRenaming` | `() => void` | Function to cancel renaming without changes | ## Accessibility Complies with the [Tree View WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/). ### Keyboard Support **`Tab`** Description: Moves focus to the tree view, placing the first tree view item in focus. **`Enter + Space`** Description: Selects the item or branch node **`ArrowDown`** Description: Moves focus to the next node **`ArrowUp`** Description: Moves focus to the previous node **`ArrowRight`** Description: When focus is on a closed branch node, opens the branch.
                    When focus is on an open branch node, moves focus to the first item node. **`ArrowLeft`** Description: When focus is on an open branch node, closes the node.
                    When focus is on an item or branch node, moves focus to its parent branch node. **`Home`** Description: Moves focus to first node without opening or closing a node. **`End`** Description: Moves focus to the last node that can be focused without expanding any nodes that are closed. **`a-z + A-Z`** Description: Focus moves to the next node with a name that starts with the typed character. The search logic ignores nodes that are descendants of closed branch. **`*`** Description: Expands all sibling nodes that are at the same depth as the focused node. **`Shift + ArrowDown`** Description: Moves focus to and toggles the selection state of the next node. **`Shift + ArrowUp`** Description: Moves focus to and toggles the selection state of the previous node. **`Ctrl + A`** Description: Selects all nodes in the tree. If all nodes are selected, unselects all nodes. --- # Tree View (VUE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import styles from 'styles/tree-view.module.css' export const Basic = () => { return ( Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/tree-view.module.css' export const Basic = () => { return ( Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => props.node.children ? ( {nodeState().expanded ? : } {props.node.name} {(child, index) => } ) : ( {props.node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Controlled Expanded Pass the `expandedValue` and `onExpandedChange` props to the `TreeView.Root` component to control the expanded state of the tree view. **Example: controlled-expanded** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' export const ControlledExpanded = () => { const [expandedValue, setExpandedValue] = useState(['node_modules']) return ( setExpandedValue(expandedValue)} > Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For, createSignal } from 'solid-js' import styles from 'styles/tree-view.module.css' export const ControlledExpanded = () => { const [expandedValue, setExpandedValue] = createSignal(['node_modules']) return ( setExpandedValue(expandedValue)} > Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => props.node.children ? ( {nodeState().expanded ? : } {props.node.name} {(child, index) => } ) : ( {props.node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Controlled Selection Pass the `selectedValue` and `onSelectionChange` props to the `TreeView.Root` component to control the selected state of the tree view. **Example: controlled-selected** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' export const ControlledSelected = () => { const [selectedValue, setSelectedValue] = useState(['package.json']) return ( setSelectedValue(selectedValue)} > Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For, createSignal } from 'solid-js' import styles from 'styles/tree-view.module.css' export const ControlledSelected = () => { const [selectedValue, setSelectedValue] = createSignal(['package.json']) return ( setSelectedValue(selectedValue)} > Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => props.node.children ? ( {nodeState().expanded ? : } {props.node.name} {(child, index) => } ) : ( {props.node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Selected: {JSON.stringify(selectedValue)}
                    Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Root Provider An alternative way to control the tree view is to use the `RootProvider` component and the `useTreeView` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { TreeView, createTreeCollection, useTreeView } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import styles from 'styles/tree-view.module.css' export const RootProvider = () => { const treeView = useTreeView({ collection }) return (
                    selected: {JSON.stringify(treeView.selectedValue)} Tree {collection.rootNode.children?.map((node, index) => ( ))}
                    ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection, useTreeView } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/tree-view.module.css' export const RootProvider = () => { const treeView = useTreeView({ collection }) return ( Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => props.node.children ? ( {nodeState().expanded ? : } {props.node.name} {(child, index) => } ) : ( {props.node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Root Provider Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Lazy Loading Lazy loading is a feature that allows the tree view to load children of a node on demand (or async). This helps to improve the initial load time and memory usage. To use this, you need to provide the following: - `loadChildren` — A function that is used to load the children of a node. - `onLoadChildrenComplete` — A callback that is called when the children of a node are loaded. Used to update the tree collection. - `childrenCount` — A number that indicates the number of children of a branch node. **Example: async-loading** #### React ```tsx import { TreeView, createTreeCollection, useTreeViewNodeContext } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon, LoaderIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' // mock api result const response: Record = { node_modules: [ { id: 'zag-js', name: 'zag-js' }, { id: 'pandacss', name: 'panda' }, { id: '@types', name: '@types', childrenCount: 2 }, ], 'node_modules/@types': [ { id: 'react', name: 'react' }, { id: 'react-dom', name: 'react-dom' }, ], src: [ { id: 'app.tsx', name: 'app.tsx' }, { id: 'index.ts', name: 'index.ts' }, ], } // function to load children of a node function loadChildren(details: TreeView.LoadChildrenDetails): Promise { const value = details.valuePath.join('/') return new Promise((resolve) => { setTimeout(() => { resolve(response[value] ?? []) }, 500) }) } export const AsyncLoading = () => { const [collection, setCollection] = useState(initialCollection) return ( setCollection(e.collection)} > Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } function TreeBranchIcon() { const nodeState = useTreeViewNodeContext() if (nodeState.loading) return return nodeState.expanded ? : } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children || node.childrenCount ? ( {node.name} {node.children?.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] childrenCount?: number } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', childrenCount: 3 }, { id: 'src', name: 'src', childrenCount: 2 }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { SquareCheckBigIcon, ChevronRightIcon, FileIcon, FolderIcon, LoaderCircleIcon } from 'lucide-solid' import { For, createSignal } from 'solid-js' import { useTreeViewNodeContext } from '../use-tree-view-node-context' // mock api result const response: Record = { node_modules: [ { id: 'zag-js', name: 'zag-js' }, { id: 'pandacss', name: 'panda' }, { id: '@types', name: '@types', childrenCount: 2 }, ], 'node_modules/@types': [ { id: 'react', name: 'react' }, { id: 'react-dom', name: 'react-dom' }, ], src: [ { id: 'app.tsx', name: 'app.tsx' }, { id: 'index.ts', name: 'index.ts' }, ], } // function to load children of a node function loadChildren(details: TreeView.LoadChildrenDetails): Promise { const value = details.valuePath.join('/') return new Promise((resolve) => { setTimeout(() => { resolve(response[value] ?? []) }, 1200) }) } export const AsyncLoading = () => { const [collection, setCollection] = createSignal(initialCollection) return ( setCollection(e.collection)} > Tree {(node, index) => } ) } function TreeNodeIndicator() { const nodeState = useTreeViewNodeContext() return nodeState().loading ? : } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children || node.childrenCount ? ( {node.name} {(child, index) => } ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] childrenCount?: number } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', childrenCount: 3 }, { id: 'src', name: 'src', childrenCount: 2 }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte (collection = e.collection)} > Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children || node.childrenCount} {#if nodeState().loading} {:else} {/if} {node.name} {#each node.children ?? [] as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Lazy Mount Lazy mounting is a feature that allows the content of a tree view to be rendered only when it is expanded. This is useful for performance optimization, especially when tree content is large or complex. To enable lazy mounting, use the `lazyMount` prop on the `TreeView.Root` component. In addition, the `unmountOnExit` prop can be used in conjunction with `lazyMount` to unmount the tree view content when branches are collapsed, freeing up resources. The next time a branch is expanded, its content will be re-rendered. **Example: lazy-mount** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useTreeViewNodeContext } from '../use-tree-view-node-context' import styles from 'styles/tree-view.module.css' export const LazyMount = () => { return ( Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeBranchIcon = () => { const { expanded } = useTreeViewNodeContext() return expanded ? : } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children ? ( {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { SquareCheckBigIcon, ChevronRightIcon, FileIcon, FolderIcon } from 'lucide-solid' import { For, Show } from 'solid-js' interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) export const LazyMount = () => { return ( Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.name} } > {node.name} {(child, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Filtering Filtering is useful when you have a large tree and you want to filter the nodes to only show the ones that match the search query. Here's an example that composes the `filter` method from the `TreeCollection` and `useFilter` hook to filter the nodes. **Example: filtering** #### React ```tsx import { useFilter } from '@ark-ui/react/locale' import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' import fieldStyles from 'styles/field.module.css' export const Filtering = () => { const { contains } = useFilter({ sensitivity: 'base' }) const [collection, setCollection] = useState(initialCollection) const filter = (value: string) => { const filtered = value.length > 0 ? initialCollection.filter((node) => contains(node.name, value)) : initialCollection setCollection(filtered) } return (
                    filter(e.target.value)} /> {collection.rootNode.children?.map((node, index) => ( ))}
                    ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props const tree = useTreeViewContext() const nodeState = tree.getNodeState(props) return ( {nodeState.isBranch ? ( {nodeState.expanded ? : } {node.name} {node.children?.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { useFilter } from '@ark-ui/solid/locale' import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { SquareCheckBigIcon, ChevronRightIcon, FileIcon, FolderIcon } from 'lucide-solid' import { For, Show, createSignal } from 'solid-js' export const Filtering = () => { const filterFn = useFilter({ sensitivity: 'base' }) const [collection, setCollection] = createSignal(initialCollection) const filter = (value: string) => { const filtered = value.length > 0 ? initialCollection.filter((node) => filterFn().contains(node.name, value)) : initialCollection setCollection(filtered) } return (
                    filter(e.currentTarget.value)} /> {(node, index) => }
                    ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.name} } > {node.name} {(child, index) => } ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    filter(e.currentTarget.value)} /> {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each}
                    {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Links Tree items can be rendered as links to another page or website. This could be useful for documentation sites. Here's an example that modifies the tree collection to represent an hierarchical link structure. It uses the `asChild` prop to render the tree items as links, passing the `href` prop to a `
                    ` element. **Example: links** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, ExternalLinkIcon, FileIcon } from 'lucide-react' import styles from 'styles/tree-view.module.css' export const Links = () => { return ( Docs {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children ? ( {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} {node.href?.startsWith('http') && } )} ) } interface Node { id: string name: string href?: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'docs', name: 'Documentation', children: [ { id: 'docs/getting-started', name: 'Getting Started', href: '/docs/getting-started' }, { id: 'docs/installation', name: 'Installation', href: '/docs/installation' }, { id: 'docs/components', name: 'Components', children: [ { id: 'docs/components/accordion', name: 'Accordion', href: '/docs/components/accordion' }, { id: 'docs/components/dialog', name: 'Dialog', href: '/docs/components/dialog' }, { id: 'docs/components/menu', name: 'Menu', href: '/docs/components/menu' }, ], }, ], }, { id: 'examples', name: 'Examples', children: [ { id: 'examples/react', name: 'React Examples', href: '/examples/react' }, { id: 'examples/vue', name: 'Vue Examples', href: '/examples/vue' }, { id: 'examples/solid', name: 'Solid Examples', href: '/examples/solid' }, ], }, { id: 'external', name: 'External Links', children: [ { id: 'external/github', name: 'GitHub Repository', href: 'https://github.com/chakra-ui/zag' }, { id: 'external/npm', name: 'NPM Package', href: 'https://www.npmjs.com/package/@zag-js/core' }, { id: 'external/docs', name: 'Official Docs', href: 'https://zagjs.com' }, ], }, { id: 'readme.md', name: 'README.md', href: '/readme' }, { id: 'license', name: 'LICENSE', href: '/license' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, ExternalLinkIcon, FileIcon } from 'lucide-solid' import { For, Show } from 'solid-js' export const Links = () => { return ( Docs {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( }> {node.name} } > {node.name} {(child, index) => } ) } interface Node { id: string name: string href?: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'docs', name: 'Documentation', children: [ { id: 'docs/getting-started', name: 'Getting Started', href: '/docs/getting-started' }, { id: 'docs/installation', name: 'Installation', href: '/docs/installation' }, { id: 'docs/components', name: 'Components', children: [ { id: 'docs/components/accordion', name: 'Accordion', href: '/docs/components/accordion' }, { id: 'docs/components/dialog', name: 'Dialog', href: '/docs/components/dialog' }, { id: 'docs/components/menu', name: 'Menu', href: '/docs/components/menu' }, ], }, ], }, { id: 'examples', name: 'Examples', children: [ { id: 'examples/react', name: 'React Examples', href: '/examples/react' }, { id: 'examples/vue', name: 'Vue Examples', href: '/examples/vue' }, { id: 'examples/solid', name: 'Solid Examples', href: '/examples/solid' }, ], }, { id: 'external', name: 'External Links', children: [ { id: 'external/github', name: 'GitHub Repository', href: 'https://github.com/chakra-ui/zag' }, { id: 'external/npm', name: 'NPM Package', href: 'https://www.npmjs.com/package/@zag-js/core' }, { id: 'external/docs', name: 'Official Docs', href: 'https://zagjs.com' }, ], }, { id: 'readme.md', name: 'README.md', href: '/readme' }, { id: 'license', name: 'LICENSE', href: '/license' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Docs {#each collection.rootNode.children ?? [] as node, index (node.id)} {/each} ``` ### Virtualized For large tree views with thousands of nodes, virtualization can significantly improve performance by only rendering visible nodes. Key implementation details: - Use `useTreeView` hook with `TreeView.RootProvider` for programmatic control - Pass `scrollToIndexFn` to enable keyboard navigation within the virtualized list - Use `getVisibleNodes()` to get the flattened list of currently visible nodes **Example: virtualized** #### React ```tsx import { TreeView, createTreeCollection, useTreeView } from '@ark-ui/react/tree-view' import { useVirtualizer, type Virtualizer } from '@tanstack/react-virtual' import { ChevronRightIcon, FileIcon, FolderIcon } from 'lucide-react' import { useRef } from 'react' import { flushSync } from 'react-dom' import button from 'styles/button.module.css' import styles from 'styles/tree-view.module.css' interface Node { id: string name: string children?: Node[] } function generateLargeTree(): Node { const folders: Node[] = [] for (let i = 0; i < 50; i++) { const children: Node[] = [] for (let j = 0; j < 20; j++) { children.push({ id: `folder-${i}/file-${i}-${j}.ts`, name: `file-${i}-${j}.ts` }) } folders.push({ id: `folder-${i}`, name: `folder-${i}`, children }) } return { id: 'ROOT', name: '', children: folders, } } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: generateLargeTree(), }) const ROW_HEIGHT = 32 export const Virtualized = () => { const treeRef = useRef(null) const virtualizerRef = useRef | null>(null) const tree = useTreeView({ collection, scrollToIndexFn(details) { flushSync(() => { virtualizerRef.current?.scrollToIndex(details.index, { align: 'auto' }) }) }, }) const visibleNodes = tree.getVisibleNodes() const virtualizer = useVirtualizer({ count: visibleNodes.length, getScrollElement: () => treeRef.current, estimateSize: () => ROW_HEIGHT, overscan: 10, }) virtualizerRef.current = virtualizer return ( Virtualized Tree ({visibleNodes.length} visible nodes)
                    {virtualizer.getVirtualItems().map((virtualItem) => { const { node, indexPath } = visibleNodes[virtualItem.index] const nodeState = tree.getNodeState({ node, indexPath }) return (
                    { if (e.button !== 0) return tree.focus(node.id) }} style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: `${virtualItem.size}px`, transform: `translateY(${virtualItem.start}px)`, }} > {nodeState.isBranch ? ( {node.name} ) : ( {node.name} )}
                    ) })}
                    ) } ``` #### Solid ```tsx import { TreeView, createTreeCollection, useTreeView } from '@ark-ui/solid/tree-view' import { createVirtualizer, type Virtualizer } from '@tanstack/solid-virtual' import { ChevronRightIcon, FileIcon, FolderIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tree-view.module.css' interface Node { id: string name: string children?: Node[] } function generateLargeTree(): Node { const folders: Node[] = [] for (let i = 0; i < 50; i++) { const children: Node[] = [] for (let j = 0; j < 20; j++) { children.push({ id: `folder-${i}/file-${i}-${j}.ts`, name: `file-${i}-${j}.ts` }) } folders.push({ id: `folder-${i}`, name: `folder-${i}`, children }) } return { id: 'ROOT', name: '', children: folders, } } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: generateLargeTree(), }) const ROW_HEIGHT = 32 export const Virtualized = () => { let treeRef: HTMLDivElement | undefined let virtualizerRef: Virtualizer | undefined const tree = useTreeView({ collection, scrollToIndexFn(details) { virtualizerRef?.scrollToIndex(details.index, { align: 'auto' }) }, }) const visibleNodes = () => tree().getVisibleNodes() const virtualizer = createVirtualizer({ get count() { return visibleNodes().length }, getScrollElement: () => treeRef ?? null, estimateSize: () => ROW_HEIGHT, overscan: 10, }) virtualizerRef = virtualizer return ( Virtualized Tree ({visibleNodes().length} visible nodes)
                    {(virtualItem) => { const visibleNode = () => visibleNodes()[virtualItem.index] const nodeState = () => tree().getNodeState({ node: visibleNode().node, indexPath: visibleNode().indexPath }) return (
                    { if (e.button !== 0) return tree().focus(visibleNode().node.id) }} style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: `${virtualItem.size}px`, transform: `translateY(${virtualItem.start}px)`, }} > {nodeState().isBranch ? ( {visibleNode().node.name} ) : ( {visibleNode().node.name} )}
                    ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Virtualized Tree ({visibleNodes.length} visible nodes)
                    {#each $virtualizer.getVirtualItems() as virtualItem (visibleNodes[virtualItem.index].node.id)} {@const visibleNode = visibleNodes[virtualItem.index]} {@const nodeState = tree().getNodeState({ node: visibleNode.node, indexPath: visibleNode.indexPath })}
                    { if (e.button !== 0) return tree().focus(visibleNode.node.id) }} style="position: absolute; top: 0; left: 0; width: 100%; height: {virtualItem.size}px; transform: translateY({virtualItem.start}px);" > {#if nodeState.isBranch} {visibleNode.node.name} {:else} {visibleNode.node.name} {/if}
                    {/each}
                    ``` ### Checkbox Tree Use the `defaultCheckedValue` prop to enable checkbox selection mode. This allows users to select multiple nodes with checkboxes, including parent-child selection relationships. **Example: checkbox-tree** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { CheckIcon, ChevronRightIcon, MinusIcon } from 'lucide-react' import styles from 'styles/tree-view.module.css' export const CheckboxTree = () => { return ( Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNodeCheckbox = (props: TreeView.NodeCheckboxProps) => { return ( }> ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children ? ( {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { SquareCheckBigIcon, ChevronRightIcon, SquareMinusIcon, SquareIcon } from 'lucide-solid' import { For } from 'solid-js' export const CheckboxTree = () => { return ( Tree {(node, index) => } ) } const TreeNodeCheckbox = () => { return ( } fallback={}> ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children ? ( {node.name} {(child, index) => } ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet treeNodeCheckbox()} {#snippet indeterminate()} {/snippet} {#snippet fallback()} {/snippet} {/snippet} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#if node.children} {@render treeNodeCheckbox()} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {@render treeNodeCheckbox()} {node.name} {/if} {/snippet} ``` ### Expand and Collapse All Use the `expand()` and `collapse()` methods from the tree view context to programmatically expand or collapse all branches. **Example: expand-collapse-all** #### React ```tsx import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useMemo } from 'react' import button from 'styles/button.module.css' import styles from 'styles/tree-view.module.css' const ExpandCollapseButtons = () => { const tree = useTreeViewContext() const branchValues = useMemo(() => tree.collection.getBranchValues(), [tree.collection]) const isAllExpanded = useMemo( () => branchValues.every((value) => tree.expandedValue.includes(value)), [tree.expandedValue, branchValues], ) return (
                    {isAllExpanded ? ( ) : ( )}
                    ) } export const ExpandCollapseAll = () => { return ( {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For, Show, createMemo } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tree-view.module.css' const ExpandCollapseButtons = () => { const tree = useTreeViewContext() const branchValues = createMemo(() => tree().collection.getBranchValues()) const isAllExpanded = createMemo(() => branchValues().every((value) => tree().expandedValue.includes(value))) return (
                    tree().expand()}> Expand all } >
                    ) } export const ExpandCollapseAll = () => { return ( {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => ( {props.node.name} } > }> {props.node.name} {(child, index) => } )} ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tree)}
                    {#if branchValues.every((value) => tree().expandedValue.includes(value))} {:else} {/if}
                    {/snippet}
                    {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each}
                    {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Mutation Use the collection's `remove()` and `replace()` methods to dynamically add and remove nodes from the tree. This is useful for building file explorer interfaces where users can create and delete files. **Example: mutation** #### React ```tsx import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/react/tree-view' import { ChevronRightIcon, PlusIcon, TrashIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' export const Mutation = () => { const [collection, setCollection] = useState(initialCollection) const removeNode = (props: TreeNodeProps) => { setCollection(collection.remove([props.indexPath])) } const addNode = (props: TreeNodeProps) => { const { node, indexPath } = props if (!collection.isBranchNode(node)) return const children = [{ id: `untitled-${Date.now()}`, name: 'untitled.tsx' }, ...(node.children || [])] setCollection(collection.replace(indexPath, { ...node, children })) } return ( {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNodeActions = (props: TreeNodeProps) => { const { onRemove, onAdd, node } = props const tree = useTreeViewContext() const isBranch = tree.collection.isBranchNode(node) return (
                    {isBranch && ( )}
                    ) } interface TreeNodeProps extends TreeView.NodeProviderProps { onRemove?: (props: TreeView.NodeProviderProps) => void onAdd?: (props: TreeView.NodeProviderProps) => void } const TreeNode = (props: TreeNodeProps) => { const { node, indexPath } = props const tree = useTreeViewContext() const nodeState = tree.getNodeState(props) return ( {nodeState.isBranch ? ( {node.name} {node.children?.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, PlusIcon, TrashIcon } from 'lucide-solid' import { For, Show, createSignal } from 'solid-js' import styles from 'styles/tree-view.module.css' export const Mutation = () => { const [collection, setCollection] = createSignal(initialCollection) const removeNode = (props: TreeNodeProps) => { setCollection((prev) => prev.remove([props.indexPath])) } const addNode = (props: TreeNodeProps) => { const { node, indexPath } = props const col = collection() if (!col.isBranchNode(node)) return const children = [{ id: `untitled-${Date.now()}`, name: 'untitled.tsx' }, ...(node.children || [])] setCollection(col.replace(indexPath, { ...node, children })) } return ( {(node, index) => } ) } const TreeNodeActions = (props: TreeNodeProps) => { const tree = useTreeViewContext() const isBranch = () => tree().collection.isBranchNode(props.node) return (
                    ) } interface TreeNodeProps extends TreeView.NodeProviderProps { onRemove?: (props: TreeView.NodeProviderProps) => void onAdd?: (props: TreeView.NodeProviderProps) => void } const TreeNode = (props: TreeNodeProps) => { const tree = useTreeViewContext() const nodeState = () => tree().getNodeState(props) return ( {props.node.name} } > {props.node.name} {(child, index) => ( )} ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tree)} {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index], tree)} {/each} {/snippet} {#snippet renderNode(node: TreeNode, indexPath: number[], tree: any)} {#if node.children} {node.name}
                    {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index], tree)} {/each}
                    {:else} {node.name}
                    {/if}
                    {/snippet} ``` ### Rename Node Enable inline renaming of nodes using the `canRename` prop and `onRenameComplete` callback. Press F2 to activate rename mode on the focused node. **Example: rename-node** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' export const RenameNode = () => { const [collection, setCollection] = useState(initialCollection) return ( true} onRenameComplete={(details) => { setCollection((prev) => { const node = prev.at(details.indexPath) if (!node) return prev return prev.replace(details.indexPath, { ...node, name: details.label }) }) }} > Tree (Press F2 to rename) {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.renaming ? ( ) : ( {nodeState.expanded ? : } {node.name} )} {node.children.map((child, index) => ( ))} ) : ( {nodeState.renaming ? ( ) : ( {node.name} )} ) } ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For, Show, createSignal } from 'solid-js' import styles from 'styles/tree-view.module.css' export const RenameNode = () => { const [collection, setCollection] = createSignal(initialCollection) return ( true} onRenameComplete={(details) => { setCollection((prev) => { const node = prev.at(details.indexPath) if (!node) return prev return prev.replace(details.indexPath, { ...node, name: details.label }) }) }} > Tree (Press F2 to rename) {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => ( {props.node.name}} > } > }> {props.node.name} } > {(child, index) => } )} ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte true} onRenameComplete={handleRenameComplete}> Tree (Press F2 to rename) {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().renaming} {:else} {#if nodeState().expanded} {:else} {/if} {node.name} {/if} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {#if nodeState().renaming} {:else} {node.name} {/if} {/if} {/snippet} {/snippet} ``` ## Guides ### Type Safety The `TreeView.RootComponent` type enables you to create typed wrapper components that maintain full type safety for tree nodes. ```tsx import { TreeView as ArkTreeView } from '@ark-ui/react/tree-view' const TreeView: ArkTreeView.RootComponent = (props) => { return {/* ... */} } ``` Use the wrapper with full type inference on `onSelectionChange` and other callbacks: ```tsx const App = () => { const collection = createTreeCollection({ initialItems: [ { id: '1', label: 'React', children: [] }, { id: '2', label: 'Vue', children: [] }, ], }) return ( { // e.items is typed as Array<{ id: string, label: string, children: [] }> console.log(e.items) }} > {/* ... */} ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `TreeCollection` | Yes | The collection of tree nodes | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: T, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails) => void` | No | Called when the selection changes | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'multiple' | 'single'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **BranchContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-content | | `[data-state]` | "open" | "closed" | | `[data-depth]` | The depth of the item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | **BranchControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-control | | `[data-path]` | The path of the item | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-renaming]` | | | `[data-value]` | The value of the item | | `[data-depth]` | The depth of the item | | `[data-loading]` | Present when loading | **BranchIndentGuide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndentGuide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indent-guide | | `[data-depth]` | The depth of the item | **BranchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-loading]` | Present when loading | **Branch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Branch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch | | `[data-depth]` | The depth of the item | | `[data-branch]` | | | `[data-value]` | The value of the item | | `[data-path]` | The path of the item | | `[data-selected]` | Present when selected | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-loading]` | Present when loading | **Branch CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Branch | **BranchText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-text | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-loading]` | Present when loading | **BranchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-trigger | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-value]` | The value of the item | | `[data-loading]` | Present when loading | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | | `[data-focus]` | Present when focused | | `[data-selected]` | Present when selected | | `[data-disabled]` | Present when disabled | | `[data-renaming]` | | | `[data-depth]` | The depth of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckboxIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | | | `indeterminate` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | | **NodeCheckbox Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckbox Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | node-checkbox | | `[data-state]` | "checked" | "unchecked" | "indeterminate" | | `[data-disabled]` | Present when disabled | **NodeProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `indexPath` | `number[]` | Yes | The index path of the tree node | | `node` | `NonNullable` | No | The tree node | **NodeRenameInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Tree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `TreeCollection` | Yes | The collection of tree nodes | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: any, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails) => void` | No | Called when the selection changes | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'multiple' | 'single'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **BranchContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-content | | `[data-state]` | "open" | "closed" | | `[data-depth]` | The depth of the item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | **BranchControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-control | | `[data-path]` | The path of the item | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-renaming]` | | | `[data-value]` | The value of the item | | `[data-depth]` | The depth of the item | | `[data-loading]` | Present when loading | **BranchIndentGuide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndentGuide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indent-guide | | `[data-depth]` | The depth of the item | **BranchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-loading]` | Present when loading | **Branch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Branch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch | | `[data-depth]` | The depth of the item | | `[data-branch]` | | | `[data-value]` | The value of the item | | `[data-path]` | The path of the item | | `[data-selected]` | Present when selected | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-loading]` | Present when loading | **Branch CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Branch | **BranchText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-text | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-loading]` | Present when loading | **BranchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-trigger | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-value]` | The value of the item | | `[data-loading]` | Present when loading | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | | `[data-focus]` | Present when focused | | `[data-selected]` | Present when selected | | `[data-disabled]` | Present when disabled | | `[data-renaming]` | | | `[data-depth]` | The depth of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'h3'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckboxIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `number | boolean | Node | (string & {}) | ArrayElement` | No | | | `indeterminate` | `number | boolean | Node | (string & {}) | ArrayElement` | No | | **NodeCheckbox Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckbox Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | node-checkbox | | `[data-state]` | "checked" | "unchecked" | "indeterminate" | | `[data-disabled]` | Present when disabled | **NodeProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `indexPath` | `number[]` | Yes | The index path of the tree node | | `node` | `NonNullable` | No | The tree node | **NodeRenameInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Tree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `TreeCollection` | Yes | The collection of tree nodes | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: T, indexPath: number[]) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node values | | `defaultCheckedValue` | `string[]` | No | The initial checked node values when rendered. Use when you don't need to control the checked node values. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node values when rendered. Use when you don't need to control the expanded node values. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node values when rendered. Use when you don't need to control the selected node values. | | `expandedValue` | `string[]` | No | The controlled expanded node values | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The id of the focused node | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node(value: string): string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | A function that loads the children of a node. | | `selectedValue` | `string[]` | No | The controlled selected node values | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **BranchContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-content | | `[data-state]` | "open" | "closed" | | `[data-depth]` | The depth of the item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | **BranchControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-control | | `[data-path]` | The path of the item | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-renaming]` | | | `[data-value]` | The value of the item | | `[data-depth]` | The depth of the item | | `[data-loading]` | Present when loading | **BranchIndentGuide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndentGuide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indent-guide | | `[data-depth]` | The depth of the item | **BranchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-loading]` | Present when loading | **Branch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Branch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch | | `[data-depth]` | The depth of the item | | `[data-branch]` | | | `[data-value]` | The value of the item | | `[data-path]` | The path of the item | | `[data-selected]` | Present when selected | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-loading]` | Present when loading | **Branch CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Branch | **BranchText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-text | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-loading]` | Present when loading | **BranchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-trigger | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-value]` | The value of the item | | `[data-loading]` | Present when loading | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | | `[data-focus]` | Present when focused | | `[data-selected]` | Present when selected | | `[data-disabled]` | Present when disabled | | `[data-renaming]` | | | `[data-depth]` | The depth of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckboxIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `{}` | No | | | `indeterminate` | `{}` | No | | **NodeCheckbox Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckbox Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | node-checkbox | | `[data-state]` | "checked" | "unchecked" | "indeterminate" | | `[data-disabled]` | Present when disabled | **NodeProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `indexPath` | `number[]` | Yes | The index path of the tree node | | `node` | `NonNullable` | No | The tree node | **NodeRenameInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TreeViewApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Tree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: T, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `collection` | `TreeCollection` | No | The tree collection data | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails) => void` | No | Called when the selection changes | | `ref` | `Element` | No | | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'multiple' | 'single'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **BranchContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'ul'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-content | | `[data-state]` | "open" | "closed" | | `[data-depth]` | The depth of the item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | **BranchControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-control | | `[data-path]` | The path of the item | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-renaming]` | | | `[data-value]` | The value of the item | | `[data-depth]` | The depth of the item | | `[data-loading]` | Present when loading | **BranchIndentGuide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchIndentGuide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indent-guide | | `[data-depth]` | The depth of the item | **BranchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-loading]` | Present when loading | **Branch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'li'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Branch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch | | `[data-depth]` | The depth of the item | | `[data-branch]` | | | `[data-value]` | The value of the item | | `[data-path]` | The path of the item | | `[data-selected]` | Present when selected | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-loading]` | Present when loading | **Branch CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Branch | **BranchText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-text | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-loading]` | Present when loading | **BranchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-trigger | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-value]` | The value of the item | | `[data-loading]` | Present when loading | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTreeViewContext]>` | Yes | | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'li'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | | `[data-focus]` | Present when focused | | `[data-selected]` | Present when selected | | `[data-disabled]` | Present when disabled | | `[data-renaming]` | | | `[data-depth]` | The depth of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h3'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NodeCheckboxIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `Snippet<[]>` | No | | | `indeterminate` | `Snippet<[]>` | No | | **NodeCheckbox Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NodeCheckbox Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | node-checkbox | | `[data-state]` | "checked" | "unchecked" | "indeterminate" | | `[data-disabled]` | Present when disabled | **NodeContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTreeViewNodeContext]>` | Yes | | **NodeProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `indexPath` | `number[]` | Yes | | | `node` | `NonNullable` | No | | **NodeRenameInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Tree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'ul'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `collection` | `TreeCollection` | The tree collection data | | `expandedValue` | `string[]` | The value of the expanded nodes. | | `setExpandedValue` | `(value: string[]) => void` | Sets the expanded value | | `selectedValue` | `string[]` | The value of the selected nodes. | | `setSelectedValue` | `(value: string[]) => void` | Sets the selected value | | `checkedValue` | `string[]` | The value of the checked nodes | | `toggleChecked` | `(value: string, isBranch: boolean) => void` | Toggles the checked value of a node | | `setChecked` | `(value: string[]) => void` | Sets the checked value of a node | | `clearChecked` | `VoidFunction` | Clears the checked value of a node | | `getCheckedMap` | `() => CheckedValueMap` | Returns the checked details of branch and leaf nodes | | `getVisibleNodes` | `() => V[]` | Returns the visible nodes as a flat array of nodes and their index path | | `expand` | `(value?: string[]) => void` | Function to expand nodes. If no value is provided, all nodes will be expanded | | `collapse` | `(value?: string[]) => void` | Function to collapse nodes If no value is provided, all nodes will be collapsed | | `select` | `(value?: string[]) => void` | Function to select nodes If no value is provided, all nodes will be selected | | `deselect` | `(value?: string[]) => void` | Function to deselect nodes If no value is provided, all nodes will be deselected | | `focus` | `(value: string) => void` | Function to focus a node by value | | `selectParent` | `(value: string) => void` | Function to select the parent node of the focused node | | `expandParent` | `(value: string) => void` | Function to expand the parent node of the focused node | | `startRenaming` | `(value: string) => void` | Function to start renaming a node by value | | `submitRenaming` | `(value: string, label: string) => void` | Function to submit the rename and update the node label | | `cancelRenaming` | `() => void` | Function to cancel renaming without changes | ## Accessibility Complies with the [Tree View WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/). ### Keyboard Support **`Tab`** Description: Moves focus to the tree view, placing the first tree view item in focus. **`Enter + Space`** Description: Selects the item or branch node **`ArrowDown`** Description: Moves focus to the next node **`ArrowUp`** Description: Moves focus to the previous node **`ArrowRight`** Description: When focus is on a closed branch node, opens the branch.
                    When focus is on an open branch node, moves focus to the first item node. **`ArrowLeft`** Description: When focus is on an open branch node, closes the node.
                    When focus is on an item or branch node, moves focus to its parent branch node. **`Home`** Description: Moves focus to first node without opening or closing a node. **`End`** Description: Moves focus to the last node that can be focused without expanding any nodes that are closed. **`a-z + A-Z`** Description: Focus moves to the next node with a name that starts with the typed character. The search logic ignores nodes that are descendants of closed branch. **`*`** Description: Expands all sibling nodes that are at the same depth as the focused node. **`Shift + ArrowDown`** Description: Moves focus to and toggles the selection state of the next node. **`Shift + ArrowUp`** Description: Moves focus to and toggles the selection state of the previous node. **`Ctrl + A`** Description: Selects all nodes in the tree. If all nodes are selected, unselects all nodes. --- # Tree View (SVELTE) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import styles from 'styles/tree-view.module.css' export const Basic = () => { return ( Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/tree-view.module.css' export const Basic = () => { return ( Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => props.node.children ? ( {nodeState().expanded ? : } {props.node.name} {(child, index) => } ) : ( {props.node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Controlled Expanded Pass the `expandedValue` and `onExpandedChange` props to the `TreeView.Root` component to control the expanded state of the tree view. **Example: controlled-expanded** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' export const ControlledExpanded = () => { const [expandedValue, setExpandedValue] = useState(['node_modules']) return ( setExpandedValue(expandedValue)} > Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For, createSignal } from 'solid-js' import styles from 'styles/tree-view.module.css' export const ControlledExpanded = () => { const [expandedValue, setExpandedValue] = createSignal(['node_modules']) return ( setExpandedValue(expandedValue)} > Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => props.node.children ? ( {nodeState().expanded ? : } {props.node.name} {(child, index) => } ) : ( {props.node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Controlled Selection Pass the `selectedValue` and `onSelectionChange` props to the `TreeView.Root` component to control the selected state of the tree view. **Example: controlled-selected** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' export const ControlledSelected = () => { const [selectedValue, setSelectedValue] = useState(['package.json']) return ( setSelectedValue(selectedValue)} > Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For, createSignal } from 'solid-js' import styles from 'styles/tree-view.module.css' export const ControlledSelected = () => { const [selectedValue, setSelectedValue] = createSignal(['package.json']) return ( setSelectedValue(selectedValue)} > Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => props.node.children ? ( {nodeState().expanded ? : } {props.node.name} {(child, index) => } ) : ( {props.node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Selected: {JSON.stringify(selectedValue)}
                    Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Root Provider An alternative way to control the tree view is to use the `RootProvider` component and the `useTreeView` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { TreeView, createTreeCollection, useTreeView } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import styles from 'styles/tree-view.module.css' export const RootProvider = () => { const treeView = useTreeView({ collection }) return (
                    selected: {JSON.stringify(treeView.selectedValue)} Tree {collection.rootNode.children?.map((node, index) => ( ))}
                    ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection, useTreeView } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/tree-view.module.css' export const RootProvider = () => { const treeView = useTreeView({ collection }) return ( Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => props.node.children ? ( {nodeState().expanded ? : } {props.node.name} {(child, index) => } ) : ( {props.node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Root Provider Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Lazy Loading Lazy loading is a feature that allows the tree view to load children of a node on demand (or async). This helps to improve the initial load time and memory usage. To use this, you need to provide the following: - `loadChildren` — A function that is used to load the children of a node. - `onLoadChildrenComplete` — A callback that is called when the children of a node are loaded. Used to update the tree collection. - `childrenCount` — A number that indicates the number of children of a branch node. **Example: async-loading** #### React ```tsx import { TreeView, createTreeCollection, useTreeViewNodeContext } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon, LoaderIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' // mock api result const response: Record = { node_modules: [ { id: 'zag-js', name: 'zag-js' }, { id: 'pandacss', name: 'panda' }, { id: '@types', name: '@types', childrenCount: 2 }, ], 'node_modules/@types': [ { id: 'react', name: 'react' }, { id: 'react-dom', name: 'react-dom' }, ], src: [ { id: 'app.tsx', name: 'app.tsx' }, { id: 'index.ts', name: 'index.ts' }, ], } // function to load children of a node function loadChildren(details: TreeView.LoadChildrenDetails): Promise { const value = details.valuePath.join('/') return new Promise((resolve) => { setTimeout(() => { resolve(response[value] ?? []) }, 500) }) } export const AsyncLoading = () => { const [collection, setCollection] = useState(initialCollection) return ( setCollection(e.collection)} > Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } function TreeBranchIcon() { const nodeState = useTreeViewNodeContext() if (nodeState.loading) return return nodeState.expanded ? : } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children || node.childrenCount ? ( {node.name} {node.children?.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] childrenCount?: number } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', childrenCount: 3 }, { id: 'src', name: 'src', childrenCount: 2 }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { SquareCheckBigIcon, ChevronRightIcon, FileIcon, FolderIcon, LoaderCircleIcon } from 'lucide-solid' import { For, createSignal } from 'solid-js' import { useTreeViewNodeContext } from '../use-tree-view-node-context' // mock api result const response: Record = { node_modules: [ { id: 'zag-js', name: 'zag-js' }, { id: 'pandacss', name: 'panda' }, { id: '@types', name: '@types', childrenCount: 2 }, ], 'node_modules/@types': [ { id: 'react', name: 'react' }, { id: 'react-dom', name: 'react-dom' }, ], src: [ { id: 'app.tsx', name: 'app.tsx' }, { id: 'index.ts', name: 'index.ts' }, ], } // function to load children of a node function loadChildren(details: TreeView.LoadChildrenDetails): Promise { const value = details.valuePath.join('/') return new Promise((resolve) => { setTimeout(() => { resolve(response[value] ?? []) }, 1200) }) } export const AsyncLoading = () => { const [collection, setCollection] = createSignal(initialCollection) return ( setCollection(e.collection)} > Tree {(node, index) => } ) } function TreeNodeIndicator() { const nodeState = useTreeViewNodeContext() return nodeState().loading ? : } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children || node.childrenCount ? ( {node.name} {(child, index) => } ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] childrenCount?: number } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', childrenCount: 3 }, { id: 'src', name: 'src', childrenCount: 2 }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte (collection = e.collection)} > Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children || node.childrenCount} {#if nodeState().loading} {:else} {/if} {node.name} {#each node.children ?? [] as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Lazy Mount Lazy mounting is a feature that allows the content of a tree view to be rendered only when it is expanded. This is useful for performance optimization, especially when tree content is large or complex. To enable lazy mounting, use the `lazyMount` prop on the `TreeView.Root` component. In addition, the `unmountOnExit` prop can be used in conjunction with `lazyMount` to unmount the tree view content when branches are collapsed, freeing up resources. The next time a branch is expanded, its content will be re-rendered. **Example: lazy-mount** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useTreeViewNodeContext } from '../use-tree-view-node-context' import styles from 'styles/tree-view.module.css' export const LazyMount = () => { return ( Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeBranchIcon = () => { const { expanded } = useTreeViewNodeContext() return expanded ? : } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children ? ( {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { SquareCheckBigIcon, ChevronRightIcon, FileIcon, FolderIcon } from 'lucide-solid' import { For, Show } from 'solid-js' interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) export const LazyMount = () => { return ( Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.name} } > {node.name} {(child, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Filtering Filtering is useful when you have a large tree and you want to filter the nodes to only show the ones that match the search query. Here's an example that composes the `filter` method from the `TreeCollection` and `useFilter` hook to filter the nodes. **Example: filtering** #### React ```tsx import { useFilter } from '@ark-ui/react/locale' import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' import fieldStyles from 'styles/field.module.css' export const Filtering = () => { const { contains } = useFilter({ sensitivity: 'base' }) const [collection, setCollection] = useState(initialCollection) const filter = (value: string) => { const filtered = value.length > 0 ? initialCollection.filter((node) => contains(node.name, value)) : initialCollection setCollection(filtered) } return (
                    filter(e.target.value)} /> {collection.rootNode.children?.map((node, index) => ( ))}
                    ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props const tree = useTreeViewContext() const nodeState = tree.getNodeState(props) return ( {nodeState.isBranch ? ( {nodeState.expanded ? : } {node.name} {node.children?.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { useFilter } from '@ark-ui/solid/locale' import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { SquareCheckBigIcon, ChevronRightIcon, FileIcon, FolderIcon } from 'lucide-solid' import { For, Show, createSignal } from 'solid-js' export const Filtering = () => { const filterFn = useFilter({ sensitivity: 'base' }) const [collection, setCollection] = createSignal(initialCollection) const filter = (value: string) => { const filtered = value.length > 0 ? initialCollection.filter((node) => filterFn().contains(node.name, value)) : initialCollection setCollection(filtered) } return (
                    filter(e.currentTarget.value)} /> {(node, index) => }
                    ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.name} } > {node.name} {(child, index) => } ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    filter(e.currentTarget.value)} /> {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each}
                    {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Links Tree items can be rendered as links to another page or website. This could be useful for documentation sites. Here's an example that modifies the tree collection to represent an hierarchical link structure. It uses the `asChild` prop to render the tree items as links, passing the `href` prop to a `
                    ` element. **Example: links** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, ExternalLinkIcon, FileIcon } from 'lucide-react' import styles from 'styles/tree-view.module.css' export const Links = () => { return ( Docs {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children ? ( {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} {node.href?.startsWith('http') && } )} ) } interface Node { id: string name: string href?: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'docs', name: 'Documentation', children: [ { id: 'docs/getting-started', name: 'Getting Started', href: '/docs/getting-started' }, { id: 'docs/installation', name: 'Installation', href: '/docs/installation' }, { id: 'docs/components', name: 'Components', children: [ { id: 'docs/components/accordion', name: 'Accordion', href: '/docs/components/accordion' }, { id: 'docs/components/dialog', name: 'Dialog', href: '/docs/components/dialog' }, { id: 'docs/components/menu', name: 'Menu', href: '/docs/components/menu' }, ], }, ], }, { id: 'examples', name: 'Examples', children: [ { id: 'examples/react', name: 'React Examples', href: '/examples/react' }, { id: 'examples/vue', name: 'Vue Examples', href: '/examples/vue' }, { id: 'examples/solid', name: 'Solid Examples', href: '/examples/solid' }, ], }, { id: 'external', name: 'External Links', children: [ { id: 'external/github', name: 'GitHub Repository', href: 'https://github.com/chakra-ui/zag' }, { id: 'external/npm', name: 'NPM Package', href: 'https://www.npmjs.com/package/@zag-js/core' }, { id: 'external/docs', name: 'Official Docs', href: 'https://zagjs.com' }, ], }, { id: 'readme.md', name: 'README.md', href: '/readme' }, { id: 'license', name: 'LICENSE', href: '/license' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, ExternalLinkIcon, FileIcon } from 'lucide-solid' import { For, Show } from 'solid-js' export const Links = () => { return ( Docs {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( }> {node.name} } > {node.name} {(child, index) => } ) } interface Node { id: string name: string href?: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'docs', name: 'Documentation', children: [ { id: 'docs/getting-started', name: 'Getting Started', href: '/docs/getting-started' }, { id: 'docs/installation', name: 'Installation', href: '/docs/installation' }, { id: 'docs/components', name: 'Components', children: [ { id: 'docs/components/accordion', name: 'Accordion', href: '/docs/components/accordion' }, { id: 'docs/components/dialog', name: 'Dialog', href: '/docs/components/dialog' }, { id: 'docs/components/menu', name: 'Menu', href: '/docs/components/menu' }, ], }, ], }, { id: 'examples', name: 'Examples', children: [ { id: 'examples/react', name: 'React Examples', href: '/examples/react' }, { id: 'examples/vue', name: 'Vue Examples', href: '/examples/vue' }, { id: 'examples/solid', name: 'Solid Examples', href: '/examples/solid' }, ], }, { id: 'external', name: 'External Links', children: [ { id: 'external/github', name: 'GitHub Repository', href: 'https://github.com/chakra-ui/zag' }, { id: 'external/npm', name: 'NPM Package', href: 'https://www.npmjs.com/package/@zag-js/core' }, { id: 'external/docs', name: 'Official Docs', href: 'https://zagjs.com' }, ], }, { id: 'readme.md', name: 'README.md', href: '/readme' }, { id: 'license', name: 'LICENSE', href: '/license' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Docs {#each collection.rootNode.children ?? [] as node, index (node.id)} {/each} ``` ### Virtualized For large tree views with thousands of nodes, virtualization can significantly improve performance by only rendering visible nodes. Key implementation details: - Use `useTreeView` hook with `TreeView.RootProvider` for programmatic control - Pass `scrollToIndexFn` to enable keyboard navigation within the virtualized list - Use `getVisibleNodes()` to get the flattened list of currently visible nodes **Example: virtualized** #### React ```tsx import { TreeView, createTreeCollection, useTreeView } from '@ark-ui/react/tree-view' import { useVirtualizer, type Virtualizer } from '@tanstack/react-virtual' import { ChevronRightIcon, FileIcon, FolderIcon } from 'lucide-react' import { useRef } from 'react' import { flushSync } from 'react-dom' import button from 'styles/button.module.css' import styles from 'styles/tree-view.module.css' interface Node { id: string name: string children?: Node[] } function generateLargeTree(): Node { const folders: Node[] = [] for (let i = 0; i < 50; i++) { const children: Node[] = [] for (let j = 0; j < 20; j++) { children.push({ id: `folder-${i}/file-${i}-${j}.ts`, name: `file-${i}-${j}.ts` }) } folders.push({ id: `folder-${i}`, name: `folder-${i}`, children }) } return { id: 'ROOT', name: '', children: folders, } } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: generateLargeTree(), }) const ROW_HEIGHT = 32 export const Virtualized = () => { const treeRef = useRef(null) const virtualizerRef = useRef | null>(null) const tree = useTreeView({ collection, scrollToIndexFn(details) { flushSync(() => { virtualizerRef.current?.scrollToIndex(details.index, { align: 'auto' }) }) }, }) const visibleNodes = tree.getVisibleNodes() const virtualizer = useVirtualizer({ count: visibleNodes.length, getScrollElement: () => treeRef.current, estimateSize: () => ROW_HEIGHT, overscan: 10, }) virtualizerRef.current = virtualizer return ( Virtualized Tree ({visibleNodes.length} visible nodes)
                    {virtualizer.getVirtualItems().map((virtualItem) => { const { node, indexPath } = visibleNodes[virtualItem.index] const nodeState = tree.getNodeState({ node, indexPath }) return (
                    { if (e.button !== 0) return tree.focus(node.id) }} style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: `${virtualItem.size}px`, transform: `translateY(${virtualItem.start}px)`, }} > {nodeState.isBranch ? ( {node.name} ) : ( {node.name} )}
                    ) })}
                    ) } ``` #### Solid ```tsx import { TreeView, createTreeCollection, useTreeView } from '@ark-ui/solid/tree-view' import { createVirtualizer, type Virtualizer } from '@tanstack/solid-virtual' import { ChevronRightIcon, FileIcon, FolderIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tree-view.module.css' interface Node { id: string name: string children?: Node[] } function generateLargeTree(): Node { const folders: Node[] = [] for (let i = 0; i < 50; i++) { const children: Node[] = [] for (let j = 0; j < 20; j++) { children.push({ id: `folder-${i}/file-${i}-${j}.ts`, name: `file-${i}-${j}.ts` }) } folders.push({ id: `folder-${i}`, name: `folder-${i}`, children }) } return { id: 'ROOT', name: '', children: folders, } } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: generateLargeTree(), }) const ROW_HEIGHT = 32 export const Virtualized = () => { let treeRef: HTMLDivElement | undefined let virtualizerRef: Virtualizer | undefined const tree = useTreeView({ collection, scrollToIndexFn(details) { virtualizerRef?.scrollToIndex(details.index, { align: 'auto' }) }, }) const visibleNodes = () => tree().getVisibleNodes() const virtualizer = createVirtualizer({ get count() { return visibleNodes().length }, getScrollElement: () => treeRef ?? null, estimateSize: () => ROW_HEIGHT, overscan: 10, }) virtualizerRef = virtualizer return ( Virtualized Tree ({visibleNodes().length} visible nodes)
                    {(virtualItem) => { const visibleNode = () => visibleNodes()[virtualItem.index] const nodeState = () => tree().getNodeState({ node: visibleNode().node, indexPath: visibleNode().indexPath }) return (
                    { if (e.button !== 0) return tree().focus(visibleNode().node.id) }} style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: `${virtualItem.size}px`, transform: `translateY(${virtualItem.start}px)`, }} > {nodeState().isBranch ? ( {visibleNode().node.name} ) : ( {visibleNode().node.name} )}
                    ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Virtualized Tree ({visibleNodes.length} visible nodes)
                    {#each $virtualizer.getVirtualItems() as virtualItem (visibleNodes[virtualItem.index].node.id)} {@const visibleNode = visibleNodes[virtualItem.index]} {@const nodeState = tree().getNodeState({ node: visibleNode.node, indexPath: visibleNode.indexPath })}
                    { if (e.button !== 0) return tree().focus(visibleNode.node.id) }} style="position: absolute; top: 0; left: 0; width: 100%; height: {virtualItem.size}px; transform: translateY({virtualItem.start}px);" > {#if nodeState.isBranch} {visibleNode.node.name} {:else} {visibleNode.node.name} {/if}
                    {/each}
                    ``` ### Checkbox Tree Use the `defaultCheckedValue` prop to enable checkbox selection mode. This allows users to select multiple nodes with checkboxes, including parent-child selection relationships. **Example: checkbox-tree** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { CheckIcon, ChevronRightIcon, MinusIcon } from 'lucide-react' import styles from 'styles/tree-view.module.css' export const CheckboxTree = () => { return ( Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNodeCheckbox = (props: TreeView.NodeCheckboxProps) => { return ( }> ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children ? ( {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { SquareCheckBigIcon, ChevronRightIcon, SquareMinusIcon, SquareIcon } from 'lucide-solid' import { For } from 'solid-js' export const CheckboxTree = () => { return ( Tree {(node, index) => } ) } const TreeNodeCheckbox = () => { return ( } fallback={}> ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children ? ( {node.name} {(child, index) => } ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet treeNodeCheckbox()} {#snippet indeterminate()} {/snippet} {#snippet fallback()} {/snippet} {/snippet} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#if node.children} {@render treeNodeCheckbox()} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {@render treeNodeCheckbox()} {node.name} {/if} {/snippet} ``` ### Expand and Collapse All Use the `expand()` and `collapse()` methods from the tree view context to programmatically expand or collapse all branches. **Example: expand-collapse-all** #### React ```tsx import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useMemo } from 'react' import button from 'styles/button.module.css' import styles from 'styles/tree-view.module.css' const ExpandCollapseButtons = () => { const tree = useTreeViewContext() const branchValues = useMemo(() => tree.collection.getBranchValues(), [tree.collection]) const isAllExpanded = useMemo( () => branchValues.every((value) => tree.expandedValue.includes(value)), [tree.expandedValue, branchValues], ) return (
                    {isAllExpanded ? ( ) : ( )}
                    ) } export const ExpandCollapseAll = () => { return ( {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For, Show, createMemo } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tree-view.module.css' const ExpandCollapseButtons = () => { const tree = useTreeViewContext() const branchValues = createMemo(() => tree().collection.getBranchValues()) const isAllExpanded = createMemo(() => branchValues().every((value) => tree().expandedValue.includes(value))) return (
                    tree().expand()}> Expand all } >
                    ) } export const ExpandCollapseAll = () => { return ( {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => ( {props.node.name} } > }> {props.node.name} {(child, index) => } )} ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tree)}
                    {#if branchValues.every((value) => tree().expandedValue.includes(value))} {:else} {/if}
                    {/snippet}
                    {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each}
                    {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Mutation Use the collection's `remove()` and `replace()` methods to dynamically add and remove nodes from the tree. This is useful for building file explorer interfaces where users can create and delete files. **Example: mutation** #### React ```tsx import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/react/tree-view' import { ChevronRightIcon, PlusIcon, TrashIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' export const Mutation = () => { const [collection, setCollection] = useState(initialCollection) const removeNode = (props: TreeNodeProps) => { setCollection(collection.remove([props.indexPath])) } const addNode = (props: TreeNodeProps) => { const { node, indexPath } = props if (!collection.isBranchNode(node)) return const children = [{ id: `untitled-${Date.now()}`, name: 'untitled.tsx' }, ...(node.children || [])] setCollection(collection.replace(indexPath, { ...node, children })) } return ( {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNodeActions = (props: TreeNodeProps) => { const { onRemove, onAdd, node } = props const tree = useTreeViewContext() const isBranch = tree.collection.isBranchNode(node) return (
                    {isBranch && ( )}
                    ) } interface TreeNodeProps extends TreeView.NodeProviderProps { onRemove?: (props: TreeView.NodeProviderProps) => void onAdd?: (props: TreeView.NodeProviderProps) => void } const TreeNode = (props: TreeNodeProps) => { const { node, indexPath } = props const tree = useTreeViewContext() const nodeState = tree.getNodeState(props) return ( {nodeState.isBranch ? ( {node.name} {node.children?.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, PlusIcon, TrashIcon } from 'lucide-solid' import { For, Show, createSignal } from 'solid-js' import styles from 'styles/tree-view.module.css' export const Mutation = () => { const [collection, setCollection] = createSignal(initialCollection) const removeNode = (props: TreeNodeProps) => { setCollection((prev) => prev.remove([props.indexPath])) } const addNode = (props: TreeNodeProps) => { const { node, indexPath } = props const col = collection() if (!col.isBranchNode(node)) return const children = [{ id: `untitled-${Date.now()}`, name: 'untitled.tsx' }, ...(node.children || [])] setCollection(col.replace(indexPath, { ...node, children })) } return ( {(node, index) => } ) } const TreeNodeActions = (props: TreeNodeProps) => { const tree = useTreeViewContext() const isBranch = () => tree().collection.isBranchNode(props.node) return (
                    ) } interface TreeNodeProps extends TreeView.NodeProviderProps { onRemove?: (props: TreeView.NodeProviderProps) => void onAdd?: (props: TreeView.NodeProviderProps) => void } const TreeNode = (props: TreeNodeProps) => { const tree = useTreeViewContext() const nodeState = () => tree().getNodeState(props) return ( {props.node.name} } > {props.node.name} {(child, index) => ( )} ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tree)} {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index], tree)} {/each} {/snippet} {#snippet renderNode(node: TreeNode, indexPath: number[], tree: any)} {#if node.children} {node.name}
                    {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index], tree)} {/each}
                    {:else} {node.name}
                    {/if}
                    {/snippet} ``` ### Rename Node Enable inline renaming of nodes using the `canRename` prop and `onRenameComplete` callback. Press F2 to activate rename mode on the focused node. **Example: rename-node** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' export const RenameNode = () => { const [collection, setCollection] = useState(initialCollection) return ( true} onRenameComplete={(details) => { setCollection((prev) => { const node = prev.at(details.indexPath) if (!node) return prev return prev.replace(details.indexPath, { ...node, name: details.label }) }) }} > Tree (Press F2 to rename) {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.renaming ? ( ) : ( {nodeState.expanded ? : } {node.name} )} {node.children.map((child, index) => ( ))} ) : ( {nodeState.renaming ? ( ) : ( {node.name} )} ) } ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For, Show, createSignal } from 'solid-js' import styles from 'styles/tree-view.module.css' export const RenameNode = () => { const [collection, setCollection] = createSignal(initialCollection) return ( true} onRenameComplete={(details) => { setCollection((prev) => { const node = prev.at(details.indexPath) if (!node) return prev return prev.replace(details.indexPath, { ...node, name: details.label }) }) }} > Tree (Press F2 to rename) {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => ( {props.node.name}} > } > }> {props.node.name} } > {(child, index) => } )} ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte true} onRenameComplete={handleRenameComplete}> Tree (Press F2 to rename) {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().renaming} {:else} {#if nodeState().expanded} {:else} {/if} {node.name} {/if} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {#if nodeState().renaming} {:else} {node.name} {/if} {/if} {/snippet} {/snippet} ``` ## Guides ### Type Safety The `TreeView.RootComponent` type enables you to create typed wrapper components that maintain full type safety for tree nodes. ```tsx import { TreeView as ArkTreeView } from '@ark-ui/react/tree-view' const TreeView: ArkTreeView.RootComponent = (props) => { return {/* ... */} } ``` Use the wrapper with full type inference on `onSelectionChange` and other callbacks: ```tsx const App = () => { const collection = createTreeCollection({ initialItems: [ { id: '1', label: 'React', children: [] }, { id: '2', label: 'Vue', children: [] }, ], }) return ( { // e.items is typed as Array<{ id: string, label: string, children: [] }> console.log(e.items) }} > {/* ... */} ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `TreeCollection` | Yes | The collection of tree nodes | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: T, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails) => void` | No | Called when the selection changes | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'multiple' | 'single'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **BranchContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-content | | `[data-state]` | "open" | "closed" | | `[data-depth]` | The depth of the item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | **BranchControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-control | | `[data-path]` | The path of the item | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-renaming]` | | | `[data-value]` | The value of the item | | `[data-depth]` | The depth of the item | | `[data-loading]` | Present when loading | **BranchIndentGuide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndentGuide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indent-guide | | `[data-depth]` | The depth of the item | **BranchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-loading]` | Present when loading | **Branch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Branch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch | | `[data-depth]` | The depth of the item | | `[data-branch]` | | | `[data-value]` | The value of the item | | `[data-path]` | The path of the item | | `[data-selected]` | Present when selected | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-loading]` | Present when loading | **Branch CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Branch | **BranchText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-text | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-loading]` | Present when loading | **BranchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-trigger | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-value]` | The value of the item | | `[data-loading]` | Present when loading | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | | `[data-focus]` | Present when focused | | `[data-selected]` | Present when selected | | `[data-disabled]` | Present when disabled | | `[data-renaming]` | | | `[data-depth]` | The depth of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckboxIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | | | `indeterminate` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | | **NodeCheckbox Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckbox Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | node-checkbox | | `[data-state]` | "checked" | "unchecked" | "indeterminate" | | `[data-disabled]` | Present when disabled | **NodeProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `indexPath` | `number[]` | Yes | The index path of the tree node | | `node` | `NonNullable` | No | The tree node | **NodeRenameInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Tree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `TreeCollection` | Yes | The collection of tree nodes | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: any, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails) => void` | No | Called when the selection changes | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'multiple' | 'single'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **BranchContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-content | | `[data-state]` | "open" | "closed" | | `[data-depth]` | The depth of the item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | **BranchControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-control | | `[data-path]` | The path of the item | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-renaming]` | | | `[data-value]` | The value of the item | | `[data-depth]` | The depth of the item | | `[data-loading]` | Present when loading | **BranchIndentGuide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndentGuide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indent-guide | | `[data-depth]` | The depth of the item | **BranchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-loading]` | Present when loading | **Branch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Branch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch | | `[data-depth]` | The depth of the item | | `[data-branch]` | | | `[data-value]` | The value of the item | | `[data-path]` | The path of the item | | `[data-selected]` | Present when selected | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-loading]` | Present when loading | **Branch CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Branch | **BranchText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-text | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-loading]` | Present when loading | **BranchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-trigger | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-value]` | The value of the item | | `[data-loading]` | Present when loading | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | | `[data-focus]` | Present when focused | | `[data-selected]` | Present when selected | | `[data-disabled]` | Present when disabled | | `[data-renaming]` | | | `[data-depth]` | The depth of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'h3'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckboxIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `number | boolean | Node | (string & {}) | ArrayElement` | No | | | `indeterminate` | `number | boolean | Node | (string & {}) | ArrayElement` | No | | **NodeCheckbox Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckbox Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | node-checkbox | | `[data-state]` | "checked" | "unchecked" | "indeterminate" | | `[data-disabled]` | Present when disabled | **NodeProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `indexPath` | `number[]` | Yes | The index path of the tree node | | `node` | `NonNullable` | No | The tree node | **NodeRenameInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Tree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `TreeCollection` | Yes | The collection of tree nodes | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: T, indexPath: number[]) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node values | | `defaultCheckedValue` | `string[]` | No | The initial checked node values when rendered. Use when you don't need to control the checked node values. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node values when rendered. Use when you don't need to control the expanded node values. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node values when rendered. Use when you don't need to control the selected node values. | | `expandedValue` | `string[]` | No | The controlled expanded node values | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The id of the focused node | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node(value: string): string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | A function that loads the children of a node. | | `selectedValue` | `string[]` | No | The controlled selected node values | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **BranchContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-content | | `[data-state]` | "open" | "closed" | | `[data-depth]` | The depth of the item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | **BranchControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-control | | `[data-path]` | The path of the item | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-renaming]` | | | `[data-value]` | The value of the item | | `[data-depth]` | The depth of the item | | `[data-loading]` | Present when loading | **BranchIndentGuide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndentGuide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indent-guide | | `[data-depth]` | The depth of the item | **BranchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-loading]` | Present when loading | **Branch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Branch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch | | `[data-depth]` | The depth of the item | | `[data-branch]` | | | `[data-value]` | The value of the item | | `[data-path]` | The path of the item | | `[data-selected]` | Present when selected | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-loading]` | Present when loading | **Branch CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Branch | **BranchText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-text | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-loading]` | Present when loading | **BranchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-trigger | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-value]` | The value of the item | | `[data-loading]` | Present when loading | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | | `[data-focus]` | Present when focused | | `[data-selected]` | Present when selected | | `[data-disabled]` | Present when disabled | | `[data-renaming]` | | | `[data-depth]` | The depth of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckboxIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `{}` | No | | | `indeterminate` | `{}` | No | | **NodeCheckbox Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckbox Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | node-checkbox | | `[data-state]` | "checked" | "unchecked" | "indeterminate" | | `[data-disabled]` | Present when disabled | **NodeProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `indexPath` | `number[]` | Yes | The index path of the tree node | | `node` | `NonNullable` | No | The tree node | **NodeRenameInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TreeViewApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Tree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: T, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `collection` | `TreeCollection` | No | The tree collection data | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails) => void` | No | Called when the selection changes | | `ref` | `Element` | No | | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'multiple' | 'single'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **BranchContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'ul'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-content | | `[data-state]` | "open" | "closed" | | `[data-depth]` | The depth of the item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | **BranchControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-control | | `[data-path]` | The path of the item | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-renaming]` | | | `[data-value]` | The value of the item | | `[data-depth]` | The depth of the item | | `[data-loading]` | Present when loading | **BranchIndentGuide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchIndentGuide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indent-guide | | `[data-depth]` | The depth of the item | **BranchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-loading]` | Present when loading | **Branch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'li'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Branch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch | | `[data-depth]` | The depth of the item | | `[data-branch]` | | | `[data-value]` | The value of the item | | `[data-path]` | The path of the item | | `[data-selected]` | Present when selected | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-loading]` | Present when loading | **Branch CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Branch | **BranchText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-text | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-loading]` | Present when loading | **BranchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-trigger | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-value]` | The value of the item | | `[data-loading]` | Present when loading | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTreeViewContext]>` | Yes | | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'li'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | | `[data-focus]` | Present when focused | | `[data-selected]` | Present when selected | | `[data-disabled]` | Present when disabled | | `[data-renaming]` | | | `[data-depth]` | The depth of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h3'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NodeCheckboxIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `Snippet<[]>` | No | | | `indeterminate` | `Snippet<[]>` | No | | **NodeCheckbox Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NodeCheckbox Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | node-checkbox | | `[data-state]` | "checked" | "unchecked" | "indeterminate" | | `[data-disabled]` | Present when disabled | **NodeContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTreeViewNodeContext]>` | Yes | | **NodeProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `indexPath` | `number[]` | Yes | | | `node` | `NonNullable` | No | | **NodeRenameInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Tree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'ul'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `collection` | `TreeCollection` | The tree collection data | | `expandedValue` | `string[]` | The value of the expanded nodes. | | `setExpandedValue` | `(value: string[]) => void` | Sets the expanded value | | `selectedValue` | `string[]` | The value of the selected nodes. | | `setSelectedValue` | `(value: string[]) => void` | Sets the selected value | | `checkedValue` | `string[]` | The value of the checked nodes | | `toggleChecked` | `(value: string, isBranch: boolean) => void` | Toggles the checked value of a node | | `setChecked` | `(value: string[]) => void` | Sets the checked value of a node | | `clearChecked` | `VoidFunction` | Clears the checked value of a node | | `getCheckedMap` | `() => CheckedValueMap` | Returns the checked details of branch and leaf nodes | | `getVisibleNodes` | `() => V[]` | Returns the visible nodes as a flat array of nodes and their index path | | `expand` | `(value?: string[]) => void` | Function to expand nodes. If no value is provided, all nodes will be expanded | | `collapse` | `(value?: string[]) => void` | Function to collapse nodes If no value is provided, all nodes will be collapsed | | `select` | `(value?: string[]) => void` | Function to select nodes If no value is provided, all nodes will be selected | | `deselect` | `(value?: string[]) => void` | Function to deselect nodes If no value is provided, all nodes will be deselected | | `focus` | `(value: string) => void` | Function to focus a node by value | | `selectParent` | `(value: string) => void` | Function to select the parent node of the focused node | | `expandParent` | `(value: string) => void` | Function to expand the parent node of the focused node | | `startRenaming` | `(value: string) => void` | Function to start renaming a node by value | | `submitRenaming` | `(value: string, label: string) => void` | Function to submit the rename and update the node label | | `cancelRenaming` | `() => void` | Function to cancel renaming without changes | ## Accessibility Complies with the [Tree View WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/). ### Keyboard Support **`Tab`** Description: Moves focus to the tree view, placing the first tree view item in focus. **`Enter + Space`** Description: Selects the item or branch node **`ArrowDown`** Description: Moves focus to the next node **`ArrowUp`** Description: Moves focus to the previous node **`ArrowRight`** Description: When focus is on a closed branch node, opens the branch.
                    When focus is on an open branch node, moves focus to the first item node. **`ArrowLeft`** Description: When focus is on an open branch node, closes the node.
                    When focus is on an item or branch node, moves focus to its parent branch node. **`Home`** Description: Moves focus to first node without opening or closing a node. **`End`** Description: Moves focus to the last node that can be focused without expanding any nodes that are closed. **`a-z + A-Z`** Description: Focus moves to the next node with a name that starts with the typed character. The search logic ignores nodes that are descendants of closed branch. **`*`** Description: Expands all sibling nodes that are at the same depth as the focused node. **`Shift + ArrowDown`** Description: Moves focus to and toggles the selection state of the next node. **`Shift + ArrowUp`** Description: Moves focus to and toggles the selection state of the previous node. **`Ctrl + A`** Description: Selects all nodes in the tree. If all nodes are selected, unselects all nodes. --- # Tree View (SOLID) ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import styles from 'styles/tree-view.module.css' export const Basic = () => { return ( Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/tree-view.module.css' export const Basic = () => { return ( Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => props.node.children ? ( {nodeState().expanded ? : } {props.node.name} {(child, index) => } ) : ( {props.node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Controlled Expanded Pass the `expandedValue` and `onExpandedChange` props to the `TreeView.Root` component to control the expanded state of the tree view. **Example: controlled-expanded** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' export const ControlledExpanded = () => { const [expandedValue, setExpandedValue] = useState(['node_modules']) return ( setExpandedValue(expandedValue)} > Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For, createSignal } from 'solid-js' import styles from 'styles/tree-view.module.css' export const ControlledExpanded = () => { const [expandedValue, setExpandedValue] = createSignal(['node_modules']) return ( setExpandedValue(expandedValue)} > Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => props.node.children ? ( {nodeState().expanded ? : } {props.node.name} {(child, index) => } ) : ( {props.node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Controlled Selection Pass the `selectedValue` and `onSelectionChange` props to the `TreeView.Root` component to control the selected state of the tree view. **Example: controlled-selected** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' export const ControlledSelected = () => { const [selectedValue, setSelectedValue] = useState(['package.json']) return ( setSelectedValue(selectedValue)} > Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For, createSignal } from 'solid-js' import styles from 'styles/tree-view.module.css' export const ControlledSelected = () => { const [selectedValue, setSelectedValue] = createSignal(['package.json']) return ( setSelectedValue(selectedValue)} > Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => props.node.children ? ( {nodeState().expanded ? : } {props.node.name} {(child, index) => } ) : ( {props.node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Selected: {JSON.stringify(selectedValue)}
                    Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Root Provider An alternative way to control the tree view is to use the `RootProvider` component and the `useTreeView` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { TreeView, createTreeCollection, useTreeView } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import styles from 'styles/tree-view.module.css' export const RootProvider = () => { const treeView = useTreeView({ collection }) return (
                    selected: {JSON.stringify(treeView.selectedValue)} Tree {collection.rootNode.children?.map((node, index) => ( ))}
                    ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection, useTreeView } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For } from 'solid-js' import styles from 'styles/tree-view.module.css' export const RootProvider = () => { const treeView = useTreeView({ collection }) return ( Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => props.node.children ? ( {nodeState().expanded ? : } {props.node.name} {(child, index) => } ) : ( {props.node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Root Provider Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Lazy Loading Lazy loading is a feature that allows the tree view to load children of a node on demand (or async). This helps to improve the initial load time and memory usage. To use this, you need to provide the following: - `loadChildren` — A function that is used to load the children of a node. - `onLoadChildrenComplete` — A callback that is called when the children of a node are loaded. Used to update the tree collection. - `childrenCount` — A number that indicates the number of children of a branch node. **Example: async-loading** #### React ```tsx import { TreeView, createTreeCollection, useTreeViewNodeContext } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon, LoaderIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' // mock api result const response: Record = { node_modules: [ { id: 'zag-js', name: 'zag-js' }, { id: 'pandacss', name: 'panda' }, { id: '@types', name: '@types', childrenCount: 2 }, ], 'node_modules/@types': [ { id: 'react', name: 'react' }, { id: 'react-dom', name: 'react-dom' }, ], src: [ { id: 'app.tsx', name: 'app.tsx' }, { id: 'index.ts', name: 'index.ts' }, ], } // function to load children of a node function loadChildren(details: TreeView.LoadChildrenDetails): Promise { const value = details.valuePath.join('/') return new Promise((resolve) => { setTimeout(() => { resolve(response[value] ?? []) }, 500) }) } export const AsyncLoading = () => { const [collection, setCollection] = useState(initialCollection) return ( setCollection(e.collection)} > Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } function TreeBranchIcon() { const nodeState = useTreeViewNodeContext() if (nodeState.loading) return return nodeState.expanded ? : } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children || node.childrenCount ? ( {node.name} {node.children?.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] childrenCount?: number } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', childrenCount: 3 }, { id: 'src', name: 'src', childrenCount: 2 }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { SquareCheckBigIcon, ChevronRightIcon, FileIcon, FolderIcon, LoaderCircleIcon } from 'lucide-solid' import { For, createSignal } from 'solid-js' import { useTreeViewNodeContext } from '../use-tree-view-node-context' // mock api result const response: Record = { node_modules: [ { id: 'zag-js', name: 'zag-js' }, { id: 'pandacss', name: 'panda' }, { id: '@types', name: '@types', childrenCount: 2 }, ], 'node_modules/@types': [ { id: 'react', name: 'react' }, { id: 'react-dom', name: 'react-dom' }, ], src: [ { id: 'app.tsx', name: 'app.tsx' }, { id: 'index.ts', name: 'index.ts' }, ], } // function to load children of a node function loadChildren(details: TreeView.LoadChildrenDetails): Promise { const value = details.valuePath.join('/') return new Promise((resolve) => { setTimeout(() => { resolve(response[value] ?? []) }, 1200) }) } export const AsyncLoading = () => { const [collection, setCollection] = createSignal(initialCollection) return ( setCollection(e.collection)} > Tree {(node, index) => } ) } function TreeNodeIndicator() { const nodeState = useTreeViewNodeContext() return nodeState().loading ? : } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children || node.childrenCount ? ( {node.name} {(child, index) => } ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] childrenCount?: number } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', childrenCount: 3 }, { id: 'src', name: 'src', childrenCount: 2 }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte (collection = e.collection)} > Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children || node.childrenCount} {#if nodeState().loading} {:else} {/if} {node.name} {#each node.children ?? [] as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Lazy Mount Lazy mounting is a feature that allows the content of a tree view to be rendered only when it is expanded. This is useful for performance optimization, especially when tree content is large or complex. To enable lazy mounting, use the `lazyMount` prop on the `TreeView.Root` component. In addition, the `unmountOnExit` prop can be used in conjunction with `lazyMount` to unmount the tree view content when branches are collapsed, freeing up resources. The next time a branch is expanded, its content will be re-rendered. **Example: lazy-mount** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useTreeViewNodeContext } from '../use-tree-view-node-context' import styles from 'styles/tree-view.module.css' export const LazyMount = () => { return ( Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeBranchIcon = () => { const { expanded } = useTreeViewNodeContext() return expanded ? : } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children ? ( {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { SquareCheckBigIcon, ChevronRightIcon, FileIcon, FolderIcon } from 'lucide-solid' import { For, Show } from 'solid-js' interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) export const LazyMount = () => { return ( Tree {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.name} } > {node.name} {(child, index) => } ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Filtering Filtering is useful when you have a large tree and you want to filter the nodes to only show the ones that match the search query. Here's an example that composes the `filter` method from the `TreeCollection` and `useFilter` hook to filter the nodes. **Example: filtering** #### React ```tsx import { useFilter } from '@ark-ui/react/locale' import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' import fieldStyles from 'styles/field.module.css' export const Filtering = () => { const { contains } = useFilter({ sensitivity: 'base' }) const [collection, setCollection] = useState(initialCollection) const filter = (value: string) => { const filtered = value.length > 0 ? initialCollection.filter((node) => contains(node.name, value)) : initialCollection setCollection(filtered) } return (
                    filter(e.target.value)} /> {collection.rootNode.children?.map((node, index) => ( ))}
                    ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props const tree = useTreeViewContext() const nodeState = tree.getNodeState(props) return ( {nodeState.isBranch ? ( {nodeState.expanded ? : } {node.name} {node.children?.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { useFilter } from '@ark-ui/solid/locale' import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { SquareCheckBigIcon, ChevronRightIcon, FileIcon, FolderIcon } from 'lucide-solid' import { For, Show, createSignal } from 'solid-js' export const Filtering = () => { const filterFn = useFilter({ sensitivity: 'base' }) const [collection, setCollection] = createSignal(initialCollection) const filter = (value: string) => { const filtered = value.length > 0 ? initialCollection.filter((node) => filterFn().contains(node.name, value)) : initialCollection setCollection(filtered) } return (
                    filter(e.currentTarget.value)} /> {(node, index) => }
                    ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.name} } > {node.name} {(child, index) => } ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    filter(e.currentTarget.value)} /> {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each}
                    {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Links Tree items can be rendered as links to another page or website. This could be useful for documentation sites. Here's an example that modifies the tree collection to represent an hierarchical link structure. It uses the `asChild` prop to render the tree items as links, passing the `href` prop to a `
                    ` element. **Example: links** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, ExternalLinkIcon, FileIcon } from 'lucide-react' import styles from 'styles/tree-view.module.css' export const Links = () => { return ( Docs {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children ? ( {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} {node.href?.startsWith('http') && } )} ) } interface Node { id: string name: string href?: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'docs', name: 'Documentation', children: [ { id: 'docs/getting-started', name: 'Getting Started', href: '/docs/getting-started' }, { id: 'docs/installation', name: 'Installation', href: '/docs/installation' }, { id: 'docs/components', name: 'Components', children: [ { id: 'docs/components/accordion', name: 'Accordion', href: '/docs/components/accordion' }, { id: 'docs/components/dialog', name: 'Dialog', href: '/docs/components/dialog' }, { id: 'docs/components/menu', name: 'Menu', href: '/docs/components/menu' }, ], }, ], }, { id: 'examples', name: 'Examples', children: [ { id: 'examples/react', name: 'React Examples', href: '/examples/react' }, { id: 'examples/vue', name: 'Vue Examples', href: '/examples/vue' }, { id: 'examples/solid', name: 'Solid Examples', href: '/examples/solid' }, ], }, { id: 'external', name: 'External Links', children: [ { id: 'external/github', name: 'GitHub Repository', href: 'https://github.com/chakra-ui/zag' }, { id: 'external/npm', name: 'NPM Package', href: 'https://www.npmjs.com/package/@zag-js/core' }, { id: 'external/docs', name: 'Official Docs', href: 'https://zagjs.com' }, ], }, { id: 'readme.md', name: 'README.md', href: '/readme' }, { id: 'license', name: 'LICENSE', href: '/license' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, ExternalLinkIcon, FileIcon } from 'lucide-solid' import { For, Show } from 'solid-js' export const Links = () => { return ( Docs {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( }> {node.name} } > {node.name} {(child, index) => } ) } interface Node { id: string name: string href?: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'docs', name: 'Documentation', children: [ { id: 'docs/getting-started', name: 'Getting Started', href: '/docs/getting-started' }, { id: 'docs/installation', name: 'Installation', href: '/docs/installation' }, { id: 'docs/components', name: 'Components', children: [ { id: 'docs/components/accordion', name: 'Accordion', href: '/docs/components/accordion' }, { id: 'docs/components/dialog', name: 'Dialog', href: '/docs/components/dialog' }, { id: 'docs/components/menu', name: 'Menu', href: '/docs/components/menu' }, ], }, ], }, { id: 'examples', name: 'Examples', children: [ { id: 'examples/react', name: 'React Examples', href: '/examples/react' }, { id: 'examples/vue', name: 'Vue Examples', href: '/examples/vue' }, { id: 'examples/solid', name: 'Solid Examples', href: '/examples/solid' }, ], }, { id: 'external', name: 'External Links', children: [ { id: 'external/github', name: 'GitHub Repository', href: 'https://github.com/chakra-ui/zag' }, { id: 'external/npm', name: 'NPM Package', href: 'https://www.npmjs.com/package/@zag-js/core' }, { id: 'external/docs', name: 'Official Docs', href: 'https://zagjs.com' }, ], }, { id: 'readme.md', name: 'README.md', href: '/readme' }, { id: 'license', name: 'LICENSE', href: '/license' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Docs {#each collection.rootNode.children ?? [] as node, index (node.id)} {/each} ``` ### Virtualized For large tree views with thousands of nodes, virtualization can significantly improve performance by only rendering visible nodes. Key implementation details: - Use `useTreeView` hook with `TreeView.RootProvider` for programmatic control - Pass `scrollToIndexFn` to enable keyboard navigation within the virtualized list - Use `getVisibleNodes()` to get the flattened list of currently visible nodes **Example: virtualized** #### React ```tsx import { TreeView, createTreeCollection, useTreeView } from '@ark-ui/react/tree-view' import { useVirtualizer, type Virtualizer } from '@tanstack/react-virtual' import { ChevronRightIcon, FileIcon, FolderIcon } from 'lucide-react' import { useRef } from 'react' import { flushSync } from 'react-dom' import button from 'styles/button.module.css' import styles from 'styles/tree-view.module.css' interface Node { id: string name: string children?: Node[] } function generateLargeTree(): Node { const folders: Node[] = [] for (let i = 0; i < 50; i++) { const children: Node[] = [] for (let j = 0; j < 20; j++) { children.push({ id: `folder-${i}/file-${i}-${j}.ts`, name: `file-${i}-${j}.ts` }) } folders.push({ id: `folder-${i}`, name: `folder-${i}`, children }) } return { id: 'ROOT', name: '', children: folders, } } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: generateLargeTree(), }) const ROW_HEIGHT = 32 export const Virtualized = () => { const treeRef = useRef(null) const virtualizerRef = useRef | null>(null) const tree = useTreeView({ collection, scrollToIndexFn(details) { flushSync(() => { virtualizerRef.current?.scrollToIndex(details.index, { align: 'auto' }) }) }, }) const visibleNodes = tree.getVisibleNodes() const virtualizer = useVirtualizer({ count: visibleNodes.length, getScrollElement: () => treeRef.current, estimateSize: () => ROW_HEIGHT, overscan: 10, }) virtualizerRef.current = virtualizer return ( Virtualized Tree ({visibleNodes.length} visible nodes)
                    {virtualizer.getVirtualItems().map((virtualItem) => { const { node, indexPath } = visibleNodes[virtualItem.index] const nodeState = tree.getNodeState({ node, indexPath }) return (
                    { if (e.button !== 0) return tree.focus(node.id) }} style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: `${virtualItem.size}px`, transform: `translateY(${virtualItem.start}px)`, }} > {nodeState.isBranch ? ( {node.name} ) : ( {node.name} )}
                    ) })}
                    ) } ``` #### Solid ```tsx import { TreeView, createTreeCollection, useTreeView } from '@ark-ui/solid/tree-view' import { createVirtualizer, type Virtualizer } from '@tanstack/solid-virtual' import { ChevronRightIcon, FileIcon, FolderIcon } from 'lucide-solid' import { For } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tree-view.module.css' interface Node { id: string name: string children?: Node[] } function generateLargeTree(): Node { const folders: Node[] = [] for (let i = 0; i < 50; i++) { const children: Node[] = [] for (let j = 0; j < 20; j++) { children.push({ id: `folder-${i}/file-${i}-${j}.ts`, name: `file-${i}-${j}.ts` }) } folders.push({ id: `folder-${i}`, name: `folder-${i}`, children }) } return { id: 'ROOT', name: '', children: folders, } } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: generateLargeTree(), }) const ROW_HEIGHT = 32 export const Virtualized = () => { let treeRef: HTMLDivElement | undefined let virtualizerRef: Virtualizer | undefined const tree = useTreeView({ collection, scrollToIndexFn(details) { virtualizerRef?.scrollToIndex(details.index, { align: 'auto' }) }, }) const visibleNodes = () => tree().getVisibleNodes() const virtualizer = createVirtualizer({ get count() { return visibleNodes().length }, getScrollElement: () => treeRef ?? null, estimateSize: () => ROW_HEIGHT, overscan: 10, }) virtualizerRef = virtualizer return ( Virtualized Tree ({visibleNodes().length} visible nodes)
                    {(virtualItem) => { const visibleNode = () => visibleNodes()[virtualItem.index] const nodeState = () => tree().getNodeState({ node: visibleNode().node, indexPath: visibleNode().indexPath }) return (
                    { if (e.button !== 0) return tree().focus(visibleNode().node.id) }} style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: `${virtualItem.size}px`, transform: `translateY(${virtualItem.start}px)`, }} > {nodeState().isBranch ? ( {visibleNode().node.name} ) : ( {visibleNode().node.name} )}
                    ) }}
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Virtualized Tree ({visibleNodes.length} visible nodes)
                    {#each $virtualizer.getVirtualItems() as virtualItem (visibleNodes[virtualItem.index].node.id)} {@const visibleNode = visibleNodes[virtualItem.index]} {@const nodeState = tree().getNodeState({ node: visibleNode.node, indexPath: visibleNode.indexPath })}
                    { if (e.button !== 0) return tree().focus(visibleNode.node.id) }} style="position: absolute; top: 0; left: 0; width: 100%; height: {virtualItem.size}px; transform: translateY({virtualItem.start}px);" > {#if nodeState.isBranch} {visibleNode.node.name} {:else} {visibleNode.node.name} {/if}
                    {/each}
                    ``` ### Checkbox Tree Use the `defaultCheckedValue` prop to enable checkbox selection mode. This allows users to select multiple nodes with checkboxes, including parent-child selection relationships. **Example: checkbox-tree** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { CheckIcon, ChevronRightIcon, MinusIcon } from 'lucide-react' import styles from 'styles/tree-view.module.css' export const CheckboxTree = () => { return ( Tree {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNodeCheckbox = (props: TreeView.NodeCheckboxProps) => { return ( }> ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children ? ( {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { SquareCheckBigIcon, ChevronRightIcon, SquareMinusIcon, SquareIcon } from 'lucide-solid' import { For } from 'solid-js' export const CheckboxTree = () => { return ( Tree {(node, index) => } ) } const TreeNodeCheckbox = () => { return ( } fallback={}> ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {node.children ? ( {node.name} {(child, index) => } ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] | undefined } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte Tree {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet treeNodeCheckbox()} {#snippet indeterminate()} {/snippet} {#snippet fallback()} {/snippet} {/snippet} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#if node.children} {@render treeNodeCheckbox()} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {@render treeNodeCheckbox()} {node.name} {/if} {/snippet} ``` ### Expand and Collapse All Use the `expand()` and `collapse()` methods from the tree view context to programmatically expand or collapse all branches. **Example: expand-collapse-all** #### React ```tsx import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useMemo } from 'react' import button from 'styles/button.module.css' import styles from 'styles/tree-view.module.css' const ExpandCollapseButtons = () => { const tree = useTreeViewContext() const branchValues = useMemo(() => tree.collection.getBranchValues(), [tree.collection]) const isAllExpanded = useMemo( () => branchValues.every((value) => tree.expandedValue.includes(value)), [tree.expandedValue, branchValues], ) return (
                    {isAllExpanded ? ( ) : ( )}
                    ) } export const ExpandCollapseAll = () => { return ( {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.expanded ? : } {node.name} {node.children.map((child, index) => ( ))} ) : ( {node.name} ) } ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For, Show, createMemo } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/tree-view.module.css' const ExpandCollapseButtons = () => { const tree = useTreeViewContext() const branchValues = createMemo(() => tree().collection.getBranchValues()) const isAllExpanded = createMemo(() => branchValues().every((value) => tree().expandedValue.includes(value))) return (
                    tree().expand()}> Expand all } >
                    ) } export const ExpandCollapseAll = () => { return ( {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => ( {props.node.name} } > }> {props.node.name} {(child, index) => } )} ) } interface Node { id: string name: string children?: Node[] } const collection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tree)}
                    {#if branchValues.every((value) => tree().expandedValue.includes(value))} {:else} {/if}
                    {/snippet}
                    {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each}
                    {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().expanded} {:else} {/if} {node.name} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {node.name} {/if} {/snippet} {/snippet} ``` ### Mutation Use the collection's `remove()` and `replace()` methods to dynamically add and remove nodes from the tree. This is useful for building file explorer interfaces where users can create and delete files. **Example: mutation** #### React ```tsx import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/react/tree-view' import { ChevronRightIcon, PlusIcon, TrashIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' export const Mutation = () => { const [collection, setCollection] = useState(initialCollection) const removeNode = (props: TreeNodeProps) => { setCollection(collection.remove([props.indexPath])) } const addNode = (props: TreeNodeProps) => { const { node, indexPath } = props if (!collection.isBranchNode(node)) return const children = [{ id: `untitled-${Date.now()}`, name: 'untitled.tsx' }, ...(node.children || [])] setCollection(collection.replace(indexPath, { ...node, children })) } return ( {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNodeActions = (props: TreeNodeProps) => { const { onRemove, onAdd, node } = props const tree = useTreeViewContext() const isBranch = tree.collection.isBranchNode(node) return (
                    {isBranch && ( )}
                    ) } interface TreeNodeProps extends TreeView.NodeProviderProps { onRemove?: (props: TreeView.NodeProviderProps) => void onAdd?: (props: TreeView.NodeProviderProps) => void } const TreeNode = (props: TreeNodeProps) => { const { node, indexPath } = props const tree = useTreeViewContext() const nodeState = tree.getNodeState(props) return ( {nodeState.isBranch ? ( {node.name} {node.children?.map((child, index) => ( ))} ) : ( {node.name} )} ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection, useTreeViewContext } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, PlusIcon, TrashIcon } from 'lucide-solid' import { For, Show, createSignal } from 'solid-js' import styles from 'styles/tree-view.module.css' export const Mutation = () => { const [collection, setCollection] = createSignal(initialCollection) const removeNode = (props: TreeNodeProps) => { setCollection((prev) => prev.remove([props.indexPath])) } const addNode = (props: TreeNodeProps) => { const { node, indexPath } = props const col = collection() if (!col.isBranchNode(node)) return const children = [{ id: `untitled-${Date.now()}`, name: 'untitled.tsx' }, ...(node.children || [])] setCollection(col.replace(indexPath, { ...node, children })) } return ( {(node, index) => } ) } const TreeNodeActions = (props: TreeNodeProps) => { const tree = useTreeViewContext() const isBranch = () => tree().collection.isBranchNode(props.node) return (
                    ) } interface TreeNodeProps extends TreeView.NodeProviderProps { onRemove?: (props: TreeView.NodeProviderProps) => void onAdd?: (props: TreeView.NodeProviderProps) => void } const TreeNode = (props: TreeNodeProps) => { const tree = useTreeViewContext() const nodeState = () => tree().getNodeState(props) return ( {props.node.name} } > {props.node.name} {(child, index) => ( )} ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(tree)} {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index], tree)} {/each} {/snippet} {#snippet renderNode(node: TreeNode, indexPath: number[], tree: any)} {#if node.children} {node.name}
                    {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index], tree)} {/each}
                    {:else} {node.name}
                    {/if}
                    {/snippet} ``` ### Rename Node Enable inline renaming of nodes using the `canRename` prop and `onRenameComplete` callback. Press F2 to activate rename mode on the focused node. **Example: rename-node** #### React ```tsx import { TreeView, createTreeCollection } from '@ark-ui/react/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react' import { useState } from 'react' import styles from 'styles/tree-view.module.css' export const RenameNode = () => { const [collection, setCollection] = useState(initialCollection) return ( true} onRenameComplete={(details) => { setCollection((prev) => { const node = prev.at(details.indexPath) if (!node) return prev return prev.replace(details.indexPath, { ...node, name: details.label }) }) }} > Tree (Press F2 to rename) {collection.rootNode.children?.map((node, index) => ( ))} ) } const TreeNode = (props: TreeView.NodeProviderProps) => { const { node, indexPath } = props return ( {(nodeState) => node.children ? ( {nodeState.renaming ? ( ) : ( {nodeState.expanded ? : } {node.name} )} {node.children.map((child, index) => ( ))} ) : ( {nodeState.renaming ? ( ) : ( {node.name} )} ) } ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Solid ```tsx import { TreeView, createTreeCollection } from '@ark-ui/solid/tree-view' import { ChevronRightIcon, FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-solid' import { For, Show, createSignal } from 'solid-js' import styles from 'styles/tree-view.module.css' export const RenameNode = () => { const [collection, setCollection] = createSignal(initialCollection) return ( true} onRenameComplete={(details) => { setCollection((prev) => { const node = prev.at(details.indexPath) if (!node) return prev return prev.replace(details.indexPath, { ...node, name: details.label }) }) }} > Tree (Press F2 to rename) {(node, index) => } ) } const TreeNode = (props: TreeView.NodeProviderProps) => { return ( {(nodeState) => ( {props.node.name}} > } > }> {props.node.name} } > {(child, index) => } )} ) } interface Node { id: string name: string children?: Node[] } const initialCollection = createTreeCollection({ nodeToValue: (node) => node.id, nodeToString: (node) => node.name, rootNode: { id: 'ROOT', name: '', children: [ { id: 'node_modules', name: 'node_modules', children: [ { id: 'node_modules/zag-js', name: 'zag-js' }, { id: 'node_modules/pandacss', name: 'panda' }, { id: 'node_modules/@types', name: '@types', children: [ { id: 'node_modules/@types/react', name: 'react' }, { id: 'node_modules/@types/react-dom', name: 'react-dom' }, ], }, ], }, { id: 'src', name: 'src', children: [ { id: 'src/app.tsx', name: 'app.tsx' }, { id: 'src/index.ts', name: 'index.ts' }, ], }, { id: 'panda.config', name: 'panda.config.ts' }, { id: 'package.json', name: 'package.json' }, { id: 'renovate.json', name: 'renovate.json' }, { id: 'readme.md', name: 'README.md' }, ], }, }) ``` #### Vue ```vue ``` #### Svelte ```svelte true} onRenameComplete={handleRenameComplete}> Tree (Press F2 to rename) {#each collection.rootNode.children ?? [] as node, index (node.id)} {@render renderNode(node, [index])} {/each} {#snippet renderNode(node: TreeNode, indexPath: number[])} {#snippet render(nodeState)} {#if node.children} {#if nodeState().renaming} {:else} {#if nodeState().expanded} {:else} {/if} {node.name} {/if} {#each node.children as child, index (child.id)} {@render renderNode(child, [...indexPath, index])} {/each} {:else} {#if nodeState().renaming} {:else} {node.name} {/if} {/if} {/snippet} {/snippet} ``` ## Guides ### Type Safety The `TreeView.RootComponent` type enables you to create typed wrapper components that maintain full type safety for tree nodes. ```tsx import { TreeView as ArkTreeView } from '@ark-ui/react/tree-view' const TreeView: ArkTreeView.RootComponent = (props) => { return {/* ... */} } ``` Use the wrapper with full type inference on `onSelectionChange` and other callbacks: ```tsx const App = () => { const collection = createTreeCollection({ initialItems: [ { id: '1', label: 'React', children: [] }, { id: '2', label: 'Vue', children: [] }, ], }) return ( { // e.items is typed as Array<{ id: string, label: string, children: [] }> console.log(e.items) }} > {/* ... */} ) } ``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `TreeCollection` | Yes | The collection of tree nodes | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: T, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails) => void` | No | Called when the selection changes | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'multiple' | 'single'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **BranchContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-content | | `[data-state]` | "open" | "closed" | | `[data-depth]` | The depth of the item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | **BranchControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-control | | `[data-path]` | The path of the item | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-renaming]` | | | `[data-value]` | The value of the item | | `[data-depth]` | The depth of the item | | `[data-loading]` | Present when loading | **BranchIndentGuide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndentGuide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indent-guide | | `[data-depth]` | The depth of the item | **BranchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-loading]` | Present when loading | **Branch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Branch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch | | `[data-depth]` | The depth of the item | | `[data-branch]` | | | `[data-value]` | The value of the item | | `[data-path]` | The path of the item | | `[data-selected]` | Present when selected | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-loading]` | Present when loading | **Branch CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Branch | **BranchText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-text | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-loading]` | Present when loading | **BranchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-trigger | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-value]` | The value of the item | | `[data-loading]` | Present when loading | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | | `[data-focus]` | Present when focused | | `[data-selected]` | Present when selected | | `[data-disabled]` | Present when disabled | | `[data-renaming]` | | | `[data-depth]` | The depth of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckboxIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | | | `indeterminate` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | | **NodeCheckbox Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckbox Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | node-checkbox | | `[data-state]` | "checked" | "unchecked" | "indeterminate" | | `[data-disabled]` | Present when disabled | **NodeProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `indexPath` | `number[]` | Yes | The index path of the tree node | | `node` | `NonNullable` | No | The tree node | **NodeRenameInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Tree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `TreeCollection` | Yes | The collection of tree nodes | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: any, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails) => void` | No | Called when the selection changes | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'multiple' | 'single'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **BranchContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-content | | `[data-state]` | "open" | "closed" | | `[data-depth]` | The depth of the item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | **BranchControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-control | | `[data-path]` | The path of the item | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-renaming]` | | | `[data-value]` | The value of the item | | `[data-depth]` | The depth of the item | | `[data-loading]` | Present when loading | **BranchIndentGuide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndentGuide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indent-guide | | `[data-depth]` | The depth of the item | **BranchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-loading]` | Present when loading | **Branch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Branch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch | | `[data-depth]` | The depth of the item | | `[data-branch]` | | | `[data-value]` | The value of the item | | `[data-path]` | The path of the item | | `[data-selected]` | Present when selected | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-loading]` | Present when loading | **Branch CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Branch | **BranchText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-text | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-loading]` | Present when loading | **BranchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-trigger | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-value]` | The value of the item | | `[data-loading]` | Present when loading | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | | `[data-focus]` | Present when focused | | `[data-selected]` | Present when selected | | `[data-disabled]` | Present when disabled | | `[data-renaming]` | | | `[data-depth]` | The depth of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'h3'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckboxIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `number | boolean | Node | (string & {}) | ArrayElement` | No | | | `indeterminate` | `number | boolean | Node | (string & {}) | ArrayElement` | No | | **NodeCheckbox Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'span'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckbox Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | node-checkbox | | `[data-state]` | "checked" | "unchecked" | "indeterminate" | | `[data-disabled]` | Present when disabled | **NodeProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `indexPath` | `number[]` | Yes | The index path of the tree node | | `node` | `NonNullable` | No | The tree node | **NodeRenameInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'input'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Tree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `collection` | `TreeCollection` | Yes | The collection of tree nodes | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: T, indexPath: number[]) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node values | | `defaultCheckedValue` | `string[]` | No | The initial checked node values when rendered. Use when you don't need to control the checked node values. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node values when rendered. Use when you don't need to control the expanded node values. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node values when rendered. Use when you don't need to control the selected node values. | | `expandedValue` | `string[]` | No | The controlled expanded node values | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The id of the focused node | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node(value: string): string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | A function that loads the children of a node. | | `selectedValue` | `string[]` | No | The controlled selected node values | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **BranchContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-content | | `[data-state]` | "open" | "closed" | | `[data-depth]` | The depth of the item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | **BranchControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-control | | `[data-path]` | The path of the item | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-renaming]` | | | `[data-value]` | The value of the item | | `[data-depth]` | The depth of the item | | `[data-loading]` | Present when loading | **BranchIndentGuide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndentGuide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indent-guide | | `[data-depth]` | The depth of the item | **BranchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-loading]` | Present when loading | **Branch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Branch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch | | `[data-depth]` | The depth of the item | | `[data-branch]` | | | `[data-value]` | The value of the item | | `[data-path]` | The path of the item | | `[data-selected]` | Present when selected | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-loading]` | Present when loading | **Branch CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Branch | **BranchText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-text | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-loading]` | Present when loading | **BranchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **BranchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-trigger | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-value]` | The value of the item | | `[data-loading]` | Present when loading | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | | `[data-focus]` | Present when focused | | `[data-selected]` | Present when selected | | `[data-disabled]` | Present when disabled | | `[data-renaming]` | | | `[data-depth]` | The depth of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckboxIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `{}` | No | | | `indeterminate` | `{}` | No | | **NodeCheckbox Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **NodeCheckbox Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | node-checkbox | | `[data-state]` | "checked" | "unchecked" | "indeterminate" | | `[data-disabled]` | Present when disabled | **NodeProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `indexPath` | `number[]` | Yes | The index path of the tree node | | `node` | `NonNullable` | No | The tree node | **NodeRenameInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TreeViewApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Tree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: T, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `collection` | `TreeCollection` | No | The tree collection data | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails) => void` | No | Called when the selection changes | | `ref` | `Element` | No | | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'multiple' | 'single'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **BranchContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'ul'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-content | | `[data-state]` | "open" | "closed" | | `[data-depth]` | The depth of the item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | **BranchControl Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchControl Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-control | | `[data-path]` | The path of the item | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-renaming]` | | | `[data-value]` | The value of the item | | `[data-depth]` | The depth of the item | | `[data-loading]` | Present when loading | **BranchIndentGuide Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchIndentGuide Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indent-guide | | `[data-depth]` | The depth of the item | **BranchIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | | `[data-loading]` | Present when loading | **Branch Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'li'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Branch Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch | | `[data-depth]` | The depth of the item | | `[data-branch]` | | | `[data-value]` | The value of the item | | `[data-path]` | The path of the item | | `[data-selected]` | Present when selected | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-loading]` | Present when loading | **Branch CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Branch | **BranchText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-text | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-loading]` | Present when loading | **BranchTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **BranchTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | branch-trigger | | `[data-disabled]` | Present when disabled | | `[data-state]` | "open" | "closed" | | `[data-value]` | The value of the item | | `[data-loading]` | Present when loading | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTreeViewContext]>` | Yes | | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-indicator | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'li'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item | | `[data-path]` | The path of the item | | `[data-value]` | The value of the item | | `[data-focus]` | Present when focused | | `[data-selected]` | Present when selected | | `[data-disabled]` | Present when disabled | | `[data-renaming]` | | | `[data-depth]` | The depth of the item | **Item CSS Variables:** | Variable | Description | |----------|-------------| | `--depth` | The depth value for the Item | **ItemText Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **ItemText Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | item-text | | `[data-disabled]` | Present when disabled | | `[data-selected]` | Present when selected | | `[data-focus]` | Present when focused | **Label Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'h3'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NodeCheckboxIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `Snippet<[]>` | No | | | `indeterminate` | `Snippet<[]>` | No | | **NodeCheckbox Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'span'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NodeCheckbox Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | tree-view | | `[data-part]` | node-checkbox | | `[data-state]` | "checked" | "unchecked" | "indeterminate" | | `[data-disabled]` | Present when disabled | **NodeContext Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseTreeViewNodeContext]>` | Yes | | **NodeProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `indexPath` | `number[]` | Yes | | | `node` | `NonNullable` | No | | **NodeRenameInput Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'input'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **Tree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'ul'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `collection` | `TreeCollection` | The tree collection data | | `expandedValue` | `string[]` | The value of the expanded nodes. | | `setExpandedValue` | `(value: string[]) => void` | Sets the expanded value | | `selectedValue` | `string[]` | The value of the selected nodes. | | `setSelectedValue` | `(value: string[]) => void` | Sets the selected value | | `checkedValue` | `string[]` | The value of the checked nodes | | `toggleChecked` | `(value: string, isBranch: boolean) => void` | Toggles the checked value of a node | | `setChecked` | `(value: string[]) => void` | Sets the checked value of a node | | `clearChecked` | `VoidFunction` | Clears the checked value of a node | | `getCheckedMap` | `() => CheckedValueMap` | Returns the checked details of branch and leaf nodes | | `getVisibleNodes` | `() => V[]` | Returns the visible nodes as a flat array of nodes and their index path | | `expand` | `(value?: string[]) => void` | Function to expand nodes. If no value is provided, all nodes will be expanded | | `collapse` | `(value?: string[]) => void` | Function to collapse nodes If no value is provided, all nodes will be collapsed | | `select` | `(value?: string[]) => void` | Function to select nodes If no value is provided, all nodes will be selected | | `deselect` | `(value?: string[]) => void` | Function to deselect nodes If no value is provided, all nodes will be deselected | | `focus` | `(value: string) => void` | Function to focus a node by value | | `selectParent` | `(value: string) => void` | Function to select the parent node of the focused node | | `expandParent` | `(value: string) => void` | Function to expand the parent node of the focused node | | `startRenaming` | `(value: string) => void` | Function to start renaming a node by value | | `submitRenaming` | `(value: string, label: string) => void` | Function to submit the rename and update the node label | | `cancelRenaming` | `() => void` | Function to cancel renaming without changes | ## Accessibility Complies with the [Tree View WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/). ### Keyboard Support **`Tab`** Description: Moves focus to the tree view, placing the first tree view item in focus. **`Enter + Space`** Description: Selects the item or branch node **`ArrowDown`** Description: Moves focus to the next node **`ArrowUp`** Description: Moves focus to the previous node **`ArrowRight`** Description: When focus is on a closed branch node, opens the branch.
                    When focus is on an open branch node, moves focus to the first item node. **`ArrowLeft`** Description: When focus is on an open branch node, closes the node.
                    When focus is on an item or branch node, moves focus to its parent branch node. **`Home`** Description: Moves focus to first node without opening or closing a node. **`End`** Description: Moves focus to the last node that can be focused without expanding any nodes that are closed. **`a-z + A-Z`** Description: Focus moves to the next node with a name that starts with the typed character. The search logic ignores nodes that are descendants of closed branch. **`*`** Description: Expands all sibling nodes that are at the same depth as the focused node. **`Shift + ArrowDown`** Description: Moves focus to and toggles the selection state of the next node. **`Shift + ArrowUp`** Description: Moves focus to and toggles the selection state of the previous node. **`Ctrl + A`** Description: Selects all nodes in the tree. If all nodes are selected, unselects all nodes. --- # Client Only (REACT) ## Motivation The `ClientOnly` component renders its children only on the client side. This is useful for components that need to access the DOM or browser APIs that are not available on the server side. ## Examples ### Basic **Example: basic** #### React ```tsx import { ClientOnly } from '@ark-ui/react/client-only' export const Basic = () => (
                    This content is only rendered on the client side.
                    ) ``` #### Solid ```tsx import { ClientOnly } from '@ark-ui/solid/client-only' export const Basic = () => (
                    This content is only rendered on the client side.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    This content is only rendered on the client side.
                    ``` ### With Fallback **Example: with-fallback** #### React ```tsx import { ClientOnly } from '@ark-ui/react/client-only' export const WithFallback = () => ( Loading...
                    }>
                    This content is only rendered on the client side.
                    ) ``` #### Solid ```tsx import { ClientOnly } from '@ark-ui/solid/client-only' export const WithFallback = () => ( Loading...
                    }>
                    This content is only rendered on the client side.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet fallback()}
                    Loading...
                    {/snippet}
                    This content is only rendered on the client side.
                    ``` ## API Reference **Component API Reference** #### React **ClientOnly Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `any` | No | | #### Solid **ClientOnly Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `number | boolean | Node | ArrayElement | (string & {})` | No | | #### Svelte **ClientOnly Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `Snippet<[]>` | No | | --- # Client Only (VUE) ## Motivation The `ClientOnly` component renders its children only on the client side. This is useful for components that need to access the DOM or browser APIs that are not available on the server side. ## Examples ### Basic **Example: basic** #### React ```tsx import { ClientOnly } from '@ark-ui/react/client-only' export const Basic = () => (
                    This content is only rendered on the client side.
                    ) ``` #### Solid ```tsx import { ClientOnly } from '@ark-ui/solid/client-only' export const Basic = () => (
                    This content is only rendered on the client side.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    This content is only rendered on the client side.
                    ``` ### With Fallback **Example: with-fallback** #### React ```tsx import { ClientOnly } from '@ark-ui/react/client-only' export const WithFallback = () => ( Loading...
                    }>
                    This content is only rendered on the client side.
                    ) ``` #### Solid ```tsx import { ClientOnly } from '@ark-ui/solid/client-only' export const WithFallback = () => ( Loading...
                    }>
                    This content is only rendered on the client side.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet fallback()}
                    Loading...
                    {/snippet}
                    This content is only rendered on the client side.
                    ``` ## API Reference **Component API Reference** #### React **ClientOnly Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `any` | No | | #### Solid **ClientOnly Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `number | boolean | Node | ArrayElement | (string & {})` | No | | #### Svelte **ClientOnly Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `Snippet<[]>` | No | | --- # Client Only (SVELTE) ## Motivation The `ClientOnly` component renders its children only on the client side. This is useful for components that need to access the DOM or browser APIs that are not available on the server side. ## Examples ### Basic **Example: basic** #### React ```tsx import { ClientOnly } from '@ark-ui/react/client-only' export const Basic = () => (
                    This content is only rendered on the client side.
                    ) ``` #### Solid ```tsx import { ClientOnly } from '@ark-ui/solid/client-only' export const Basic = () => (
                    This content is only rendered on the client side.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    This content is only rendered on the client side.
                    ``` ### With Fallback **Example: with-fallback** #### React ```tsx import { ClientOnly } from '@ark-ui/react/client-only' export const WithFallback = () => ( Loading...
                    }>
                    This content is only rendered on the client side.
                    ) ``` #### Solid ```tsx import { ClientOnly } from '@ark-ui/solid/client-only' export const WithFallback = () => ( Loading...
                    }>
                    This content is only rendered on the client side.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet fallback()}
                    Loading...
                    {/snippet}
                    This content is only rendered on the client side.
                    ``` ## API Reference **Component API Reference** #### React **ClientOnly Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `any` | No | | #### Solid **ClientOnly Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `number | boolean | Node | ArrayElement | (string & {})` | No | | #### Svelte **ClientOnly Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `Snippet<[]>` | No | | --- # Client Only (SOLID) ## Motivation The `ClientOnly` component renders its children only on the client side. This is useful for components that need to access the DOM or browser APIs that are not available on the server side. ## Examples ### Basic **Example: basic** #### React ```tsx import { ClientOnly } from '@ark-ui/react/client-only' export const Basic = () => (
                    This content is only rendered on the client side.
                    ) ``` #### Solid ```tsx import { ClientOnly } from '@ark-ui/solid/client-only' export const Basic = () => (
                    This content is only rendered on the client side.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    This content is only rendered on the client side.
                    ``` ### With Fallback **Example: with-fallback** #### React ```tsx import { ClientOnly } from '@ark-ui/react/client-only' export const WithFallback = () => ( Loading...
                    }>
                    This content is only rendered on the client side.
                    ) ``` #### Solid ```tsx import { ClientOnly } from '@ark-ui/solid/client-only' export const WithFallback = () => ( Loading...
                    }>
                    This content is only rendered on the client side.
                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet fallback()}
                    Loading...
                    {/snippet}
                    This content is only rendered on the client side.
                    ``` ## API Reference **Component API Reference** #### React **ClientOnly Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `any` | No | | #### Solid **ClientOnly Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `number | boolean | Node | ArrayElement | (string & {})` | No | | #### Svelte **ClientOnly Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `fallback` | `Snippet<[]>` | No | | --- # Download Trigger (REACT) ## Motivation The `DownloadTrigger` component provides a convenient way to programmatically trigger file downloads in web applications. It handles the complexities of downloading files, whether they are URLs, Blobs, or other data types. ## Examples ### Basic Pass the data you want to download to the `data` prop, and specify the `fileName` and `mimeType` of the file. **Example: basic** #### React ```tsx import { DownloadTrigger } from '@ark-ui/react/download-trigger' import { DownloadIcon, FileIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' const content = 'Hello, World! This is a sample text file.' export const Basic = () => { return (
                    {content}
                    Download txt
                    ) } ``` #### Solid ```tsx import { DownloadTrigger } from '@ark-ui/solid/download-trigger' import { DownloadIcon, FileIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' const content = 'Hello, World! This is a sample text file.' export const Basic = () => { return (
                    {content}
                    Download txt
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {content}
                    Download txt
                    ``` ### Download SVG Here's an example of how to download an SVG file. **Example: svg** #### React ```tsx import { DownloadTrigger } from '@ark-ui/react/download-trigger' import { DownloadIcon, FileIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' const svgContent = ` ` export const Svg = () => { return (
                    circle.svg
                    Download SVG
                    ) } ``` #### Solid ```tsx import { DownloadTrigger } from '@ark-ui/solid/download-trigger' import { DownloadIcon, FileIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' const svgContent = ` ` export const Svg = () => { return (
                    circle.svg
                    Download SVG
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    circle.svg
                    Download SVG
                    ``` ### Promise You can also trigger downloads from a promise that returns a `Blob`, `File`, or `string`. **Example: with-promise** #### React ```tsx import { DownloadTrigger } from '@ark-ui/react/download-trigger' import { DownloadIcon, ImageIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' export const WithPromise = () => { const fetchImage = async () => { const response = await fetch('https://picsum.photos/200/300') return response.blob() } return (
                    random-image.jpg (fetched on download)
                    Download Image
                    ) } ``` #### Solid ```tsx import { DownloadTrigger } from '@ark-ui/solid/download-trigger' import { DownloadIcon, ImageIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' export const WithPromise = () => { const fetchImage = async () => { const response = await fetch('https://picsum.photos/200/300') return response.blob() } return (
                    random-image.jpg (fetched on download)
                    Download Image
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    random-image.jpg (fetched on download)
                    Download Image
                    ``` ## API Reference **Component API Reference** #### React **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `DownloadableData | (() => MaybePromise)` | Yes | The data to download | | `fileName` | `string` | Yes | The name of the file to download | | `mimeType` | `FileMimeType` | Yes | The MIME type of the data to download | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `DownloadableData | (() => MaybePromise)` | Yes | The data to download | | `fileName` | `string` | Yes | The name of the file to download | | `mimeType` | `FileMimeType` | Yes | The MIME type of the data to download | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `DownloadableData | (() => MaybePromise)` | Yes | The data to download | | `fileName` | `string` | Yes | The name of the file to download | | `mimeType` | `FileMimeType` | Yes | The MIME type of the data to download | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `DownloadableData | (() => MaybePromise)` | Yes | | | `fileName` | `string` | Yes | | | `mimeType` | `FileMimeType` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | --- # Download Trigger (VUE) ## Motivation The `DownloadTrigger` component provides a convenient way to programmatically trigger file downloads in web applications. It handles the complexities of downloading files, whether they are URLs, Blobs, or other data types. ## Examples ### Basic Pass the data you want to download to the `data` prop, and specify the `fileName` and `mimeType` of the file. **Example: basic** #### React ```tsx import { DownloadTrigger } from '@ark-ui/react/download-trigger' import { DownloadIcon, FileIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' const content = 'Hello, World! This is a sample text file.' export const Basic = () => { return (
                    {content}
                    Download txt
                    ) } ``` #### Solid ```tsx import { DownloadTrigger } from '@ark-ui/solid/download-trigger' import { DownloadIcon, FileIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' const content = 'Hello, World! This is a sample text file.' export const Basic = () => { return (
                    {content}
                    Download txt
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {content}
                    Download txt
                    ``` ### Download SVG Here's an example of how to download an SVG file. **Example: svg** #### React ```tsx import { DownloadTrigger } from '@ark-ui/react/download-trigger' import { DownloadIcon, FileIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' const svgContent = ` ` export const Svg = () => { return (
                    circle.svg
                    Download SVG
                    ) } ``` #### Solid ```tsx import { DownloadTrigger } from '@ark-ui/solid/download-trigger' import { DownloadIcon, FileIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' const svgContent = ` ` export const Svg = () => { return (
                    circle.svg
                    Download SVG
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    circle.svg
                    Download SVG
                    ``` ### Promise You can also trigger downloads from a promise that returns a `Blob`, `File`, or `string`. **Example: with-promise** #### React ```tsx import { DownloadTrigger } from '@ark-ui/react/download-trigger' import { DownloadIcon, ImageIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' export const WithPromise = () => { const fetchImage = async () => { const response = await fetch('https://picsum.photos/200/300') return response.blob() } return (
                    random-image.jpg (fetched on download)
                    Download Image
                    ) } ``` #### Solid ```tsx import { DownloadTrigger } from '@ark-ui/solid/download-trigger' import { DownloadIcon, ImageIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' export const WithPromise = () => { const fetchImage = async () => { const response = await fetch('https://picsum.photos/200/300') return response.blob() } return (
                    random-image.jpg (fetched on download)
                    Download Image
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    random-image.jpg (fetched on download)
                    Download Image
                    ``` ## API Reference **Component API Reference** #### React **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `DownloadableData | (() => MaybePromise)` | Yes | The data to download | | `fileName` | `string` | Yes | The name of the file to download | | `mimeType` | `FileMimeType` | Yes | The MIME type of the data to download | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `DownloadableData | (() => MaybePromise)` | Yes | The data to download | | `fileName` | `string` | Yes | The name of the file to download | | `mimeType` | `FileMimeType` | Yes | The MIME type of the data to download | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `DownloadableData | (() => MaybePromise)` | Yes | The data to download | | `fileName` | `string` | Yes | The name of the file to download | | `mimeType` | `FileMimeType` | Yes | The MIME type of the data to download | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `DownloadableData | (() => MaybePromise)` | Yes | | | `fileName` | `string` | Yes | | | `mimeType` | `FileMimeType` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | --- # Download Trigger (SVELTE) ## Motivation The `DownloadTrigger` component provides a convenient way to programmatically trigger file downloads in web applications. It handles the complexities of downloading files, whether they are URLs, Blobs, or other data types. ## Examples ### Basic Pass the data you want to download to the `data` prop, and specify the `fileName` and `mimeType` of the file. **Example: basic** #### React ```tsx import { DownloadTrigger } from '@ark-ui/react/download-trigger' import { DownloadIcon, FileIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' const content = 'Hello, World! This is a sample text file.' export const Basic = () => { return (
                    {content}
                    Download txt
                    ) } ``` #### Solid ```tsx import { DownloadTrigger } from '@ark-ui/solid/download-trigger' import { DownloadIcon, FileIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' const content = 'Hello, World! This is a sample text file.' export const Basic = () => { return (
                    {content}
                    Download txt
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {content}
                    Download txt
                    ``` ### Download SVG Here's an example of how to download an SVG file. **Example: svg** #### React ```tsx import { DownloadTrigger } from '@ark-ui/react/download-trigger' import { DownloadIcon, FileIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' const svgContent = ` ` export const Svg = () => { return (
                    circle.svg
                    Download SVG
                    ) } ``` #### Solid ```tsx import { DownloadTrigger } from '@ark-ui/solid/download-trigger' import { DownloadIcon, FileIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' const svgContent = ` ` export const Svg = () => { return (
                    circle.svg
                    Download SVG
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    circle.svg
                    Download SVG
                    ``` ### Promise You can also trigger downloads from a promise that returns a `Blob`, `File`, or `string`. **Example: with-promise** #### React ```tsx import { DownloadTrigger } from '@ark-ui/react/download-trigger' import { DownloadIcon, ImageIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' export const WithPromise = () => { const fetchImage = async () => { const response = await fetch('https://picsum.photos/200/300') return response.blob() } return (
                    random-image.jpg (fetched on download)
                    Download Image
                    ) } ``` #### Solid ```tsx import { DownloadTrigger } from '@ark-ui/solid/download-trigger' import { DownloadIcon, ImageIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' export const WithPromise = () => { const fetchImage = async () => { const response = await fetch('https://picsum.photos/200/300') return response.blob() } return (
                    random-image.jpg (fetched on download)
                    Download Image
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    random-image.jpg (fetched on download)
                    Download Image
                    ``` ## API Reference **Component API Reference** #### React **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `DownloadableData | (() => MaybePromise)` | Yes | The data to download | | `fileName` | `string` | Yes | The name of the file to download | | `mimeType` | `FileMimeType` | Yes | The MIME type of the data to download | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `DownloadableData | (() => MaybePromise)` | Yes | The data to download | | `fileName` | `string` | Yes | The name of the file to download | | `mimeType` | `FileMimeType` | Yes | The MIME type of the data to download | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `DownloadableData | (() => MaybePromise)` | Yes | The data to download | | `fileName` | `string` | Yes | The name of the file to download | | `mimeType` | `FileMimeType` | Yes | The MIME type of the data to download | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `DownloadableData | (() => MaybePromise)` | Yes | | | `fileName` | `string` | Yes | | | `mimeType` | `FileMimeType` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | --- # Download Trigger (SOLID) ## Motivation The `DownloadTrigger` component provides a convenient way to programmatically trigger file downloads in web applications. It handles the complexities of downloading files, whether they are URLs, Blobs, or other data types. ## Examples ### Basic Pass the data you want to download to the `data` prop, and specify the `fileName` and `mimeType` of the file. **Example: basic** #### React ```tsx import { DownloadTrigger } from '@ark-ui/react/download-trigger' import { DownloadIcon, FileIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' const content = 'Hello, World! This is a sample text file.' export const Basic = () => { return (
                    {content}
                    Download txt
                    ) } ``` #### Solid ```tsx import { DownloadTrigger } from '@ark-ui/solid/download-trigger' import { DownloadIcon, FileIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' const content = 'Hello, World! This is a sample text file.' export const Basic = () => { return (
                    {content}
                    Download txt
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {content}
                    Download txt
                    ``` ### Download SVG Here's an example of how to download an SVG file. **Example: svg** #### React ```tsx import { DownloadTrigger } from '@ark-ui/react/download-trigger' import { DownloadIcon, FileIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' const svgContent = ` ` export const Svg = () => { return (
                    circle.svg
                    Download SVG
                    ) } ``` #### Solid ```tsx import { DownloadTrigger } from '@ark-ui/solid/download-trigger' import { DownloadIcon, FileIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' const svgContent = ` ` export const Svg = () => { return (
                    circle.svg
                    Download SVG
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    circle.svg
                    Download SVG
                    ``` ### Promise You can also trigger downloads from a promise that returns a `Blob`, `File`, or `string`. **Example: with-promise** #### React ```tsx import { DownloadTrigger } from '@ark-ui/react/download-trigger' import { DownloadIcon, ImageIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' export const WithPromise = () => { const fetchImage = async () => { const response = await fetch('https://picsum.photos/200/300') return response.blob() } return (
                    random-image.jpg (fetched on download)
                    Download Image
                    ) } ``` #### Solid ```tsx import { DownloadTrigger } from '@ark-ui/solid/download-trigger' import { DownloadIcon, ImageIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/download-trigger.module.css' export const WithPromise = () => { const fetchImage = async () => { const response = await fetch('https://picsum.photos/200/300') return response.blob() } return (
                    random-image.jpg (fetched on download)
                    Download Image
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    random-image.jpg (fetched on download)
                    Download Image
                    ``` ## API Reference **Component API Reference** #### React **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `DownloadableData | (() => MaybePromise)` | Yes | The data to download | | `fileName` | `string` | Yes | The name of the file to download | | `mimeType` | `FileMimeType` | Yes | The MIME type of the data to download | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Solid **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `DownloadableData | (() => MaybePromise)` | Yes | The data to download | | `fileName` | `string` | Yes | The name of the file to download | | `mimeType` | `FileMimeType` | Yes | The MIME type of the data to download | | `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `DownloadableData | (() => MaybePromise)` | Yes | The data to download | | `fileName` | `string` | Yes | The name of the file to download | | `mimeType` | `FileMimeType` | Yes | The MIME type of the data to download | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **DownloadTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `DownloadableData | (() => MaybePromise)` | Yes | | | `fileName` | `string` | Yes | | | `mimeType` | `FileMimeType` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | --- # Environment (REACT) ## Motivation We use [Zag.js](https://zagjs.com/overview/composition#custom-window-environment) internally, which relies on DOM query methods like `document.querySelectorAll` and `document.getElementById`. In custom environments like iframes, Shadow DOM, or Electron, these methods might not work as expected. To handle this, Ark UI includes the `EnvironmentProvider`, allowing you to set the appropriate root node or document, ensuring correct DOM queries. ## Setup To support custom environments like an iframe, Shadow DOM or Electron, render the `EnvironmentProvider` component to provide the environment context to all Ark UI components. ### Usage in iframe The `EnvironmentProvider` component will automatically detect the current environment and set the correct environment context. However, you can also manually set the `Document` like shown in this React example below: ```jsx import Frame, { FrameContextConsumer } from 'react-frame-component' import { EnvironmentProvider } from '@ark-ui/react' export const App = () => ( {({ document }) => {/* Your App */}} ) ``` ### Usage in Shadow DOM Here's an example of how to set the `EnvironmentProvider`'s value with Shadow DOM in Solid.js `Portal` component. ```jsx import { EnvironmentProvider } from '@ark-ui/react' import { Index, Portal } from 'solid-js/web' export const App = () => { let portalNode return ( portalNode?.shadowRoot ?? document}>{/* Your App */} ) } ``` ## Context Use the `useEnvironmentContext` hook to access the `RootNode`, `Document`, and `Window`. ## API Reference **Component API Reference** #### React **EnvironmentProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RootNode | (() => RootNode)` | No | | #### Solid **EnvironmentProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RootNode | (() => RootNode)` | No | | #### Vue **EnvironmentProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RootNode | (() => RootNode)` | No | | #### Svelte **EnvironmentProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `MaybeFunction` | No | The root node to use for the environment. | --- # Environment (VUE) ## Motivation We use [Zag.js](https://zagjs.com/overview/composition#custom-window-environment) internally, which relies on DOM query methods like `document.querySelectorAll` and `document.getElementById`. In custom environments like iframes, Shadow DOM, or Electron, these methods might not work as expected. To handle this, Ark UI includes the `EnvironmentProvider`, allowing you to set the appropriate root node or document, ensuring correct DOM queries. ## Setup To support custom environments like an iframe, Shadow DOM or Electron, render the `EnvironmentProvider` component to provide the environment context to all Ark UI components. ### Usage in iframe The `EnvironmentProvider` component will automatically detect the current environment and set the correct environment context. However, you can also manually set the `Document` like shown in this React example below: ```jsx import Frame, { FrameContextConsumer } from 'react-frame-component' import { EnvironmentProvider } from '@ark-ui/react' export const App = () => ( {({ document }) => {/* Your App */}} ) ``` ### Usage in Shadow DOM Here's an example of how to set the `EnvironmentProvider`'s value with Shadow DOM in Solid.js `Portal` component. ```jsx import { EnvironmentProvider } from '@ark-ui/react' import { Index, Portal } from 'solid-js/web' export const App = () => { let portalNode return ( portalNode?.shadowRoot ?? document}>{/* Your App */} ) } ``` ## Context Use the `useEnvironmentContext` hook to access the `RootNode`, `Document`, and `Window`. ## API Reference **Component API Reference** #### React **EnvironmentProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RootNode | (() => RootNode)` | No | | #### Solid **EnvironmentProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RootNode | (() => RootNode)` | No | | #### Vue **EnvironmentProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RootNode | (() => RootNode)` | No | | #### Svelte **EnvironmentProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `MaybeFunction` | No | The root node to use for the environment. | --- # Environment (SVELTE) ## Motivation We use [Zag.js](https://zagjs.com/overview/composition#custom-window-environment) internally, which relies on DOM query methods like `document.querySelectorAll` and `document.getElementById`. In custom environments like iframes, Shadow DOM, or Electron, these methods might not work as expected. To handle this, Ark UI includes the `EnvironmentProvider`, allowing you to set the appropriate root node or document, ensuring correct DOM queries. ## Setup To support custom environments like an iframe, Shadow DOM or Electron, render the `EnvironmentProvider` component to provide the environment context to all Ark UI components. ### Usage in iframe The `EnvironmentProvider` component will automatically detect the current environment and set the correct environment context. However, you can also manually set the `Document` like shown in this React example below: ```jsx import Frame, { FrameContextConsumer } from 'react-frame-component' import { EnvironmentProvider } from '@ark-ui/react' export const App = () => ( {({ document }) => {/* Your App */}} ) ``` ### Usage in Shadow DOM Here's an example of how to set the `EnvironmentProvider`'s value with Shadow DOM in Solid.js `Portal` component. ```jsx import { EnvironmentProvider } from '@ark-ui/react' import { Index, Portal } from 'solid-js/web' export const App = () => { let portalNode return ( portalNode?.shadowRoot ?? document}>{/* Your App */} ) } ``` ## Context Use the `useEnvironmentContext` hook to access the `RootNode`, `Document`, and `Window`. ## API Reference **Component API Reference** #### React **EnvironmentProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RootNode | (() => RootNode)` | No | | #### Solid **EnvironmentProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RootNode | (() => RootNode)` | No | | #### Vue **EnvironmentProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RootNode | (() => RootNode)` | No | | #### Svelte **EnvironmentProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `MaybeFunction` | No | The root node to use for the environment. | --- # Environment (SOLID) ## Motivation We use [Zag.js](https://zagjs.com/overview/composition#custom-window-environment) internally, which relies on DOM query methods like `document.querySelectorAll` and `document.getElementById`. In custom environments like iframes, Shadow DOM, or Electron, these methods might not work as expected. To handle this, Ark UI includes the `EnvironmentProvider`, allowing you to set the appropriate root node or document, ensuring correct DOM queries. ## Setup To support custom environments like an iframe, Shadow DOM or Electron, render the `EnvironmentProvider` component to provide the environment context to all Ark UI components. ### Usage in iframe The `EnvironmentProvider` component will automatically detect the current environment and set the correct environment context. However, you can also manually set the `Document` like shown in this React example below: ```jsx import Frame, { FrameContextConsumer } from 'react-frame-component' import { EnvironmentProvider } from '@ark-ui/react' export const App = () => ( {({ document }) => {/* Your App */}} ) ``` ### Usage in Shadow DOM Here's an example of how to set the `EnvironmentProvider`'s value with Shadow DOM in Solid.js `Portal` component. ```jsx import { EnvironmentProvider } from '@ark-ui/react' import { Index, Portal } from 'solid-js/web' export const App = () => { let portalNode return ( portalNode?.shadowRoot ?? document}>{/* Your App */} ) } ``` ## Context Use the `useEnvironmentContext` hook to access the `RootNode`, `Document`, and `Window`. ## API Reference **Component API Reference** #### React **EnvironmentProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RootNode | (() => RootNode)` | No | | #### Solid **EnvironmentProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RootNode | (() => RootNode)` | No | | #### Vue **EnvironmentProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `RootNode | (() => RootNode)` | No | | #### Svelte **EnvironmentProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `MaybeFunction` | No | The root node to use for the environment. | --- # Focus Trap (REACT) ## Motivation Focus trapping is essential for modal interfaces and other interactive elements that require user attention. The `FocusTrap` component helps maintain accessibility by ensuring keyboard focus remains within a designated container until explicitly released. ## Examples **Example: basic** #### React ```tsx import { FocusTrap } from '@ark-ui/react/focus-trap' import { useState } from 'react' export const Basic = () => { const [trapped, setTrapped] = useState(false) return ( <>
                    ``` ### Autofocus The focus trap respects elements with the `autofocus` attribute. **Example: autofocus** #### React ```tsx import { FocusTrap } from '@ark-ui/react/focus-trap' import { useRef, useState } from 'react' export const Autofocus = () => { const [trapped, setTrapped] = useState(false) const toggle = () => setTrapped((c) => !c) const buttonRef = useRef(null) const getButtonNode = () => { const node = buttonRef.current if (!node) throw new Error('Button not found') return node } return (
                    {trapped && (
                    {/* biome-ignore lint/a11y/noAutofocus: intentional */}
                    )}
                    ) } ``` #### Solid ```tsx import { FocusTrap } from '@ark-ui/solid/focus-trap' import { Show, createSignal } from 'solid-js' export const Autofocus = () => { const [trapped, setTrapped] = createSignal(false) let buttonRef!: HTMLButtonElement return (
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#if trapped}
                    {/if}
                    ``` ### Initial Focus Use the `initialFocus` prop to set the element that should receive initial focus when the trap is activated. **Example: initial-focus** #### React ```tsx import { FocusTrap } from '@ark-ui/react/focus-trap' import { useRef, useState } from 'react' export const InitialFocus = () => { const [trapped, setTrapped] = useState(false) const toggle = () => setTrapped((c) => !c) const inputRef = useRef(null) return (
                    inputRef.current}>
                    ``` ## API Reference **Component API Reference** #### React **FocusTrap Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the focus trap is disabled. | | `fallbackFocus` | `FocusTarget` | No | By default, an error will be thrown if the focus trap contains no elements in its tab order. With this option you can specify a fallback element to programmatically receive focus if no other tabbable elements are found. For example, you may want a popover's `
                    ` to receive focus if the popover's content includes no tabbable elements. *Make sure the fallback element has a negative `tabindex` so it can be programmatically focused. NOTE: If `initialFocus` is `false` (or a function that returns `false`), this function will not be called when the trap is activated, and no element will be initially focused. This function may still be called while the trap is active if things change such that there are no longer any tabbable nodes in the trap. | | `initialFocus` | `VoidFunction | FocusTargetOrFalse` | No | By default, when a focus trap is activated the first element in the focus trap's tab order will receive focus. With this option you can specify a different element to receive that initial focus, or use `false` for no initially focused element at all. NOTE: Setting this option to `false` (or a function that returns `false`) will prevent the `fallbackFocus` option from being used. Setting this option to `undefined` (or a function that returns `undefined`) will result in the default behavior. | | `onActivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the target element upon activation. | | `onDeactivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the trigger element upon deactivation. | | `returnFocusOnDeactivate` | `boolean` | No | Default: `true`. If `false`, when the trap is deactivated, focus will *not* return to the element that had focus before activation. | | `setReturnFocus` | `type ONLY_FOR_FORMAT = | FocusTargetValueOrFalse | ((nodeFocusedBeforeActivation: HTMLElement | SVGElement) => FocusTargetValueOrFalse)` | No | By default, focus trap on deactivation will return to the element that was focused before activation. | #### Solid **FocusTrap Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the focus trap is disabled. | | `fallbackFocus` | `FocusTarget` | No | By default, an error will be thrown if the focus trap contains no elements in its tab order. With this option you can specify a fallback element to programmatically receive focus if no other tabbable elements are found. For example, you may want a popover's `
                    ` to receive focus if the popover's content includes no tabbable elements. *Make sure the fallback element has a negative `tabindex` so it can be programmatically focused. NOTE: If `initialFocus` is `false` (or a function that returns `false`), this function will not be called when the trap is activated, and no element will be initially focused. This function may still be called while the trap is active if things change such that there are no longer any tabbable nodes in the trap. | | `initialFocus` | `VoidFunction | FocusTargetOrFalse` | No | By default, when a focus trap is activated the first element in the focus trap's tab order will receive focus. With this option you can specify a different element to receive that initial focus, or use `false` for no initially focused element at all. NOTE: Setting this option to `false` (or a function that returns `false`) will prevent the `fallbackFocus` option from being used. Setting this option to `undefined` (or a function that returns `undefined`) will result in the default behavior. | | `onActivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the target element upon activation. | | `onDeactivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the trigger element upon deactivation. | | `returnFocusOnDeactivate` | `boolean` | No | Default: `true`. If `false`, when the trap is deactivated, focus will *not* return to the element that had focus before activation. | | `setReturnFocus` | `type ONLY_FOR_FORMAT = | FocusTargetValueOrFalse | ((nodeFocusedBeforeActivation: HTMLElement | SVGElement) => FocusTargetValueOrFalse)` | No | By default, focus trap on deactivation will return to the element that was focused before activation. | #### Vue **FocusTrap Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the focus trap is disabled | | `fallbackFocus` | `FocusTarget` | No | Element to focus if initialFocus is not found. By default, focuses on container element | | `initialFocus` | `FocusTargetOrFalse | VoidFunction` | No | Element to focus when trap is activated. By default, focuses on first tabbable element | | `returnFocusOnDeactivate` | `boolean` | No | Whether to return focus to the element that had focus when trap was activated | | `setReturnFocus` | `FocusTargetValueOrFalse | ((node: FocusableElement) => FocusTargetValueOrFalse)` | No | Custom element to return focus to when trap is deactivated | #### Svelte **FocusTrap Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the focus trap is disabled. | | `fallbackFocus` | `FocusTarget` | No | By default, an error will be thrown if the focus trap contains no elements in its tab order. With this option you can specify a fallback element to programmatically receive focus if no other tabbable elements are found. For example, you may want a popover's `
                    ` to receive focus if the popover's content includes no tabbable elements. *Make sure the fallback element has a negative `tabindex` so it can be programmatically focused. NOTE: If `initialFocus` is `false` (or a function that returns `false`), this function will not be called when the trap is activated, and no element will be initially focused. This function may still be called while the trap is active if things change such that there are no longer any tabbable nodes in the trap. | | `initialFocus` | `VoidFunction | FocusTargetOrFalse` | No | By default, when a focus trap is activated the first element in the focus trap's tab order will receive focus. With this option you can specify a different element to receive that initial focus, or use `false` for no initially focused element at all. NOTE: Setting this option to `false` (or a function that returns `false`) will prevent the `fallbackFocus` option from being used. Setting this option to `undefined` (or a function that returns `undefined`) will result in the default behavior. | | `onActivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the target element upon activation. | | `onDeactivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the trigger element upon deactivation. | | `ref` | `Element` | No | | | `returnFocusOnDeactivate` | `boolean` | No | Default: `true`. If `false`, when the trap is deactivated, focus will *not* return to the element that had focus before activation. | | `setReturnFocus` | `type ONLY_FOR_FORMAT = | FocusTargetValueOrFalse | ((nodeFocusedBeforeActivation: HTMLElement | SVGElement) => FocusTargetValueOrFalse)` | No | By default, focus trap on deactivation will return to the element that was focused before activation. | --- # Focus Trap (VUE) ## Motivation Focus trapping is essential for modal interfaces and other interactive elements that require user attention. The `FocusTrap` component helps maintain accessibility by ensuring keyboard focus remains within a designated container until explicitly released. ## Examples **Example: basic** #### React ```tsx import { FocusTrap } from '@ark-ui/react/focus-trap' import { useState } from 'react' export const Basic = () => { const [trapped, setTrapped] = useState(false) return ( <>
                    ``` ### Autofocus The focus trap respects elements with the `autofocus` attribute. **Example: autofocus** #### React ```tsx import { FocusTrap } from '@ark-ui/react/focus-trap' import { useRef, useState } from 'react' export const Autofocus = () => { const [trapped, setTrapped] = useState(false) const toggle = () => setTrapped((c) => !c) const buttonRef = useRef(null) const getButtonNode = () => { const node = buttonRef.current if (!node) throw new Error('Button not found') return node } return (
                    {trapped && (
                    {/* biome-ignore lint/a11y/noAutofocus: intentional */}
                    )}
                    ) } ``` #### Solid ```tsx import { FocusTrap } from '@ark-ui/solid/focus-trap' import { Show, createSignal } from 'solid-js' export const Autofocus = () => { const [trapped, setTrapped] = createSignal(false) let buttonRef!: HTMLButtonElement return (
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#if trapped}
                    {/if}
                    ``` ### Initial Focus Use the `initialFocus` prop to set the element that should receive initial focus when the trap is activated. **Example: initial-focus** #### React ```tsx import { FocusTrap } from '@ark-ui/react/focus-trap' import { useRef, useState } from 'react' export const InitialFocus = () => { const [trapped, setTrapped] = useState(false) const toggle = () => setTrapped((c) => !c) const inputRef = useRef(null) return (
                    inputRef.current}>
                    ``` ## API Reference **Component API Reference** #### React **FocusTrap Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the focus trap is disabled. | | `fallbackFocus` | `FocusTarget` | No | By default, an error will be thrown if the focus trap contains no elements in its tab order. With this option you can specify a fallback element to programmatically receive focus if no other tabbable elements are found. For example, you may want a popover's `
                    ` to receive focus if the popover's content includes no tabbable elements. *Make sure the fallback element has a negative `tabindex` so it can be programmatically focused. NOTE: If `initialFocus` is `false` (or a function that returns `false`), this function will not be called when the trap is activated, and no element will be initially focused. This function may still be called while the trap is active if things change such that there are no longer any tabbable nodes in the trap. | | `initialFocus` | `VoidFunction | FocusTargetOrFalse` | No | By default, when a focus trap is activated the first element in the focus trap's tab order will receive focus. With this option you can specify a different element to receive that initial focus, or use `false` for no initially focused element at all. NOTE: Setting this option to `false` (or a function that returns `false`) will prevent the `fallbackFocus` option from being used. Setting this option to `undefined` (or a function that returns `undefined`) will result in the default behavior. | | `onActivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the target element upon activation. | | `onDeactivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the trigger element upon deactivation. | | `returnFocusOnDeactivate` | `boolean` | No | Default: `true`. If `false`, when the trap is deactivated, focus will *not* return to the element that had focus before activation. | | `setReturnFocus` | `type ONLY_FOR_FORMAT = | FocusTargetValueOrFalse | ((nodeFocusedBeforeActivation: HTMLElement | SVGElement) => FocusTargetValueOrFalse)` | No | By default, focus trap on deactivation will return to the element that was focused before activation. | #### Solid **FocusTrap Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the focus trap is disabled. | | `fallbackFocus` | `FocusTarget` | No | By default, an error will be thrown if the focus trap contains no elements in its tab order. With this option you can specify a fallback element to programmatically receive focus if no other tabbable elements are found. For example, you may want a popover's `
                    ` to receive focus if the popover's content includes no tabbable elements. *Make sure the fallback element has a negative `tabindex` so it can be programmatically focused. NOTE: If `initialFocus` is `false` (or a function that returns `false`), this function will not be called when the trap is activated, and no element will be initially focused. This function may still be called while the trap is active if things change such that there are no longer any tabbable nodes in the trap. | | `initialFocus` | `VoidFunction | FocusTargetOrFalse` | No | By default, when a focus trap is activated the first element in the focus trap's tab order will receive focus. With this option you can specify a different element to receive that initial focus, or use `false` for no initially focused element at all. NOTE: Setting this option to `false` (or a function that returns `false`) will prevent the `fallbackFocus` option from being used. Setting this option to `undefined` (or a function that returns `undefined`) will result in the default behavior. | | `onActivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the target element upon activation. | | `onDeactivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the trigger element upon deactivation. | | `returnFocusOnDeactivate` | `boolean` | No | Default: `true`. If `false`, when the trap is deactivated, focus will *not* return to the element that had focus before activation. | | `setReturnFocus` | `type ONLY_FOR_FORMAT = | FocusTargetValueOrFalse | ((nodeFocusedBeforeActivation: HTMLElement | SVGElement) => FocusTargetValueOrFalse)` | No | By default, focus trap on deactivation will return to the element that was focused before activation. | #### Vue **FocusTrap Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the focus trap is disabled | | `fallbackFocus` | `FocusTarget` | No | Element to focus if initialFocus is not found. By default, focuses on container element | | `initialFocus` | `FocusTargetOrFalse | VoidFunction` | No | Element to focus when trap is activated. By default, focuses on first tabbable element | | `returnFocusOnDeactivate` | `boolean` | No | Whether to return focus to the element that had focus when trap was activated | | `setReturnFocus` | `FocusTargetValueOrFalse | ((node: FocusableElement) => FocusTargetValueOrFalse)` | No | Custom element to return focus to when trap is deactivated | #### Svelte **FocusTrap Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the focus trap is disabled. | | `fallbackFocus` | `FocusTarget` | No | By default, an error will be thrown if the focus trap contains no elements in its tab order. With this option you can specify a fallback element to programmatically receive focus if no other tabbable elements are found. For example, you may want a popover's `
                    ` to receive focus if the popover's content includes no tabbable elements. *Make sure the fallback element has a negative `tabindex` so it can be programmatically focused. NOTE: If `initialFocus` is `false` (or a function that returns `false`), this function will not be called when the trap is activated, and no element will be initially focused. This function may still be called while the trap is active if things change such that there are no longer any tabbable nodes in the trap. | | `initialFocus` | `VoidFunction | FocusTargetOrFalse` | No | By default, when a focus trap is activated the first element in the focus trap's tab order will receive focus. With this option you can specify a different element to receive that initial focus, or use `false` for no initially focused element at all. NOTE: Setting this option to `false` (or a function that returns `false`) will prevent the `fallbackFocus` option from being used. Setting this option to `undefined` (or a function that returns `undefined`) will result in the default behavior. | | `onActivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the target element upon activation. | | `onDeactivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the trigger element upon deactivation. | | `ref` | `Element` | No | | | `returnFocusOnDeactivate` | `boolean` | No | Default: `true`. If `false`, when the trap is deactivated, focus will *not* return to the element that had focus before activation. | | `setReturnFocus` | `type ONLY_FOR_FORMAT = | FocusTargetValueOrFalse | ((nodeFocusedBeforeActivation: HTMLElement | SVGElement) => FocusTargetValueOrFalse)` | No | By default, focus trap on deactivation will return to the element that was focused before activation. | --- # Focus Trap (SVELTE) ## Motivation Focus trapping is essential for modal interfaces and other interactive elements that require user attention. The `FocusTrap` component helps maintain accessibility by ensuring keyboard focus remains within a designated container until explicitly released. ## Examples **Example: basic** #### React ```tsx import { FocusTrap } from '@ark-ui/react/focus-trap' import { useState } from 'react' export const Basic = () => { const [trapped, setTrapped] = useState(false) return ( <>
                    ``` ### Autofocus The focus trap respects elements with the `autofocus` attribute. **Example: autofocus** #### React ```tsx import { FocusTrap } from '@ark-ui/react/focus-trap' import { useRef, useState } from 'react' export const Autofocus = () => { const [trapped, setTrapped] = useState(false) const toggle = () => setTrapped((c) => !c) const buttonRef = useRef(null) const getButtonNode = () => { const node = buttonRef.current if (!node) throw new Error('Button not found') return node } return (
                    {trapped && (
                    {/* biome-ignore lint/a11y/noAutofocus: intentional */}
                    )}
                    ) } ``` #### Solid ```tsx import { FocusTrap } from '@ark-ui/solid/focus-trap' import { Show, createSignal } from 'solid-js' export const Autofocus = () => { const [trapped, setTrapped] = createSignal(false) let buttonRef!: HTMLButtonElement return (
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#if trapped}
                    {/if}
                    ``` ### Initial Focus Use the `initialFocus` prop to set the element that should receive initial focus when the trap is activated. **Example: initial-focus** #### React ```tsx import { FocusTrap } from '@ark-ui/react/focus-trap' import { useRef, useState } from 'react' export const InitialFocus = () => { const [trapped, setTrapped] = useState(false) const toggle = () => setTrapped((c) => !c) const inputRef = useRef(null) return (
                    inputRef.current}>
                    ``` ## API Reference **Component API Reference** #### React **FocusTrap Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the focus trap is disabled. | | `fallbackFocus` | `FocusTarget` | No | By default, an error will be thrown if the focus trap contains no elements in its tab order. With this option you can specify a fallback element to programmatically receive focus if no other tabbable elements are found. For example, you may want a popover's `
                    ` to receive focus if the popover's content includes no tabbable elements. *Make sure the fallback element has a negative `tabindex` so it can be programmatically focused. NOTE: If `initialFocus` is `false` (or a function that returns `false`), this function will not be called when the trap is activated, and no element will be initially focused. This function may still be called while the trap is active if things change such that there are no longer any tabbable nodes in the trap. | | `initialFocus` | `VoidFunction | FocusTargetOrFalse` | No | By default, when a focus trap is activated the first element in the focus trap's tab order will receive focus. With this option you can specify a different element to receive that initial focus, or use `false` for no initially focused element at all. NOTE: Setting this option to `false` (or a function that returns `false`) will prevent the `fallbackFocus` option from being used. Setting this option to `undefined` (or a function that returns `undefined`) will result in the default behavior. | | `onActivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the target element upon activation. | | `onDeactivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the trigger element upon deactivation. | | `returnFocusOnDeactivate` | `boolean` | No | Default: `true`. If `false`, when the trap is deactivated, focus will *not* return to the element that had focus before activation. | | `setReturnFocus` | `type ONLY_FOR_FORMAT = | FocusTargetValueOrFalse | ((nodeFocusedBeforeActivation: HTMLElement | SVGElement) => FocusTargetValueOrFalse)` | No | By default, focus trap on deactivation will return to the element that was focused before activation. | #### Solid **FocusTrap Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the focus trap is disabled. | | `fallbackFocus` | `FocusTarget` | No | By default, an error will be thrown if the focus trap contains no elements in its tab order. With this option you can specify a fallback element to programmatically receive focus if no other tabbable elements are found. For example, you may want a popover's `
                    ` to receive focus if the popover's content includes no tabbable elements. *Make sure the fallback element has a negative `tabindex` so it can be programmatically focused. NOTE: If `initialFocus` is `false` (or a function that returns `false`), this function will not be called when the trap is activated, and no element will be initially focused. This function may still be called while the trap is active if things change such that there are no longer any tabbable nodes in the trap. | | `initialFocus` | `VoidFunction | FocusTargetOrFalse` | No | By default, when a focus trap is activated the first element in the focus trap's tab order will receive focus. With this option you can specify a different element to receive that initial focus, or use `false` for no initially focused element at all. NOTE: Setting this option to `false` (or a function that returns `false`) will prevent the `fallbackFocus` option from being used. Setting this option to `undefined` (or a function that returns `undefined`) will result in the default behavior. | | `onActivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the target element upon activation. | | `onDeactivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the trigger element upon deactivation. | | `returnFocusOnDeactivate` | `boolean` | No | Default: `true`. If `false`, when the trap is deactivated, focus will *not* return to the element that had focus before activation. | | `setReturnFocus` | `type ONLY_FOR_FORMAT = | FocusTargetValueOrFalse | ((nodeFocusedBeforeActivation: HTMLElement | SVGElement) => FocusTargetValueOrFalse)` | No | By default, focus trap on deactivation will return to the element that was focused before activation. | #### Vue **FocusTrap Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the focus trap is disabled | | `fallbackFocus` | `FocusTarget` | No | Element to focus if initialFocus is not found. By default, focuses on container element | | `initialFocus` | `FocusTargetOrFalse | VoidFunction` | No | Element to focus when trap is activated. By default, focuses on first tabbable element | | `returnFocusOnDeactivate` | `boolean` | No | Whether to return focus to the element that had focus when trap was activated | | `setReturnFocus` | `FocusTargetValueOrFalse | ((node: FocusableElement) => FocusTargetValueOrFalse)` | No | Custom element to return focus to when trap is deactivated | #### Svelte **FocusTrap Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the focus trap is disabled. | | `fallbackFocus` | `FocusTarget` | No | By default, an error will be thrown if the focus trap contains no elements in its tab order. With this option you can specify a fallback element to programmatically receive focus if no other tabbable elements are found. For example, you may want a popover's `
                    ` to receive focus if the popover's content includes no tabbable elements. *Make sure the fallback element has a negative `tabindex` so it can be programmatically focused. NOTE: If `initialFocus` is `false` (or a function that returns `false`), this function will not be called when the trap is activated, and no element will be initially focused. This function may still be called while the trap is active if things change such that there are no longer any tabbable nodes in the trap. | | `initialFocus` | `VoidFunction | FocusTargetOrFalse` | No | By default, when a focus trap is activated the first element in the focus trap's tab order will receive focus. With this option you can specify a different element to receive that initial focus, or use `false` for no initially focused element at all. NOTE: Setting this option to `false` (or a function that returns `false`) will prevent the `fallbackFocus` option from being used. Setting this option to `undefined` (or a function that returns `undefined`) will result in the default behavior. | | `onActivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the target element upon activation. | | `onDeactivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the trigger element upon deactivation. | | `ref` | `Element` | No | | | `returnFocusOnDeactivate` | `boolean` | No | Default: `true`. If `false`, when the trap is deactivated, focus will *not* return to the element that had focus before activation. | | `setReturnFocus` | `type ONLY_FOR_FORMAT = | FocusTargetValueOrFalse | ((nodeFocusedBeforeActivation: HTMLElement | SVGElement) => FocusTargetValueOrFalse)` | No | By default, focus trap on deactivation will return to the element that was focused before activation. | --- # Focus Trap (SOLID) ## Motivation Focus trapping is essential for modal interfaces and other interactive elements that require user attention. The `FocusTrap` component helps maintain accessibility by ensuring keyboard focus remains within a designated container until explicitly released. ## Examples **Example: basic** #### React ```tsx import { FocusTrap } from '@ark-ui/react/focus-trap' import { useState } from 'react' export const Basic = () => { const [trapped, setTrapped] = useState(false) return ( <>
                    ``` ### Autofocus The focus trap respects elements with the `autofocus` attribute. **Example: autofocus** #### React ```tsx import { FocusTrap } from '@ark-ui/react/focus-trap' import { useRef, useState } from 'react' export const Autofocus = () => { const [trapped, setTrapped] = useState(false) const toggle = () => setTrapped((c) => !c) const buttonRef = useRef(null) const getButtonNode = () => { const node = buttonRef.current if (!node) throw new Error('Button not found') return node } return (
                    {trapped && (
                    {/* biome-ignore lint/a11y/noAutofocus: intentional */}
                    )}
                    ) } ``` #### Solid ```tsx import { FocusTrap } from '@ark-ui/solid/focus-trap' import { Show, createSignal } from 'solid-js' export const Autofocus = () => { const [trapped, setTrapped] = createSignal(false) let buttonRef!: HTMLButtonElement return (
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    {#if trapped}
                    {/if}
                    ``` ### Initial Focus Use the `initialFocus` prop to set the element that should receive initial focus when the trap is activated. **Example: initial-focus** #### React ```tsx import { FocusTrap } from '@ark-ui/react/focus-trap' import { useRef, useState } from 'react' export const InitialFocus = () => { const [trapped, setTrapped] = useState(false) const toggle = () => setTrapped((c) => !c) const inputRef = useRef(null) return (
                    inputRef.current}>
                    ``` ## API Reference **Component API Reference** #### React **FocusTrap Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the focus trap is disabled. | | `fallbackFocus` | `FocusTarget` | No | By default, an error will be thrown if the focus trap contains no elements in its tab order. With this option you can specify a fallback element to programmatically receive focus if no other tabbable elements are found. For example, you may want a popover's `
                    ` to receive focus if the popover's content includes no tabbable elements. *Make sure the fallback element has a negative `tabindex` so it can be programmatically focused. NOTE: If `initialFocus` is `false` (or a function that returns `false`), this function will not be called when the trap is activated, and no element will be initially focused. This function may still be called while the trap is active if things change such that there are no longer any tabbable nodes in the trap. | | `initialFocus` | `VoidFunction | FocusTargetOrFalse` | No | By default, when a focus trap is activated the first element in the focus trap's tab order will receive focus. With this option you can specify a different element to receive that initial focus, or use `false` for no initially focused element at all. NOTE: Setting this option to `false` (or a function that returns `false`) will prevent the `fallbackFocus` option from being used. Setting this option to `undefined` (or a function that returns `undefined`) will result in the default behavior. | | `onActivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the target element upon activation. | | `onDeactivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the trigger element upon deactivation. | | `returnFocusOnDeactivate` | `boolean` | No | Default: `true`. If `false`, when the trap is deactivated, focus will *not* return to the element that had focus before activation. | | `setReturnFocus` | `type ONLY_FOR_FORMAT = | FocusTargetValueOrFalse | ((nodeFocusedBeforeActivation: HTMLElement | SVGElement) => FocusTargetValueOrFalse)` | No | By default, focus trap on deactivation will return to the element that was focused before activation. | #### Solid **FocusTrap Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the focus trap is disabled. | | `fallbackFocus` | `FocusTarget` | No | By default, an error will be thrown if the focus trap contains no elements in its tab order. With this option you can specify a fallback element to programmatically receive focus if no other tabbable elements are found. For example, you may want a popover's `
                    ` to receive focus if the popover's content includes no tabbable elements. *Make sure the fallback element has a negative `tabindex` so it can be programmatically focused. NOTE: If `initialFocus` is `false` (or a function that returns `false`), this function will not be called when the trap is activated, and no element will be initially focused. This function may still be called while the trap is active if things change such that there are no longer any tabbable nodes in the trap. | | `initialFocus` | `VoidFunction | FocusTargetOrFalse` | No | By default, when a focus trap is activated the first element in the focus trap's tab order will receive focus. With this option you can specify a different element to receive that initial focus, or use `false` for no initially focused element at all. NOTE: Setting this option to `false` (or a function that returns `false`) will prevent the `fallbackFocus` option from being used. Setting this option to `undefined` (or a function that returns `undefined`) will result in the default behavior. | | `onActivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the target element upon activation. | | `onDeactivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the trigger element upon deactivation. | | `returnFocusOnDeactivate` | `boolean` | No | Default: `true`. If `false`, when the trap is deactivated, focus will *not* return to the element that had focus before activation. | | `setReturnFocus` | `type ONLY_FOR_FORMAT = | FocusTargetValueOrFalse | ((nodeFocusedBeforeActivation: HTMLElement | SVGElement) => FocusTargetValueOrFalse)` | No | By default, focus trap on deactivation will return to the element that was focused before activation. | #### Vue **FocusTrap Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the focus trap is disabled | | `fallbackFocus` | `FocusTarget` | No | Element to focus if initialFocus is not found. By default, focuses on container element | | `initialFocus` | `FocusTargetOrFalse | VoidFunction` | No | Element to focus when trap is activated. By default, focuses on first tabbable element | | `returnFocusOnDeactivate` | `boolean` | No | Whether to return focus to the element that had focus when trap was activated | | `setReturnFocus` | `FocusTargetValueOrFalse | ((node: FocusableElement) => FocusTargetValueOrFalse)` | No | Custom element to return focus to when trap is deactivated | #### Svelte **FocusTrap Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the focus trap is disabled. | | `fallbackFocus` | `FocusTarget` | No | By default, an error will be thrown if the focus trap contains no elements in its tab order. With this option you can specify a fallback element to programmatically receive focus if no other tabbable elements are found. For example, you may want a popover's `
                    ` to receive focus if the popover's content includes no tabbable elements. *Make sure the fallback element has a negative `tabindex` so it can be programmatically focused. NOTE: If `initialFocus` is `false` (or a function that returns `false`), this function will not be called when the trap is activated, and no element will be initially focused. This function may still be called while the trap is active if things change such that there are no longer any tabbable nodes in the trap. | | `initialFocus` | `VoidFunction | FocusTargetOrFalse` | No | By default, when a focus trap is activated the first element in the focus trap's tab order will receive focus. With this option you can specify a different element to receive that initial focus, or use `false` for no initially focused element at all. NOTE: Setting this option to `false` (or a function that returns `false`) will prevent the `fallbackFocus` option from being used. Setting this option to `undefined` (or a function that returns `undefined`) will result in the default behavior. | | `onActivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the target element upon activation. | | `onDeactivate` | `VoidFunction` | No | A function that will be called **before** sending focus to the trigger element upon deactivation. | | `ref` | `Element` | No | | | `returnFocusOnDeactivate` | `boolean` | No | Default: `true`. If `false`, when the trap is deactivated, focus will *not* return to the element that had focus before activation. | | `setReturnFocus` | `type ONLY_FOR_FORMAT = | FocusTargetValueOrFalse | ((nodeFocusedBeforeActivation: HTMLElement | SVGElement) => FocusTargetValueOrFalse)` | No | By default, focus trap on deactivation will return to the element that was focused before activation. | --- # Format Byte (REACT) ## Usage The byte formatting component extends the number formatting capabilities to handle byte-specific formatting, including automatic unit conversion and display options. ```jsx import { Format } from '@ark-ui/react' ``` ## Examples ### Basic Use the `Format.Byte` component to format a byte value with default options. ```tsx import { Format } from '@ark-ui/react/format' import styles from 'styles/format.module.css' export const ByteBasic = () => { return (
                    File size
                    ) } ``` ### Sizes Use the `sizes` prop to specify custom byte sizes for formatting. ```tsx import { Format } from '@ark-ui/react/format' import styles from 'styles/format.module.css' export const ByteSizes = () => { const byteSizes = [50, 5000, 5000000, 5000000000] return (
                    {byteSizes.map((size) => (
                    ))}
                    ) } ``` ### Locale Use the `locale` prop to format the byte value according to a specific locale. ```tsx import { Format } from '@ark-ui/react/format' import { LocaleProvider } from '@ark-ui/react/locale' import styles from 'styles/format.module.css' export const ByteWithLocale = () => { const locales = ['de-DE', 'zh-CN'] return (
                    {locales.map((locale) => (
                    {locale}:
                    ))}
                    ) } ``` ### Unit Use the `unit` prop to specify the unit of the byte value. ```tsx import { Format } from '@ark-ui/react/format' import styles from 'styles/format.module.css' export const ByteWithUnit = () => { return (
                    File size:
                    ) } ``` ### Unit Display Use the `unitDisplay` prop to specify the display of the unit. ```tsx import { Format } from '@ark-ui/react/format' import styles from 'styles/format.module.css' export const ByteWithUnitDisplay = () => { const unitDisplays = ['narrow', 'short', 'long'] as const return (
                    {unitDisplays.map((unitDisplay) => (
                    {unitDisplay}:
                    ))}
                    ) } ``` ### Unit System Use the `unitSystem` prop to specify whether to use decimal (1000 bytes) or binary (1024 bytes) unit system. ```tsx import { Format } from '@ark-ui/react/format' import styles from 'styles/format.module.css' export const ByteWithUnitSystem = () => { return (
                    Decimal (1000 bytes):
                    Binary (1024 bytes):
                    ) } ``` --- # Format Byte (VUE) ## Usage The byte formatting component extends the number formatting capabilities to handle byte-specific formatting, including automatic unit conversion and display options. ```jsx import { Format } from '@ark-ui/react' ``` ## Examples ### Basic Use the `Format.Byte` component to format a byte value with default options. ```vue ``` ### Sizes Use the `sizes` prop to specify custom byte sizes for formatting. ```vue ``` ### Locale Use the `locale` prop to format the byte value according to a specific locale. ```vue ``` ### Unit Use the `unit` prop to specify the unit of the byte value. ```vue ``` ### Unit Display Use the `unitDisplay` prop to specify the display of the unit. ```vue ``` ### Unit System Use the `unitSystem` prop to specify whether to use decimal (1000 bytes) or binary (1024 bytes) unit system. ```vue ``` --- # Format Byte (SVELTE) ## Usage The byte formatting component extends the number formatting capabilities to handle byte-specific formatting, including automatic unit conversion and display options. ```jsx import { Format } from '@ark-ui/react' ``` ## Examples ### Basic Use the `Format.Byte` component to format a byte value with default options. ```svelte
                    File size
                    ``` ### Sizes Use the `sizes` prop to specify custom byte sizes for formatting. ```svelte
                    {#each byteSizes as size (size)}
                    {/each}
                    ``` ### Locale Use the `locale` prop to format the byte value according to a specific locale. ```svelte
                    {#each locales as locale (locale)}
                    {locale}:
                    {/each}
                    ``` ### Unit Use the `unit` prop to specify the unit of the byte value. ```svelte
                    File size:
                    ``` ### Unit Display Use the `unitDisplay` prop to specify the display of the unit. ```svelte
                    {#each unitDisplays as unitDisplay (unitDisplay)}
                    {unitDisplay}:
                    {/each}
                    ``` ### Unit System Use the `unitSystem` prop to specify whether to use decimal (1000 bytes) or binary (1024 bytes) unit system. ```svelte
                    Decimal (1000 bytes):
                    Binary (1024 bytes):
                    ``` --- # Format Byte (SOLID) ## Usage The byte formatting component extends the number formatting capabilities to handle byte-specific formatting, including automatic unit conversion and display options. ```jsx import { Format } from '@ark-ui/react' ``` ## Examples ### Basic Use the `Format.Byte` component to format a byte value with default options. ```tsx import { Format } from '@ark-ui/solid/format' import styles from 'styles/format.module.css' export const ByteBasic = () => { return (
                    File size
                    ) } ``` ### Sizes Use the `sizes` prop to specify custom byte sizes for formatting. ```tsx import { Format } from '@ark-ui/solid/format' import { For } from 'solid-js' import styles from 'styles/format.module.css' export const ByteSizes = () => { const byteSizes = [50, 5000, 5000000, 5000000000] return (
                    {(size) => (
                    )}
                    ) } ``` ### Locale Use the `locale` prop to format the byte value according to a specific locale. ```tsx import { Format } from '@ark-ui/solid/format' import { LocaleProvider } from '@ark-ui/solid/locale' import { For } from 'solid-js' import styles from 'styles/format.module.css' export const ByteWithLocale = () => { const locales = ['de-DE', 'zh-CN'] return (
                    {(locale) => (
                    {locale}:
                    )}
                    ) } ``` ### Unit Use the `unit` prop to specify the unit of the byte value. ```tsx import { Format } from '@ark-ui/solid/format' import styles from 'styles/format.module.css' export const ByteWithUnit = () => { return (
                    File size:
                    ) } ``` ### Unit Display Use the `unitDisplay` prop to specify the display of the unit. ```tsx import { Format } from '@ark-ui/solid/format' import { For } from 'solid-js' import styles from 'styles/format.module.css' export const ByteWithUnitDisplay = () => { const unitDisplays = ['narrow', 'short', 'long'] as const return (
                    {(unitDisplay) => (
                    {unitDisplay}:
                    )}
                    ) } ``` ### Unit System Use the `unitSystem` prop to specify whether to use decimal (1000 bytes) or binary (1024 bytes) unit system. ```tsx import { Format } from '@ark-ui/solid/format' import styles from 'styles/format.module.css' export const ByteWithUnitSystem = () => { return (
                    Decimal (1000 bytes):
                    Binary (1024 bytes):
                    ) } ``` --- # Format Relative Time (REACT) ## Usage The relative time formatting logic is handled by the native `Intl.RelativeTimeFormat` API and smartly cached to avoid performance issues when using the same locale and options. ```jsx import { Format } from '@ark-ui/react' ``` ## Examples ### Basic Use the `Format.RelativeTime` component to format a relative time with default options. ```tsx import { Format } from '@ark-ui/react/format' import styles from 'styles/format.module.css' export const RelativeTimeBasic = () => { return (
                    Last updated
                    ) } ``` ### Short Use the `style="short"` prop to format the relative time in short format. ```tsx import { Format } from '@ark-ui/react/format' import styles from 'styles/format.module.css' export const RelativeTimeShort = () => { return (
                    Edited
                    ) } ``` --- # Format Relative Time (VUE) ## Usage The relative time formatting logic is handled by the native `Intl.RelativeTimeFormat` API and smartly cached to avoid performance issues when using the same locale and options. ```jsx import { Format } from '@ark-ui/react' ``` ## Examples ### Basic Use the `Format.RelativeTime` component to format a relative time with default options. ```vue ``` ### Short Use the `style="short"` prop to format the relative time in short format. ```vue ``` --- # Format Relative Time (SVELTE) ## Usage The relative time formatting logic is handled by the native `Intl.RelativeTimeFormat` API and smartly cached to avoid performance issues when using the same locale and options. ```jsx import { Format } from '@ark-ui/react' ``` ## Examples ### Basic Use the `Format.RelativeTime` component to format a relative time with default options. ```svelte
                    Last updated
                    ``` ### Short Use the `style="short"` prop to format the relative time in short format. ```svelte
                    Edited
                    ``` --- # Format Relative Time (SOLID) ## Usage The relative time formatting logic is handled by the native `Intl.RelativeTimeFormat` API and smartly cached to avoid performance issues when using the same locale and options. ```jsx import { Format } from '@ark-ui/react' ``` ## Examples ### Basic Use the `Format.RelativeTime` component to format a relative time with default options. ```tsx import { Format } from '@ark-ui/solid/format' import styles from 'styles/format.module.css' export const RelativeTimeBasic = () => { return (
                    Last updated
                    ) } ``` ### Short Use the `style="short"` prop to format the relative time in short format. ```tsx import { Format } from '@ark-ui/solid/format' import styles from 'styles/format.module.css' export const RelativeTimeShort = () => { return (
                    Edited
                    ) } ``` --- # Frame (REACT) ## Usage The `Frame` component is used to render a component in an iframe. - Tracks the size of the content and exposes them via css variables. - Support for `head` prop to inject scripts and styles. - Support for mount and unmount callbacks. ```jsx import { Frame } from '@ark-ui/react' ``` ## Examples ### Basic Wrap your component in the `Frame` component to render it in an iframe. ```tsx import { Frame } from '@ark-ui/react/frame' export const Basic = () => { return ( {'body { background-color: #f0f0f0; }'}} >

                    Hello from inside the frame!

                    This content is rendered within our custom frame component using a Portal.

                    ) } ``` ### Injecting Script Using the `onMount` prop, you can inject a script into the iframe. ```tsx import { Frame } from '@ark-ui/react/frame' import { useRef } from 'react' export const Script = () => { const ref = useRef(null) return ( { const doc = ref.current?.contentDocument if (!doc) return const script = doc.createElement('script') script.innerHTML = 'console.log("Hello from inside the frame!")' doc.body.appendChild(script) }} style={{ border: '1px solid #ccc', width: '100%', height: 'var(--height)' }} >

                    Hello from inside the frame!

                    This content is rendered within our custom frame component using a Portal.

                    ) } ``` ### Custom src doc Use the `srcDoc` prop to specify the HTML content of the page to use in the iframe. ```tsx import { Frame } from '@ark-ui/react/frame' const srcDoc = `
                    ` export const SrcDoc = () => { return (

                    Hello from inside the frame!

                    This content is rendered within our custom frame component using a Portal.

                    The frame has custom initial content, including Font Awesome and Open Sans font.

                    ) } ``` ## API Reference ### Props **Component API Reference** #### React **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `head` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | Additional content to be inserted into the frame's | | `onMount` | `() => void` | No | Callback function to be executed when the frame is mounted | | `onUnmount` | `() => void` | No | Callback function to be executed when the frame is unmounted | #### Solid **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `head` | `number | boolean | Node | ArrayElement | (string & {})` | No | Additional content to be inserted into the frame's | | `onMount` | `() => void` | No | Callback function to be executed when the frame is mounted | | `onUnmount` | `() => void` | No | Callback function to be executed when the frame is unmounted | #### Vue **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `head` | `VNode | VNode[]` | No | | | `srcDoc` | `string` | No | | #### Svelte **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `head` | `Snippet<[]>` | No | Additional content to be inserted into the frame's | | `onMount` | `() => void` | No | Callback function to be executed when the frame is mounted | | `onUnmount` | `() => void` | No | Callback function to be executed when the frame is unmounted | | `ref` | `HTMLIFrameElement` | No | The bindable ref of the iframe | | `srcdoc` | `string` | No | The source document to be displayed in the frame | --- # Frame (VUE) ## Usage The `Frame` component is used to render a component in an iframe. - Tracks the size of the content and exposes them via css variables. - Support for `head` prop to inject scripts and styles. - Support for mount and unmount callbacks. ```jsx import { Frame } from '@ark-ui/react' ``` ## Examples ### Basic Wrap your component in the `Frame` component to render it in an iframe. ```vue ``` ### Injecting Script Using the `onMount` prop, you can inject a script into the iframe. ```vue ``` ### Custom src doc Use the `srcDoc` prop to specify the HTML content of the page to use in the iframe. ```vue ``` ## API Reference ### Props **Component API Reference** #### React **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `head` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | Additional content to be inserted into the frame's | | `onMount` | `() => void` | No | Callback function to be executed when the frame is mounted | | `onUnmount` | `() => void` | No | Callback function to be executed when the frame is unmounted | #### Solid **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `head` | `number | boolean | Node | ArrayElement | (string & {})` | No | Additional content to be inserted into the frame's | | `onMount` | `() => void` | No | Callback function to be executed when the frame is mounted | | `onUnmount` | `() => void` | No | Callback function to be executed when the frame is unmounted | #### Vue **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `head` | `VNode | VNode[]` | No | | | `srcDoc` | `string` | No | | #### Svelte **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `head` | `Snippet<[]>` | No | Additional content to be inserted into the frame's | | `onMount` | `() => void` | No | Callback function to be executed when the frame is mounted | | `onUnmount` | `() => void` | No | Callback function to be executed when the frame is unmounted | | `ref` | `HTMLIFrameElement` | No | The bindable ref of the iframe | | `srcdoc` | `string` | No | The source document to be displayed in the frame | --- # Frame (SVELTE) ## Usage The `Frame` component is used to render a component in an iframe. - Tracks the size of the content and exposes them via css variables. - Support for `head` prop to inject scripts and styles. - Support for mount and unmount callbacks. ```jsx import { Frame } from '@ark-ui/react' ``` ## Examples ### Basic Wrap your component in the `Frame` component to render it in an iframe. ```svelte {#snippet head()} {/snippet}

                    Hello from inside the frame!

                    This content is rendered within our custom frame component using a Portal.

                    ``` ### Injecting Script Using the `onMount` prop, you can inject a script into the iframe. ```svelte { const doc = frameRef?.contentDocument if (!doc) return const script = doc.createElement('script') script.innerHTML = 'console.log("Hello from inside the frame!")' doc.body.appendChild(script) }} style="border: 1px solid #ccc; width: 100%; height: var(--height)" >

                    Hello from inside the frame!

                    This content is rendered within our custom frame component using a Portal.

                    ``` ### Custom src doc Use the `srcDoc` prop to specify the HTML content of the page to use in the iframe. ```svelte

                    Hello from inside the frame!

                    This content is rendered within our custom frame component using a Portal.

                    The frame has custom initial content, including Font Awesome and Open Sans font.

                    ``` ## API Reference ### Props **Component API Reference** #### React **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `head` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | Additional content to be inserted into the frame's | | `onMount` | `() => void` | No | Callback function to be executed when the frame is mounted | | `onUnmount` | `() => void` | No | Callback function to be executed when the frame is unmounted | #### Solid **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `head` | `number | boolean | Node | ArrayElement | (string & {})` | No | Additional content to be inserted into the frame's | | `onMount` | `() => void` | No | Callback function to be executed when the frame is mounted | | `onUnmount` | `() => void` | No | Callback function to be executed when the frame is unmounted | #### Vue **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `head` | `VNode | VNode[]` | No | | | `srcDoc` | `string` | No | | #### Svelte **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `head` | `Snippet<[]>` | No | Additional content to be inserted into the frame's | | `onMount` | `() => void` | No | Callback function to be executed when the frame is mounted | | `onUnmount` | `() => void` | No | Callback function to be executed when the frame is unmounted | | `ref` | `HTMLIFrameElement` | No | The bindable ref of the iframe | | `srcdoc` | `string` | No | The source document to be displayed in the frame | --- # Frame (SOLID) ## Usage The `Frame` component is used to render a component in an iframe. - Tracks the size of the content and exposes them via css variables. - Support for `head` prop to inject scripts and styles. - Support for mount and unmount callbacks. ```jsx import { Frame } from '@ark-ui/react' ``` ## Examples ### Basic Wrap your component in the `Frame` component to render it in an iframe. ```tsx import { Frame } from '@ark-ui/solid/frame' export const Basic = () => { return ( {'body { background-color: #f0f0f0; }'}} >

                    Hello from inside the frame!

                    This content is rendered within our custom frame component using a Portal.

                    ) } ``` ### Injecting Script Using the `onMount` prop, you can inject a script into the iframe. ```tsx import { Frame } from '@ark-ui/solid/frame' export const Script = () => { let ref: HTMLIFrameElement | undefined return ( { const doc = ref?.contentDocument if (!doc) return const script = doc.createElement('script') script.innerHTML = 'console.log("Hello from inside the frame!")' doc.body.appendChild(script) }} style={{ border: '1px solid #ccc', width: '100%', height: 'var(--height)' }} >

                    Hello from inside the frame!

                    This content is rendered within our custom frame component using a Portal.

                    ) } ``` ### Custom src doc Use the `srcDoc` prop to specify the HTML content of the page to use in the iframe. ```tsx import { Frame } from '@ark-ui/solid/frame' const srcDoc = `
                    ` export const SrcDoc = () => { return (

                    Hello from inside the frame!

                    This content is rendered within our custom frame component using a Portal.

                    The frame has custom initial content, including Font Awesome and Open Sans font.

                    ) } ``` ## API Reference ### Props **Component API Reference** #### React **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `head` | `string | number | bigint | boolean | ReactElement> | Iterable | ReactPortal | Promise<...>` | No | Additional content to be inserted into the frame's | | `onMount` | `() => void` | No | Callback function to be executed when the frame is mounted | | `onUnmount` | `() => void` | No | Callback function to be executed when the frame is unmounted | #### Solid **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `head` | `number | boolean | Node | ArrayElement | (string & {})` | No | Additional content to be inserted into the frame's | | `onMount` | `() => void` | No | Callback function to be executed when the frame is mounted | | `onUnmount` | `() => void` | No | Callback function to be executed when the frame is unmounted | #### Vue **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `head` | `VNode | VNode[]` | No | | | `srcDoc` | `string` | No | | #### Svelte **Frame Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `head` | `Snippet<[]>` | No | Additional content to be inserted into the frame's | | `onMount` | `() => void` | No | Callback function to be executed when the frame is mounted | | `onUnmount` | `() => void` | No | Callback function to be executed when the frame is unmounted | | `ref` | `HTMLIFrameElement` | No | The bindable ref of the iframe | | `srcdoc` | `string` | No | The source document to be displayed in the frame | --- # Highlight (REACT) ## Usage The Highlight component takes a `text` prop containing the full text and a `query` prop specifying the text to highlight. It then renders the text with highlighted portions wrapped in `` tags. **Example: basic** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const Basic = () => (

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const Basic = () => (

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    ``` ### Dynamic Query Control the `query` prop with state to create an interactive search highlighting experience. **Example: dynamic-query** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import { useState } from 'react' import field from 'styles/field.module.css' import styles from 'styles/highlight.module.css' export const DynamicQuery = () => { const [query, setQuery] = useState('component') return (
                    setQuery(e.target.value)} />

                    ) } ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import { createSignal } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/highlight.module.css' export const DynamicQuery = () => { const [query, setQuery] = createSignal('component') return (
                    setQuery(e.target.value)} />

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte

                    ``` ### Multiple Queries You can highlight multiple terms by passing an array of strings to the `query` prop. **Example: multiple** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const Multiple = () => (

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const Multiple = () => (

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    ``` ### Case Sensitivity By default, the highlighting is case-sensitive. Use the `ignoreCase` prop to make it case-insensitive. **Example: ignore-case** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const IgnoreCase = () => (

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const IgnoreCase = () => (

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    ``` ### Match All By default, the Highlight component matches the first occurrence of the query. To highlight all occurrences of the query, set the `matchAll` prop to `true`. **Example: match-all** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const MatchAll = () => (
                    Match All

                    Match First Only

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const MatchAll = () => (
                    Match All

                    Match First Only

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Match All

                    Match First Only

                    ``` ### Exact Match By default, the Highlight component matches partial words. Use the `exactMatch` prop to only highlight whole words that match the query exactly. **Example: exact-match** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const ExactMatch = () => (
                    Partial Match

                    Exact Match

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const ExactMatch = () => (
                    Partial Match

                    Exact Match

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Partial Match

                    Exact Match

                    ``` ## API Reference **Component API Reference** #### React **Highlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `query` | `string | string[]` | Yes | The query to highlight in the text | | `text` | `string` | Yes | The text to highlight | | `exactMatch` | `boolean` | No | Whether to match whole words only | | `ignoreCase` | `boolean` | No | Whether to ignore case while matching | | `matchAll` | `boolean` | No | Whether to match multiple instances of the query | #### Solid **Highlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `query` | `string | string[]` | Yes | The query to highlight in the text | | `text` | `string` | Yes | The text to highlight | | `exactMatch` | `boolean` | No | Whether to match whole words only | | `ignoreCase` | `boolean` | No | Whether to ignore case while matching | | `matchAll` | `boolean` | No | Whether to match multiple instances of the query | #### Vue **Highlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `query` | `string | string[]` | Yes | The query to highlight in the text | | `text` | `string` | Yes | The text to highlight | | `exactMatch` | `boolean` | No | Whether to match the exact query | | `ignoreCase` | `boolean` | No | Whether to ignore case while matching | | `matchAll` | `boolean` | No | Whether to match multiple instances of the query | #### Svelte **Highlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `query` | `string | string[]` | Yes | The query to highlight in the text | | `text` | `string` | Yes | The text to highlight | | `exactMatch` | `boolean` | No | Whether to match whole words only | | `ignoreCase` | `boolean` | No | Whether to ignore case while matching | | `matchAll` | `boolean` | No | Whether to match multiple instances of the query | ## Customization The Highlight component wraps matched text in `` tags. Pass a `className` (or `class` in Solid/Svelte/Vue) to style the highlighted portions. ```tsx ``` Style the `mark` tags using CSS to customize the appearance of highlighted text. ```css .highlight-mark { background-color: #ffe5e4; color: #c9453b; border-radius: 0.125rem; } ``` --- # Highlight (VUE) ## Usage The Highlight component takes a `text` prop containing the full text and a `query` prop specifying the text to highlight. It then renders the text with highlighted portions wrapped in `` tags. **Example: basic** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const Basic = () => (

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const Basic = () => (

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    ``` ### Dynamic Query Control the `query` prop with state to create an interactive search highlighting experience. **Example: dynamic-query** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import { useState } from 'react' import field from 'styles/field.module.css' import styles from 'styles/highlight.module.css' export const DynamicQuery = () => { const [query, setQuery] = useState('component') return (
                    setQuery(e.target.value)} />

                    ) } ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import { createSignal } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/highlight.module.css' export const DynamicQuery = () => { const [query, setQuery] = createSignal('component') return (
                    setQuery(e.target.value)} />

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte

                    ``` ### Multiple Queries You can highlight multiple terms by passing an array of strings to the `query` prop. **Example: multiple** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const Multiple = () => (

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const Multiple = () => (

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    ``` ### Case Sensitivity By default, the highlighting is case-sensitive. Use the `ignoreCase` prop to make it case-insensitive. **Example: ignore-case** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const IgnoreCase = () => (

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const IgnoreCase = () => (

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    ``` ### Match All By default, the Highlight component matches the first occurrence of the query. To highlight all occurrences of the query, set the `matchAll` prop to `true`. **Example: match-all** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const MatchAll = () => (
                    Match All

                    Match First Only

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const MatchAll = () => (
                    Match All

                    Match First Only

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Match All

                    Match First Only

                    ``` ### Exact Match By default, the Highlight component matches partial words. Use the `exactMatch` prop to only highlight whole words that match the query exactly. **Example: exact-match** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const ExactMatch = () => (
                    Partial Match

                    Exact Match

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const ExactMatch = () => (
                    Partial Match

                    Exact Match

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Partial Match

                    Exact Match

                    ``` ## API Reference **Component API Reference** #### React **Highlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `query` | `string | string[]` | Yes | The query to highlight in the text | | `text` | `string` | Yes | The text to highlight | | `exactMatch` | `boolean` | No | Whether to match whole words only | | `ignoreCase` | `boolean` | No | Whether to ignore case while matching | | `matchAll` | `boolean` | No | Whether to match multiple instances of the query | #### Solid **Highlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `query` | `string | string[]` | Yes | The query to highlight in the text | | `text` | `string` | Yes | The text to highlight | | `exactMatch` | `boolean` | No | Whether to match whole words only | | `ignoreCase` | `boolean` | No | Whether to ignore case while matching | | `matchAll` | `boolean` | No | Whether to match multiple instances of the query | #### Vue **Highlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `query` | `string | string[]` | Yes | The query to highlight in the text | | `text` | `string` | Yes | The text to highlight | | `exactMatch` | `boolean` | No | Whether to match the exact query | | `ignoreCase` | `boolean` | No | Whether to ignore case while matching | | `matchAll` | `boolean` | No | Whether to match multiple instances of the query | #### Svelte **Highlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `query` | `string | string[]` | Yes | The query to highlight in the text | | `text` | `string` | Yes | The text to highlight | | `exactMatch` | `boolean` | No | Whether to match whole words only | | `ignoreCase` | `boolean` | No | Whether to ignore case while matching | | `matchAll` | `boolean` | No | Whether to match multiple instances of the query | ## Customization The Highlight component wraps matched text in `` tags. Pass a `className` (or `class` in Solid/Svelte/Vue) to style the highlighted portions. ```tsx ``` Style the `mark` tags using CSS to customize the appearance of highlighted text. ```css .highlight-mark { background-color: #ffe5e4; color: #c9453b; border-radius: 0.125rem; } ``` --- # Highlight (SVELTE) ## Usage The Highlight component takes a `text` prop containing the full text and a `query` prop specifying the text to highlight. It then renders the text with highlighted portions wrapped in `` tags. **Example: basic** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const Basic = () => (

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const Basic = () => (

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    ``` ### Dynamic Query Control the `query` prop with state to create an interactive search highlighting experience. **Example: dynamic-query** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import { useState } from 'react' import field from 'styles/field.module.css' import styles from 'styles/highlight.module.css' export const DynamicQuery = () => { const [query, setQuery] = useState('component') return (
                    setQuery(e.target.value)} />

                    ) } ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import { createSignal } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/highlight.module.css' export const DynamicQuery = () => { const [query, setQuery] = createSignal('component') return (
                    setQuery(e.target.value)} />

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte

                    ``` ### Multiple Queries You can highlight multiple terms by passing an array of strings to the `query` prop. **Example: multiple** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const Multiple = () => (

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const Multiple = () => (

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    ``` ### Case Sensitivity By default, the highlighting is case-sensitive. Use the `ignoreCase` prop to make it case-insensitive. **Example: ignore-case** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const IgnoreCase = () => (

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const IgnoreCase = () => (

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    ``` ### Match All By default, the Highlight component matches the first occurrence of the query. To highlight all occurrences of the query, set the `matchAll` prop to `true`. **Example: match-all** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const MatchAll = () => (
                    Match All

                    Match First Only

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const MatchAll = () => (
                    Match All

                    Match First Only

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Match All

                    Match First Only

                    ``` ### Exact Match By default, the Highlight component matches partial words. Use the `exactMatch` prop to only highlight whole words that match the query exactly. **Example: exact-match** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const ExactMatch = () => (
                    Partial Match

                    Exact Match

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const ExactMatch = () => (
                    Partial Match

                    Exact Match

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Partial Match

                    Exact Match

                    ``` ## API Reference **Component API Reference** #### React **Highlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `query` | `string | string[]` | Yes | The query to highlight in the text | | `text` | `string` | Yes | The text to highlight | | `exactMatch` | `boolean` | No | Whether to match whole words only | | `ignoreCase` | `boolean` | No | Whether to ignore case while matching | | `matchAll` | `boolean` | No | Whether to match multiple instances of the query | #### Solid **Highlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `query` | `string | string[]` | Yes | The query to highlight in the text | | `text` | `string` | Yes | The text to highlight | | `exactMatch` | `boolean` | No | Whether to match whole words only | | `ignoreCase` | `boolean` | No | Whether to ignore case while matching | | `matchAll` | `boolean` | No | Whether to match multiple instances of the query | #### Vue **Highlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `query` | `string | string[]` | Yes | The query to highlight in the text | | `text` | `string` | Yes | The text to highlight | | `exactMatch` | `boolean` | No | Whether to match the exact query | | `ignoreCase` | `boolean` | No | Whether to ignore case while matching | | `matchAll` | `boolean` | No | Whether to match multiple instances of the query | #### Svelte **Highlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `query` | `string | string[]` | Yes | The query to highlight in the text | | `text` | `string` | Yes | The text to highlight | | `exactMatch` | `boolean` | No | Whether to match whole words only | | `ignoreCase` | `boolean` | No | Whether to ignore case while matching | | `matchAll` | `boolean` | No | Whether to match multiple instances of the query | ## Customization The Highlight component wraps matched text in `` tags. Pass a `className` (or `class` in Solid/Svelte/Vue) to style the highlighted portions. ```tsx ``` Style the `mark` tags using CSS to customize the appearance of highlighted text. ```css .highlight-mark { background-color: #ffe5e4; color: #c9453b; border-radius: 0.125rem; } ``` --- # Highlight (SOLID) ## Usage The Highlight component takes a `text` prop containing the full text and a `query` prop specifying the text to highlight. It then renders the text with highlighted portions wrapped in `` tags. **Example: basic** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const Basic = () => (

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const Basic = () => (

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    ``` ### Dynamic Query Control the `query` prop with state to create an interactive search highlighting experience. **Example: dynamic-query** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import { useState } from 'react' import field from 'styles/field.module.css' import styles from 'styles/highlight.module.css' export const DynamicQuery = () => { const [query, setQuery] = useState('component') return (
                    setQuery(e.target.value)} />

                    ) } ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import { createSignal } from 'solid-js' import field from 'styles/field.module.css' import styles from 'styles/highlight.module.css' export const DynamicQuery = () => { const [query, setQuery] = createSignal('component') return (
                    setQuery(e.target.value)} />

                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte

                    ``` ### Multiple Queries You can highlight multiple terms by passing an array of strings to the `query` prop. **Example: multiple** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const Multiple = () => (

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const Multiple = () => (

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    ``` ### Case Sensitivity By default, the highlighting is case-sensitive. Use the `ignoreCase` prop to make it case-insensitive. **Example: ignore-case** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const IgnoreCase = () => (

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const IgnoreCase = () => (

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte

                    ``` ### Match All By default, the Highlight component matches the first occurrence of the query. To highlight all occurrences of the query, set the `matchAll` prop to `true`. **Example: match-all** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const MatchAll = () => (
                    Match All

                    Match First Only

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const MatchAll = () => (
                    Match All

                    Match First Only

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Match All

                    Match First Only

                    ``` ### Exact Match By default, the Highlight component matches partial words. Use the `exactMatch` prop to only highlight whole words that match the query exactly. **Example: exact-match** #### React ```tsx import { Highlight } from '@ark-ui/react/highlight' import styles from 'styles/highlight.module.css' export const ExactMatch = () => (
                    Partial Match

                    Exact Match

                    ) ``` #### Solid ```tsx import { Highlight } from '@ark-ui/solid/highlight' import styles from 'styles/highlight.module.css' export const ExactMatch = () => (
                    Partial Match

                    Exact Match

                    ) ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Partial Match

                    Exact Match

                    ``` ## API Reference **Component API Reference** #### React **Highlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `query` | `string | string[]` | Yes | The query to highlight in the text | | `text` | `string` | Yes | The text to highlight | | `exactMatch` | `boolean` | No | Whether to match whole words only | | `ignoreCase` | `boolean` | No | Whether to ignore case while matching | | `matchAll` | `boolean` | No | Whether to match multiple instances of the query | #### Solid **Highlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `query` | `string | string[]` | Yes | The query to highlight in the text | | `text` | `string` | Yes | The text to highlight | | `exactMatch` | `boolean` | No | Whether to match whole words only | | `ignoreCase` | `boolean` | No | Whether to ignore case while matching | | `matchAll` | `boolean` | No | Whether to match multiple instances of the query | #### Vue **Highlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `query` | `string | string[]` | Yes | The query to highlight in the text | | `text` | `string` | Yes | The text to highlight | | `exactMatch` | `boolean` | No | Whether to match the exact query | | `ignoreCase` | `boolean` | No | Whether to ignore case while matching | | `matchAll` | `boolean` | No | Whether to match multiple instances of the query | #### Svelte **Highlight Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `query` | `string | string[]` | Yes | The query to highlight in the text | | `text` | `string` | Yes | The text to highlight | | `exactMatch` | `boolean` | No | Whether to match whole words only | | `ignoreCase` | `boolean` | No | Whether to ignore case while matching | | `matchAll` | `boolean` | No | Whether to match multiple instances of the query | ## Customization The Highlight component wraps matched text in `` tags. Pass a `className` (or `class` in Solid/Svelte/Vue) to style the highlighted portions. ```tsx ``` Style the `mark` tags using CSS to customize the appearance of highlighted text. ```css .highlight-mark { background-color: #ffe5e4; color: #c9453b; border-radius: 0.125rem; } ``` --- # JSON Tree View (REACT) ## Anatomy To set up the JSON tree view correctly, you'll need to understand its anatomy and how we name its parts. > Each part includes a `data-part` attribute to help identify them in the DOM. ## Examples Learn how to use the `JsonTreeView` component in your project. Let's take a look at the most basic example: **Example: basic** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' export const Basic = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' export const Basic = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Different Data Types The JSON tree view can display various JavaScript data types including objects, arrays, primitives, and special values: **Example: array-data** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const testArray = [1, 2, 3, 4, 5] Object.defineProperties(testArray, { customProperty: { value: 'custom value', enumerable: false, writable: false }, anotherProperty: { value: 42, enumerable: false, writable: false }, }) export const ArrayData = () => { return ( { const sparse = [] sparse[0] = 'first' sparse[5] = 'sixth' return sparse })(), }} > } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const testArray = [1, 2, 3, 4, 5] Object.defineProperties(testArray, { customProperty: { value: 'custom value', enumerable: false, writable: false }, anotherProperty: { value: 42, enumerable: false, writable: false }, }) export const ArrayData = () => { return ( { const sparse = [] sparse[0] = 'first' sparse[5] = 'sixth' return sparse })(), }} > } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte { const sparse = [] sparse[0] = 'first' sparse[5] = 'sixth' return sparse })(), }} > {#snippet arrow()} {/snippet} ``` ### Functions and Methods Display JavaScript functions, async functions, and generators in your JSON tree: **Example: functions** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const data = [ function sum(a: number, b: number) { return a + b }, async (promises: Promise[]) => await Promise.all(promises), function* generator(a: number) { while (a > 0) { yield a - 1 } }, ] export const Functions = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const data = [ function sum(a: number, b: number) { return a + b }, async (promises: Promise[]) => await Promise.all(promises), function* generator(a: number) { while (a > 0) { yield a - 1 } }, ] export const Functions = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Regular Expressions Regular expressions are displayed with their pattern and flags: **Example: regex** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const data = { regex: /^[a-z0-9]+/g, case_insensitive: /^(?:[a-z0-9]+)foo.*?/i, } export const Regex = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const data = { regex: /^[a-z0-9]+/g, case_insensitive: /^(?:[a-z0-9]+)foo.*?/i, } export const Regex = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Error Objects Error objects and their stack traces can be visualized: **Example: errors** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const data = new Error('Error') export const Errors = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const data = new Error('Error') export const Errors = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Map and Set Objects Native JavaScript Map and Set objects are supported: **Example: map-and-set** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const data = new Map([ ['name', 'ark-ui-json-tree'], ['license', 'MIT'], ['elements', new Set(['ark-ui', 123, false, true, null, undefined, 456n])], [ 'nested', new Map([ [ 'taglines', new Set([ { name: 'ark-ui', feature: 'headless components' }, { name: 'ark-ui', feature: 'framework agnostic' }, { name: 'ark-ui', feature: 'accessible by default' }, ]), ], ]), ], ]) export const MapAndSet = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const data = new Map([ ['name', 'ark-ui-json-tree'], ['license', 'MIT'], ['elements', new Set(['ark-ui', 123, false, true, null, undefined, 456n])], [ 'nested', new Map([ [ 'taglines', new Set([ { name: 'ark-ui', feature: 'headless components' }, { name: 'ark-ui', feature: 'framework agnostic' }, { name: 'ark-ui', feature: 'accessible by default' }, ]), ], ]), ], ]) export const MapAndSet = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Controlling Expand Level Use the `defaultExpandedDepth` prop to control how many levels are expanded by default: **Example: expand-level** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' export const ExpandLevel = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' export const ExpandLevel = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Custom Value Rendering You can customize how specific values are rendered using the `renderValue` prop. This example shows how to make email addresses clickable: **Example: render-value** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' export const RenderValue = () => { return ( } renderValue={(node) => { if (node.type === 'text' && typeof node.value === 'string' && isEmail(node.value)) { return ( {node.value} ) } }} /> ) } const isEmail = (value: string) => { const strippedValue = value.replace(/^"(.*)"$/, '$1') return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(strippedValue) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' export const RenderValue = () => { return ( } renderValue={(node) => { if (node.type === 'text' && typeof node.value === 'string' && isEmail(node.value)) { return (
                    {node.value} ) } }} /> ) } const isEmail = (value: string) => { const strippedValue = value.replace(/^"(.*)"$/, '$1') return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(strippedValue) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} {#snippet renderValue(node)} {#if node.type === 'text' && typeof node.value === 'string'} {#if isEmail(node.value)} {node.value} {:else} {node.value} {/if} {/if} {/snippet} ``` ### Configuration Options The JSON tree view supports several configuration options to customize the display: ```tsx } /> ``` **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. **Example: root-provider** #### React ```tsx import { JsonTreeView, useJsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' export const RootProvider = () => { const jsonTreeView = useJsonTreeView({ defaultExpandedDepth: 1, data: { name: 'John Doe', age: 30, email: 'john.doe@example.com', tags: ['tag1', 'tag2', 'tag3'], address: { street: '123 Main St', city: 'Anytown', state: 'CA', zip: '12345', }, }, }) return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView, useJsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' export const RootProvider = () => { const jsonTreeView = useJsonTreeView({ defaultExpandedDepth: 1, data: { name: 'John Doe', age: 30, email: 'john.doe@example.com', tags: ['tag1', 'tag2', 'tag3'], address: { street: '123 Main St', city: 'Anytown', state: 'CA', zip: '12345', }, }, }) return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` > If you're using the `RootProvider` component, you don't need to use the `Root` component. ## API Reference **Component API Reference** #### React **JsonTreeViewRoot Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: JsonNode, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `collapseStringsAfterLength` | `number` | No | | | `data` | `{}` | No | The data to display in the tree. | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedDepth` | `number` | No | The default expand level. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `groupArraysAfterLength` | `number` | No | | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails>) => Promise[]>` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `maxPreviewItems` | `number` | No | | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails>) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails>) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails>) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails>) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails>) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails>) => void` | No | Called when the selection changes | | `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `showNonenumerable` | `boolean` | No | | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewRootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn>` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewTree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `arrow` | `ReactElement>` | No | The icon to use for the arrow. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indentGuide` | `boolean | ReactElement>` | No | The indent guide to use for the tree. | | `renderValue` | `(node: JsonNodeHastElement) => ReactNode` | No | The function to render the value of the node. | #### Solid **JsonTreeViewRoot Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: any, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `collapseStringsAfterLength` | `number` | No | | | `data` | `{}` | No | The data to display in the tree. | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedDepth` | `number` | No | The default expand level. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `groupArraysAfterLength` | `number` | No | | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `maxPreviewItems` | `number` | No | | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails) => void` | No | Called when the selection changes | | `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `showNonenumerable` | `boolean` | No | | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewRootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn>` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewTree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `arrow` | `number | boolean | Node | (string & {}) | ArrayElement` | No | The icon to use for the arrow. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indentGuide` | `number | boolean | Node | (string & {}) | ArrayElement` | No | The indent guide to use for the tree. | | `renderValue` | `(node: JsonNodeHastElement) => Element` | No | The function to render the value of the node. | #### Vue **JsonTreeViewRoot Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `object` | Yes | The data to display in the tree. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: JsonNode, indexPath: number[]) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node values | | `collapseStringsAfterLength` | `number` | No | | | `defaultCheckedValue` | `string[]` | No | The initial checked node values when rendered. Use when you don't need to control the checked node values. | | `defaultExpandedDepth` | `number` | No | The default expand level. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node values when rendered. Use when you don't need to control the expanded node values. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node values when rendered. Use when you don't need to control the selected node values. | | `expandedValue` | `string[]` | No | The controlled expanded node values | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The id of the focused node | | `groupArraysAfterLength` | `number` | No | | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node(value: string): string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails>) => Promise[]>` | No | A function that loads the children of a node. | | `maxPreviewItems` | `number` | No | | | `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. | | `selectedValue` | `string[]` | No | The controlled selected node values | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `showNonenumerable` | `boolean` | No | | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewRootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TreeViewApi>` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewTree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indentGuide` | `boolean` | No | | #### Svelte **JsonTreeViewRoot Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: JsonNode, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `collapseStringsAfterLength` | `number` | No | | | `data` | `{}` | No | The data to display in the tree. | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedDepth` | `number` | No | The default expand level. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `groupArraysAfterLength` | `number` | No | | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails>) => Promise[]>` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `maxPreviewItems` | `number` | No | | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails>) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails>) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails>) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails>) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails>) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails>) => void` | No | Called when the selection changes | | `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. | | `ref` | `Element` | No | | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `showNonenumerable` | `boolean` | No | | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewRootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn>` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewTree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `arrow` | `Snippet<[]>` | No | The icon to use for the arrow. | | `asChild` | `Snippet<[PropsFn<'ul'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indentGuide` | `boolean | Snippet<[]>` | No | The indent guide to use for the tree. | | `ref` | `Element` | No | | | `renderValue` | `Snippet<[JsonNodeHastElement]>` | No | The function to render the value of the node. | ## Accessibility The JSON tree view is built on top of the Tree View component and complies with the [Tree View WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/). ### Keyboard Support **`Tab`** Description: Moves focus to the tree view, placing the first tree view item in focus. **`Enter + Space`** Description: Selects the item or branch node **`ArrowDown`** Description: Moves focus to the next node **`ArrowUp`** Description: Moves focus to the previous node **`ArrowRight`** Description: When focus is on a closed branch node, opens the branch.
                    When focus is on an open branch node, moves focus to the first item node. **`ArrowLeft`** Description: When focus is on an open branch node, closes the node.
                    When focus is on an item or branch node, moves focus to its parent branch node. **`Home`** Description: Moves focus to first node without opening or closing a node. **`End`** Description: Moves focus to the last node that can be focused without expanding any nodes that are closed. **`a-z + A-Z`** Description: Focus moves to the next node with a name that starts with the typed character. The search logic ignores nodes that are descendants of closed branch. **`*`** Description: Expands all sibling nodes that are at the same depth as the focused node. **`Shift + ArrowDown`** Description: Moves focus to and toggles the selection state of the next node. **`Shift + ArrowUp`** Description: Moves focus to and toggles the selection state of the previous node. **`Ctrl + A`** Description: Selects all nodes in the tree. If all nodes are selected, unselects all nodes. --- # JSON Tree View (VUE) ## Anatomy To set up the JSON tree view correctly, you'll need to understand its anatomy and how we name its parts. > Each part includes a `data-part` attribute to help identify them in the DOM. ## Examples Learn how to use the `JsonTreeView` component in your project. Let's take a look at the most basic example: **Example: basic** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' export const Basic = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' export const Basic = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Different Data Types The JSON tree view can display various JavaScript data types including objects, arrays, primitives, and special values: **Example: array-data** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const testArray = [1, 2, 3, 4, 5] Object.defineProperties(testArray, { customProperty: { value: 'custom value', enumerable: false, writable: false }, anotherProperty: { value: 42, enumerable: false, writable: false }, }) export const ArrayData = () => { return ( { const sparse = [] sparse[0] = 'first' sparse[5] = 'sixth' return sparse })(), }} > } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const testArray = [1, 2, 3, 4, 5] Object.defineProperties(testArray, { customProperty: { value: 'custom value', enumerable: false, writable: false }, anotherProperty: { value: 42, enumerable: false, writable: false }, }) export const ArrayData = () => { return ( { const sparse = [] sparse[0] = 'first' sparse[5] = 'sixth' return sparse })(), }} > } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte { const sparse = [] sparse[0] = 'first' sparse[5] = 'sixth' return sparse })(), }} > {#snippet arrow()} {/snippet} ``` ### Functions and Methods Display JavaScript functions, async functions, and generators in your JSON tree: **Example: functions** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const data = [ function sum(a: number, b: number) { return a + b }, async (promises: Promise[]) => await Promise.all(promises), function* generator(a: number) { while (a > 0) { yield a - 1 } }, ] export const Functions = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const data = [ function sum(a: number, b: number) { return a + b }, async (promises: Promise[]) => await Promise.all(promises), function* generator(a: number) { while (a > 0) { yield a - 1 } }, ] export const Functions = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Regular Expressions Regular expressions are displayed with their pattern and flags: **Example: regex** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const data = { regex: /^[a-z0-9]+/g, case_insensitive: /^(?:[a-z0-9]+)foo.*?/i, } export const Regex = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const data = { regex: /^[a-z0-9]+/g, case_insensitive: /^(?:[a-z0-9]+)foo.*?/i, } export const Regex = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Error Objects Error objects and their stack traces can be visualized: **Example: errors** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const data = new Error('Error') export const Errors = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const data = new Error('Error') export const Errors = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Map and Set Objects Native JavaScript Map and Set objects are supported: **Example: map-and-set** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const data = new Map([ ['name', 'ark-ui-json-tree'], ['license', 'MIT'], ['elements', new Set(['ark-ui', 123, false, true, null, undefined, 456n])], [ 'nested', new Map([ [ 'taglines', new Set([ { name: 'ark-ui', feature: 'headless components' }, { name: 'ark-ui', feature: 'framework agnostic' }, { name: 'ark-ui', feature: 'accessible by default' }, ]), ], ]), ], ]) export const MapAndSet = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const data = new Map([ ['name', 'ark-ui-json-tree'], ['license', 'MIT'], ['elements', new Set(['ark-ui', 123, false, true, null, undefined, 456n])], [ 'nested', new Map([ [ 'taglines', new Set([ { name: 'ark-ui', feature: 'headless components' }, { name: 'ark-ui', feature: 'framework agnostic' }, { name: 'ark-ui', feature: 'accessible by default' }, ]), ], ]), ], ]) export const MapAndSet = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Controlling Expand Level Use the `defaultExpandedDepth` prop to control how many levels are expanded by default: **Example: expand-level** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' export const ExpandLevel = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' export const ExpandLevel = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Custom Value Rendering You can customize how specific values are rendered using the `renderValue` prop. This example shows how to make email addresses clickable: **Example: render-value** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' export const RenderValue = () => { return ( } renderValue={(node) => { if (node.type === 'text' && typeof node.value === 'string' && isEmail(node.value)) { return ( {node.value} ) } }} /> ) } const isEmail = (value: string) => { const strippedValue = value.replace(/^"(.*)"$/, '$1') return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(strippedValue) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' export const RenderValue = () => { return ( } renderValue={(node) => { if (node.type === 'text' && typeof node.value === 'string' && isEmail(node.value)) { return ( {node.value} ) } }} /> ) } const isEmail = (value: string) => { const strippedValue = value.replace(/^"(.*)"$/, '$1') return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(strippedValue) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} {#snippet renderValue(node)} {#if node.type === 'text' && typeof node.value === 'string'} {#if isEmail(node.value)} {node.value} {:else} {node.value} {/if} {/if} {/snippet} ``` ### Configuration Options The JSON tree view supports several configuration options to customize the display: ```tsx } /> ``` **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. **Example: root-provider** #### React ```tsx import { JsonTreeView, useJsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' export const RootProvider = () => { const jsonTreeView = useJsonTreeView({ defaultExpandedDepth: 1, data: { name: 'John Doe', age: 30, email: 'john.doe@example.com', tags: ['tag1', 'tag2', 'tag3'], address: { street: '123 Main St', city: 'Anytown', state: 'CA', zip: '12345', }, }, }) return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView, useJsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' export const RootProvider = () => { const jsonTreeView = useJsonTreeView({ defaultExpandedDepth: 1, data: { name: 'John Doe', age: 30, email: 'john.doe@example.com', tags: ['tag1', 'tag2', 'tag3'], address: { street: '123 Main St', city: 'Anytown', state: 'CA', zip: '12345', }, }, }) return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` > If you're using the `RootProvider` component, you don't need to use the `Root` component. ## API Reference **Component API Reference** #### React **JsonTreeViewRoot Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: JsonNode, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `collapseStringsAfterLength` | `number` | No | | | `data` | `{}` | No | The data to display in the tree. | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedDepth` | `number` | No | The default expand level. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `groupArraysAfterLength` | `number` | No | | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails>) => Promise[]>` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `maxPreviewItems` | `number` | No | | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails>) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails>) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails>) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails>) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails>) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails>) => void` | No | Called when the selection changes | | `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `showNonenumerable` | `boolean` | No | | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewRootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn>` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewTree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `arrow` | `ReactElement>` | No | The icon to use for the arrow. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indentGuide` | `boolean | ReactElement>` | No | The indent guide to use for the tree. | | `renderValue` | `(node: JsonNodeHastElement) => ReactNode` | No | The function to render the value of the node. | #### Solid **JsonTreeViewRoot Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: any, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `collapseStringsAfterLength` | `number` | No | | | `data` | `{}` | No | The data to display in the tree. | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedDepth` | `number` | No | The default expand level. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `groupArraysAfterLength` | `number` | No | | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `maxPreviewItems` | `number` | No | | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails) => void` | No | Called when the selection changes | | `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `showNonenumerable` | `boolean` | No | | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewRootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn>` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewTree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `arrow` | `number | boolean | Node | (string & {}) | ArrayElement` | No | The icon to use for the arrow. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indentGuide` | `number | boolean | Node | (string & {}) | ArrayElement` | No | The indent guide to use for the tree. | | `renderValue` | `(node: JsonNodeHastElement) => Element` | No | The function to render the value of the node. | #### Vue **JsonTreeViewRoot Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `object` | Yes | The data to display in the tree. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: JsonNode, indexPath: number[]) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node values | | `collapseStringsAfterLength` | `number` | No | | | `defaultCheckedValue` | `string[]` | No | The initial checked node values when rendered. Use when you don't need to control the checked node values. | | `defaultExpandedDepth` | `number` | No | The default expand level. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node values when rendered. Use when you don't need to control the expanded node values. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node values when rendered. Use when you don't need to control the selected node values. | | `expandedValue` | `string[]` | No | The controlled expanded node values | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The id of the focused node | | `groupArraysAfterLength` | `number` | No | | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node(value: string): string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails>) => Promise[]>` | No | A function that loads the children of a node. | | `maxPreviewItems` | `number` | No | | | `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. | | `selectedValue` | `string[]` | No | The controlled selected node values | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `showNonenumerable` | `boolean` | No | | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewRootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TreeViewApi>` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewTree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indentGuide` | `boolean` | No | | #### Svelte **JsonTreeViewRoot Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: JsonNode, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `collapseStringsAfterLength` | `number` | No | | | `data` | `{}` | No | The data to display in the tree. | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedDepth` | `number` | No | The default expand level. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `groupArraysAfterLength` | `number` | No | | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails>) => Promise[]>` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `maxPreviewItems` | `number` | No | | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails>) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails>) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails>) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails>) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails>) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails>) => void` | No | Called when the selection changes | | `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. | | `ref` | `Element` | No | | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `showNonenumerable` | `boolean` | No | | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewRootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn>` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewTree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `arrow` | `Snippet<[]>` | No | The icon to use for the arrow. | | `asChild` | `Snippet<[PropsFn<'ul'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indentGuide` | `boolean | Snippet<[]>` | No | The indent guide to use for the tree. | | `ref` | `Element` | No | | | `renderValue` | `Snippet<[JsonNodeHastElement]>` | No | The function to render the value of the node. | ## Accessibility The JSON tree view is built on top of the Tree View component and complies with the [Tree View WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/). ### Keyboard Support **`Tab`** Description: Moves focus to the tree view, placing the first tree view item in focus. **`Enter + Space`** Description: Selects the item or branch node **`ArrowDown`** Description: Moves focus to the next node **`ArrowUp`** Description: Moves focus to the previous node **`ArrowRight`** Description: When focus is on a closed branch node, opens the branch.
                    When focus is on an open branch node, moves focus to the first item node. **`ArrowLeft`** Description: When focus is on an open branch node, closes the node.
                    When focus is on an item or branch node, moves focus to its parent branch node. **`Home`** Description: Moves focus to first node without opening or closing a node. **`End`** Description: Moves focus to the last node that can be focused without expanding any nodes that are closed. **`a-z + A-Z`** Description: Focus moves to the next node with a name that starts with the typed character. The search logic ignores nodes that are descendants of closed branch. **`*`** Description: Expands all sibling nodes that are at the same depth as the focused node. **`Shift + ArrowDown`** Description: Moves focus to and toggles the selection state of the next node. **`Shift + ArrowUp`** Description: Moves focus to and toggles the selection state of the previous node. **`Ctrl + A`** Description: Selects all nodes in the tree. If all nodes are selected, unselects all nodes. --- # JSON Tree View (SVELTE) ## Anatomy To set up the JSON tree view correctly, you'll need to understand its anatomy and how we name its parts. > Each part includes a `data-part` attribute to help identify them in the DOM. ## Examples Learn how to use the `JsonTreeView` component in your project. Let's take a look at the most basic example: **Example: basic** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' export const Basic = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' export const Basic = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Different Data Types The JSON tree view can display various JavaScript data types including objects, arrays, primitives, and special values: **Example: array-data** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const testArray = [1, 2, 3, 4, 5] Object.defineProperties(testArray, { customProperty: { value: 'custom value', enumerable: false, writable: false }, anotherProperty: { value: 42, enumerable: false, writable: false }, }) export const ArrayData = () => { return ( { const sparse = [] sparse[0] = 'first' sparse[5] = 'sixth' return sparse })(), }} > } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const testArray = [1, 2, 3, 4, 5] Object.defineProperties(testArray, { customProperty: { value: 'custom value', enumerable: false, writable: false }, anotherProperty: { value: 42, enumerable: false, writable: false }, }) export const ArrayData = () => { return ( { const sparse = [] sparse[0] = 'first' sparse[5] = 'sixth' return sparse })(), }} > } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte { const sparse = [] sparse[0] = 'first' sparse[5] = 'sixth' return sparse })(), }} > {#snippet arrow()} {/snippet} ``` ### Functions and Methods Display JavaScript functions, async functions, and generators in your JSON tree: **Example: functions** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const data = [ function sum(a: number, b: number) { return a + b }, async (promises: Promise[]) => await Promise.all(promises), function* generator(a: number) { while (a > 0) { yield a - 1 } }, ] export const Functions = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const data = [ function sum(a: number, b: number) { return a + b }, async (promises: Promise[]) => await Promise.all(promises), function* generator(a: number) { while (a > 0) { yield a - 1 } }, ] export const Functions = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Regular Expressions Regular expressions are displayed with their pattern and flags: **Example: regex** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const data = { regex: /^[a-z0-9]+/g, case_insensitive: /^(?:[a-z0-9]+)foo.*?/i, } export const Regex = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const data = { regex: /^[a-z0-9]+/g, case_insensitive: /^(?:[a-z0-9]+)foo.*?/i, } export const Regex = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Error Objects Error objects and their stack traces can be visualized: **Example: errors** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const data = new Error('Error') export const Errors = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const data = new Error('Error') export const Errors = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Map and Set Objects Native JavaScript Map and Set objects are supported: **Example: map-and-set** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const data = new Map([ ['name', 'ark-ui-json-tree'], ['license', 'MIT'], ['elements', new Set(['ark-ui', 123, false, true, null, undefined, 456n])], [ 'nested', new Map([ [ 'taglines', new Set([ { name: 'ark-ui', feature: 'headless components' }, { name: 'ark-ui', feature: 'framework agnostic' }, { name: 'ark-ui', feature: 'accessible by default' }, ]), ], ]), ], ]) export const MapAndSet = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const data = new Map([ ['name', 'ark-ui-json-tree'], ['license', 'MIT'], ['elements', new Set(['ark-ui', 123, false, true, null, undefined, 456n])], [ 'nested', new Map([ [ 'taglines', new Set([ { name: 'ark-ui', feature: 'headless components' }, { name: 'ark-ui', feature: 'framework agnostic' }, { name: 'ark-ui', feature: 'accessible by default' }, ]), ], ]), ], ]) export const MapAndSet = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Controlling Expand Level Use the `defaultExpandedDepth` prop to control how many levels are expanded by default: **Example: expand-level** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' export const ExpandLevel = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' export const ExpandLevel = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Custom Value Rendering You can customize how specific values are rendered using the `renderValue` prop. This example shows how to make email addresses clickable: **Example: render-value** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' export const RenderValue = () => { return ( } renderValue={(node) => { if (node.type === 'text' && typeof node.value === 'string' && isEmail(node.value)) { return ( {node.value} ) } }} /> ) } const isEmail = (value: string) => { const strippedValue = value.replace(/^"(.*)"$/, '$1') return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(strippedValue) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' export const RenderValue = () => { return ( } renderValue={(node) => { if (node.type === 'text' && typeof node.value === 'string' && isEmail(node.value)) { return ( {node.value} ) } }} /> ) } const isEmail = (value: string) => { const strippedValue = value.replace(/^"(.*)"$/, '$1') return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(strippedValue) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} {#snippet renderValue(node)} {#if node.type === 'text' && typeof node.value === 'string'} {#if isEmail(node.value)} {node.value} {:else} {node.value} {/if} {/if} {/snippet} ``` ### Configuration Options The JSON tree view supports several configuration options to customize the display: ```tsx } /> ``` **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. **Example: root-provider** #### React ```tsx import { JsonTreeView, useJsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' export const RootProvider = () => { const jsonTreeView = useJsonTreeView({ defaultExpandedDepth: 1, data: { name: 'John Doe', age: 30, email: 'john.doe@example.com', tags: ['tag1', 'tag2', 'tag3'], address: { street: '123 Main St', city: 'Anytown', state: 'CA', zip: '12345', }, }, }) return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView, useJsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' export const RootProvider = () => { const jsonTreeView = useJsonTreeView({ defaultExpandedDepth: 1, data: { name: 'John Doe', age: 30, email: 'john.doe@example.com', tags: ['tag1', 'tag2', 'tag3'], address: { street: '123 Main St', city: 'Anytown', state: 'CA', zip: '12345', }, }, }) return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` > If you're using the `RootProvider` component, you don't need to use the `Root` component. ## API Reference **Component API Reference** #### React **JsonTreeViewRoot Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: JsonNode, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `collapseStringsAfterLength` | `number` | No | | | `data` | `{}` | No | The data to display in the tree. | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedDepth` | `number` | No | The default expand level. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `groupArraysAfterLength` | `number` | No | | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails>) => Promise[]>` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `maxPreviewItems` | `number` | No | | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails>) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails>) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails>) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails>) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails>) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails>) => void` | No | Called when the selection changes | | `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `showNonenumerable` | `boolean` | No | | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewRootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn>` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewTree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `arrow` | `ReactElement>` | No | The icon to use for the arrow. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indentGuide` | `boolean | ReactElement>` | No | The indent guide to use for the tree. | | `renderValue` | `(node: JsonNodeHastElement) => ReactNode` | No | The function to render the value of the node. | #### Solid **JsonTreeViewRoot Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: any, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `collapseStringsAfterLength` | `number` | No | | | `data` | `{}` | No | The data to display in the tree. | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedDepth` | `number` | No | The default expand level. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `groupArraysAfterLength` | `number` | No | | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `maxPreviewItems` | `number` | No | | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails) => void` | No | Called when the selection changes | | `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `showNonenumerable` | `boolean` | No | | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewRootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn>` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewTree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `arrow` | `number | boolean | Node | (string & {}) | ArrayElement` | No | The icon to use for the arrow. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indentGuide` | `number | boolean | Node | (string & {}) | ArrayElement` | No | The indent guide to use for the tree. | | `renderValue` | `(node: JsonNodeHastElement) => Element` | No | The function to render the value of the node. | #### Vue **JsonTreeViewRoot Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `object` | Yes | The data to display in the tree. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: JsonNode, indexPath: number[]) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node values | | `collapseStringsAfterLength` | `number` | No | | | `defaultCheckedValue` | `string[]` | No | The initial checked node values when rendered. Use when you don't need to control the checked node values. | | `defaultExpandedDepth` | `number` | No | The default expand level. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node values when rendered. Use when you don't need to control the expanded node values. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node values when rendered. Use when you don't need to control the selected node values. | | `expandedValue` | `string[]` | No | The controlled expanded node values | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The id of the focused node | | `groupArraysAfterLength` | `number` | No | | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node(value: string): string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails>) => Promise[]>` | No | A function that loads the children of a node. | | `maxPreviewItems` | `number` | No | | | `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. | | `selectedValue` | `string[]` | No | The controlled selected node values | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `showNonenumerable` | `boolean` | No | | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewRootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TreeViewApi>` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewTree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indentGuide` | `boolean` | No | | #### Svelte **JsonTreeViewRoot Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: JsonNode, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `collapseStringsAfterLength` | `number` | No | | | `data` | `{}` | No | The data to display in the tree. | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedDepth` | `number` | No | The default expand level. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `groupArraysAfterLength` | `number` | No | | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails>) => Promise[]>` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `maxPreviewItems` | `number` | No | | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails>) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails>) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails>) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails>) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails>) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails>) => void` | No | Called when the selection changes | | `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. | | `ref` | `Element` | No | | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `showNonenumerable` | `boolean` | No | | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewRootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn>` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewTree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `arrow` | `Snippet<[]>` | No | The icon to use for the arrow. | | `asChild` | `Snippet<[PropsFn<'ul'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indentGuide` | `boolean | Snippet<[]>` | No | The indent guide to use for the tree. | | `ref` | `Element` | No | | | `renderValue` | `Snippet<[JsonNodeHastElement]>` | No | The function to render the value of the node. | ## Accessibility The JSON tree view is built on top of the Tree View component and complies with the [Tree View WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/). ### Keyboard Support **`Tab`** Description: Moves focus to the tree view, placing the first tree view item in focus. **`Enter + Space`** Description: Selects the item or branch node **`ArrowDown`** Description: Moves focus to the next node **`ArrowUp`** Description: Moves focus to the previous node **`ArrowRight`** Description: When focus is on a closed branch node, opens the branch.
                    When focus is on an open branch node, moves focus to the first item node. **`ArrowLeft`** Description: When focus is on an open branch node, closes the node.
                    When focus is on an item or branch node, moves focus to its parent branch node. **`Home`** Description: Moves focus to first node without opening or closing a node. **`End`** Description: Moves focus to the last node that can be focused without expanding any nodes that are closed. **`a-z + A-Z`** Description: Focus moves to the next node with a name that starts with the typed character. The search logic ignores nodes that are descendants of closed branch. **`*`** Description: Expands all sibling nodes that are at the same depth as the focused node. **`Shift + ArrowDown`** Description: Moves focus to and toggles the selection state of the next node. **`Shift + ArrowUp`** Description: Moves focus to and toggles the selection state of the previous node. **`Ctrl + A`** Description: Selects all nodes in the tree. If all nodes are selected, unselects all nodes. --- # JSON Tree View (SOLID) ## Anatomy To set up the JSON tree view correctly, you'll need to understand its anatomy and how we name its parts. > Each part includes a `data-part` attribute to help identify them in the DOM. ## Examples Learn how to use the `JsonTreeView` component in your project. Let's take a look at the most basic example: **Example: basic** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' export const Basic = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' export const Basic = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Different Data Types The JSON tree view can display various JavaScript data types including objects, arrays, primitives, and special values: **Example: array-data** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const testArray = [1, 2, 3, 4, 5] Object.defineProperties(testArray, { customProperty: { value: 'custom value', enumerable: false, writable: false }, anotherProperty: { value: 42, enumerable: false, writable: false }, }) export const ArrayData = () => { return ( { const sparse = [] sparse[0] = 'first' sparse[5] = 'sixth' return sparse })(), }} > } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const testArray = [1, 2, 3, 4, 5] Object.defineProperties(testArray, { customProperty: { value: 'custom value', enumerable: false, writable: false }, anotherProperty: { value: 42, enumerable: false, writable: false }, }) export const ArrayData = () => { return ( { const sparse = [] sparse[0] = 'first' sparse[5] = 'sixth' return sparse })(), }} > } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte { const sparse = [] sparse[0] = 'first' sparse[5] = 'sixth' return sparse })(), }} > {#snippet arrow()} {/snippet} ``` ### Functions and Methods Display JavaScript functions, async functions, and generators in your JSON tree: **Example: functions** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const data = [ function sum(a: number, b: number) { return a + b }, async (promises: Promise[]) => await Promise.all(promises), function* generator(a: number) { while (a > 0) { yield a - 1 } }, ] export const Functions = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const data = [ function sum(a: number, b: number) { return a + b }, async (promises: Promise[]) => await Promise.all(promises), function* generator(a: number) { while (a > 0) { yield a - 1 } }, ] export const Functions = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Regular Expressions Regular expressions are displayed with their pattern and flags: **Example: regex** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const data = { regex: /^[a-z0-9]+/g, case_insensitive: /^(?:[a-z0-9]+)foo.*?/i, } export const Regex = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const data = { regex: /^[a-z0-9]+/g, case_insensitive: /^(?:[a-z0-9]+)foo.*?/i, } export const Regex = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Error Objects Error objects and their stack traces can be visualized: **Example: errors** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const data = new Error('Error') export const Errors = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const data = new Error('Error') export const Errors = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Map and Set Objects Native JavaScript Map and Set objects are supported: **Example: map-and-set** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' const data = new Map([ ['name', 'ark-ui-json-tree'], ['license', 'MIT'], ['elements', new Set(['ark-ui', 123, false, true, null, undefined, 456n])], [ 'nested', new Map([ [ 'taglines', new Set([ { name: 'ark-ui', feature: 'headless components' }, { name: 'ark-ui', feature: 'framework agnostic' }, { name: 'ark-ui', feature: 'accessible by default' }, ]), ], ]), ], ]) export const MapAndSet = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' const data = new Map([ ['name', 'ark-ui-json-tree'], ['license', 'MIT'], ['elements', new Set(['ark-ui', 123, false, true, null, undefined, 456n])], [ 'nested', new Map([ [ 'taglines', new Set([ { name: 'ark-ui', feature: 'headless components' }, { name: 'ark-ui', feature: 'framework agnostic' }, { name: 'ark-ui', feature: 'accessible by default' }, ]), ], ]), ], ]) export const MapAndSet = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Controlling Expand Level Use the `defaultExpandedDepth` prop to control how many levels are expanded by default: **Example: expand-level** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' export const ExpandLevel = () => { return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' export const ExpandLevel = () => { return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` ### Custom Value Rendering You can customize how specific values are rendered using the `renderValue` prop. This example shows how to make email addresses clickable: **Example: render-value** #### React ```tsx import { JsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' export const RenderValue = () => { return ( } renderValue={(node) => { if (node.type === 'text' && typeof node.value === 'string' && isEmail(node.value)) { return ( {node.value} ) } }} /> ) } const isEmail = (value: string) => { const strippedValue = value.replace(/^"(.*)"$/, '$1') return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(strippedValue) } ``` #### Solid ```tsx import { JsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' export const RenderValue = () => { return ( } renderValue={(node) => { if (node.type === 'text' && typeof node.value === 'string' && isEmail(node.value)) { return ( {node.value} ) } }} /> ) } const isEmail = (value: string) => { const strippedValue = value.replace(/^"(.*)"$/, '$1') return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(strippedValue) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} {#snippet renderValue(node)} {#if node.type === 'text' && typeof node.value === 'string'} {#if isEmail(node.value)} {node.value} {:else} {node.value} {/if} {/if} {/snippet} ``` ### Configuration Options The JSON tree view supports several configuration options to customize the display: ```tsx } /> ``` **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. **Example: root-provider** #### React ```tsx import { JsonTreeView, useJsonTreeView } from '@ark-ui/react/json-tree-view' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/json-tree-view.module.css' export const RootProvider = () => { const jsonTreeView = useJsonTreeView({ defaultExpandedDepth: 1, data: { name: 'John Doe', age: 30, email: 'john.doe@example.com', tags: ['tag1', 'tag2', 'tag3'], address: { street: '123 Main St', city: 'Anytown', state: 'CA', zip: '12345', }, }, }) return ( } /> ) } ``` #### Solid ```tsx import { JsonTreeView, useJsonTreeView } from '@ark-ui/solid/json-tree-view' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/json-tree-view.module.css' export const RootProvider = () => { const jsonTreeView = useJsonTreeView({ defaultExpandedDepth: 1, data: { name: 'John Doe', age: 30, email: 'john.doe@example.com', tags: ['tag1', 'tag2', 'tag3'], address: { street: '123 Main St', city: 'Anytown', state: 'CA', zip: '12345', }, }, }) return ( } /> ) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet arrow()} {/snippet} ``` > If you're using the `RootProvider` component, you don't need to use the `Root` component. ## API Reference **Component API Reference** #### React **JsonTreeViewRoot Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: JsonNode, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `collapseStringsAfterLength` | `number` | No | | | `data` | `{}` | No | The data to display in the tree. | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedDepth` | `number` | No | The default expand level. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `groupArraysAfterLength` | `number` | No | | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails>) => Promise[]>` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `maxPreviewItems` | `number` | No | | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails>) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails>) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails>) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails>) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails>) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails>) => void` | No | Called when the selection changes | | `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `showNonenumerable` | `boolean` | No | | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewRootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn>` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewTree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `arrow` | `ReactElement>` | No | The icon to use for the arrow. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indentGuide` | `boolean | ReactElement>` | No | The indent guide to use for the tree. | | `renderValue` | `(node: JsonNodeHastElement) => ReactNode` | No | The function to render the value of the node. | #### Solid **JsonTreeViewRoot Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: any, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `collapseStringsAfterLength` | `number` | No | | | `data` | `{}` | No | The data to display in the tree. | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedDepth` | `number` | No | The default expand level. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `groupArraysAfterLength` | `number` | No | | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails) => Promise` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `maxPreviewItems` | `number` | No | | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails) => void` | No | Called when the selection changes | | `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `showNonenumerable` | `boolean` | No | | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewRootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn>` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewTree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `arrow` | `number | boolean | Node | (string & {}) | ArrayElement` | No | The icon to use for the arrow. | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indentGuide` | `number | boolean | Node | (string & {}) | ArrayElement` | No | The indent guide to use for the tree. | | `renderValue` | `(node: JsonNodeHastElement) => Element` | No | The function to render the value of the node. | #### Vue **JsonTreeViewRoot Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `data` | `object` | Yes | The data to display in the tree. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: JsonNode, indexPath: number[]) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node values | | `collapseStringsAfterLength` | `number` | No | | | `defaultCheckedValue` | `string[]` | No | The initial checked node values when rendered. Use when you don't need to control the checked node values. | | `defaultExpandedDepth` | `number` | No | The default expand level. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node values when rendered. Use when you don't need to control the expanded node values. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node values when rendered. Use when you don't need to control the selected node values. | | `expandedValue` | `string[]` | No | The controlled expanded node values | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The id of the focused node | | `groupArraysAfterLength` | `number` | No | | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node(value: string): string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails>) => Promise[]>` | No | A function that loads the children of a node. | | `maxPreviewItems` | `number` | No | | | `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. | | `selectedValue` | `string[]` | No | The controlled selected node values | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `showNonenumerable` | `boolean` | No | | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewRootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `TreeViewApi>` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewTree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indentGuide` | `boolean` | No | | #### Svelte **JsonTreeViewRoot Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `canRename` | `(node: JsonNode, indexPath: IndexPath) => boolean` | No | Function to determine if a node can be renamed | | `checkedValue` | `string[]` | No | The controlled checked node value | | `collapseStringsAfterLength` | `number` | No | | | `data` | `{}` | No | The data to display in the tree. | | `defaultCheckedValue` | `string[]` | No | The initial checked node value when rendered. Use when you don't need to control the checked node value. | | `defaultExpandedDepth` | `number` | No | The default expand level. | | `defaultExpandedValue` | `string[]` | No | The initial expanded node ids when rendered. Use when you don't need to control the expanded node value. | | `defaultFocusedValue` | `string` | No | The initial focused node value when rendered. Use when you don't need to control the focused node value. | | `defaultSelectedValue` | `string[]` | No | The initial selected node value when rendered. Use when you don't need to control the selected node value. | | `expandedValue` | `string[]` | No | The controlled expanded node ids | | `expandOnClick` | `boolean` | No | Whether clicking on a branch should open it or not | | `focusedValue` | `string` | No | The value of the focused node | | `groupArraysAfterLength` | `number` | No | | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | No | The ids of the tree elements. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `loadChildren` | `(details: LoadChildrenDetails>) => Promise[]>` | No | Function to load children for a node asynchronously. When provided, branches will wait for this promise to resolve before expanding. | | `maxPreviewItems` | `number` | No | | | `onBeforeRename` | `(details: RenameCompleteDetails) => boolean` | No | Called before a rename is completed. Return false to prevent the rename. | | `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | Called when the checked value changes | | `onExpandedChange` | `(details: ExpandedChangeDetails>) => void` | No | Called when the tree is opened or closed | | `onFocusChange` | `(details: FocusChangeDetails>) => void` | No | Called when the focused node changes | | `onLoadChildrenComplete` | `(details: LoadChildrenCompleteDetails>) => void` | No | Called when a node finishes loading children | | `onLoadChildrenError` | `(details: LoadChildrenErrorDetails>) => void` | No | Called when loading children fails for one or more nodes | | `onRenameComplete` | `(details: RenameCompleteDetails) => void` | No | Called when a node label rename is completed | | `onRenameStart` | `(details: RenameStartDetails>) => void` | No | Called when a node starts being renamed | | `onSelectionChange` | `(details: SelectionChangeDetails>) => void` | No | Called when the selection changes | | `quotesOnKeys` | `boolean` | No | Whether to show quotes on the keys. | | `ref` | `Element` | No | | | `selectedValue` | `string[]` | No | The controlled selected node value | | `selectionMode` | `'single' | 'multiple'` | No | Whether the tree supports multiple selection - "single": only one node can be selected - "multiple": multiple nodes can be selected | | `showNonenumerable` | `boolean` | No | | | `typeahead` | `boolean` | No | Whether the tree supports typeahead search | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewRootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseTreeViewReturn>` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `ref` | `Element` | No | | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | **JsonTreeViewTree Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `arrow` | `Snippet<[]>` | No | The icon to use for the arrow. | | `asChild` | `Snippet<[PropsFn<'ul'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `indentGuide` | `boolean | Snippet<[]>` | No | The indent guide to use for the tree. | | `ref` | `Element` | No | | | `renderValue` | `Snippet<[JsonNodeHastElement]>` | No | The function to render the value of the node. | ## Accessibility The JSON tree view is built on top of the Tree View component and complies with the [Tree View WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/). ### Keyboard Support **`Tab`** Description: Moves focus to the tree view, placing the first tree view item in focus. **`Enter + Space`** Description: Selects the item or branch node **`ArrowDown`** Description: Moves focus to the next node **`ArrowUp`** Description: Moves focus to the previous node **`ArrowRight`** Description: When focus is on a closed branch node, opens the branch.
                    When focus is on an open branch node, moves focus to the first item node. **`ArrowLeft`** Description: When focus is on an open branch node, closes the node.
                    When focus is on an item or branch node, moves focus to its parent branch node. **`Home`** Description: Moves focus to first node without opening or closing a node. **`End`** Description: Moves focus to the last node that can be focused without expanding any nodes that are closed. **`a-z + A-Z`** Description: Focus moves to the next node with a name that starts with the typed character. The search logic ignores nodes that are descendants of closed branch. **`*`** Description: Expands all sibling nodes that are at the same depth as the focused node. **`Shift + ArrowDown`** Description: Moves focus to and toggles the selection state of the next node. **`Shift + ArrowUp`** Description: Moves focus to and toggles the selection state of the previous node. **`Ctrl + A`** Description: Selects all nodes in the tree. If all nodes are selected, unselects all nodes. --- # Locale (REACT) ## Setup The `LocaleProvider` component sets the locale for your app, formatting dates, numbers, and other locale-specific data. > **Note:** If no `LocaleProvider` is setup, the default locale for the app will be `en-US` and therefore the direction > will be `ltr`. ## Usage To access the current locale and direction settings, use the `useLocaleContext` hook. ## API Reference **Component API Reference** #### React **LocaleProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `locale` | `string` | Yes | The locale to use for the application. | #### Solid **LocaleProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `locale` | `string` | Yes | The locale to use for the application. | #### Vue **LocaleProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `locale` | `string` | Yes | The locale to use for the application. | #### Svelte **LocaleProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `locale` | `string` | Yes | The locale to use for the application. | --- # Locale (VUE) ## Setup The `LocaleProvider` component sets the locale for your app, formatting dates, numbers, and other locale-specific data. > **Note:** If no `LocaleProvider` is setup, the default locale for the app will be `en-US` and therefore the direction > will be `ltr`. ## Usage To access the current locale and direction settings, use the `useLocaleContext` hook. ## API Reference **Component API Reference** #### React **LocaleProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `locale` | `string` | Yes | The locale to use for the application. | #### Solid **LocaleProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `locale` | `string` | Yes | The locale to use for the application. | #### Vue **LocaleProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `locale` | `string` | Yes | The locale to use for the application. | #### Svelte **LocaleProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `locale` | `string` | Yes | The locale to use for the application. | --- # Locale (SVELTE) ## Setup The `LocaleProvider` component sets the locale for your app, formatting dates, numbers, and other locale-specific data. > **Note:** If no `LocaleProvider` is setup, the default locale for the app will be `en-US` and therefore the direction > will be `ltr`. ## Usage To access the current locale and direction settings, use the `useLocaleContext` hook. ## API Reference **Component API Reference** #### React **LocaleProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `locale` | `string` | Yes | The locale to use for the application. | #### Solid **LocaleProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `locale` | `string` | Yes | The locale to use for the application. | #### Vue **LocaleProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `locale` | `string` | Yes | The locale to use for the application. | #### Svelte **LocaleProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `locale` | `string` | Yes | The locale to use for the application. | --- # Locale (SOLID) ## Setup The `LocaleProvider` component sets the locale for your app, formatting dates, numbers, and other locale-specific data. > **Note:** If no `LocaleProvider` is setup, the default locale for the app will be `en-US` and therefore the direction > will be `ltr`. ## Usage To access the current locale and direction settings, use the `useLocaleContext` hook. ## API Reference **Component API Reference** #### React **LocaleProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `locale` | `string` | Yes | The locale to use for the application. | #### Solid **LocaleProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `locale` | `string` | Yes | The locale to use for the application. | #### Vue **LocaleProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `locale` | `string` | Yes | The locale to use for the application. | #### Svelte **LocaleProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `locale` | `string` | Yes | The locale to use for the application. | --- # Presence (REACT) ## Examples By default the child component starts out as hidden and remains hidden after the `present` state is toggled off. This is useful for situations where the element needs to be hidden initially and continue to stay hidden after its presence is no longer required. **Example: basic** #### React ```tsx import { Presence } from '@ark-ui/react/presence' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const Basic = () => { const [present, setPresent] = useState(false) return (
                    Content
                    ) } ``` #### Solid ```tsx import { Presence } from '@ark-ui/solid/presence' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const Basic = () => { const [present, setPresent] = createSignal(false) return (
                    Content
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Content
                    ``` ### Lazy Mount To delay the mounting of a child component until the `present` prop is set to true, use the `lazyMount` prop: **Example: lazy-mount** #### React ```tsx import { Presence } from '@ark-ui/react/presence' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const LazyMount = () => { const [present, setPresent] = useState(false) return (
                    Lazy Mounted
                    ) } ``` #### Solid ```tsx import { Presence } from '@ark-ui/solid/presence' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const LazyMount = () => { const [present, setPresent] = createSignal(false) return (
                    Lazy Mounted
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Lazy Mounted
                    ``` ### Unmount on Exit To remove the child component from the DOM when it's not present, use the `unmountOnExit` prop: **Example: unmount-on-exit** #### React ```tsx import { Presence } from '@ark-ui/react/presence' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const UnmountOnExit = () => { const [present, setPresent] = useState(false) return (
                    Unmount on Exit
                    ) } ``` #### Solid ```tsx import { Presence } from '@ark-ui/solid/presence' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const UnmountOnExit = () => { const [present, setPresent] = createSignal(false) return (
                    Unmount on Exit
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Unmount on Exit
                    ``` ### Combining Lazy Mount and Unmount on Exit Both `lazyMount` and `unmountOnExit` can be combined for a component to be mounted only when it's present and to be unmounted when it's no longer present: **Example: lazy-mount-and-unmount-on-exit** #### React ```tsx import { Presence } from '@ark-ui/react/presence' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const LazyMountAndUnmountOnExit = () => { const [present, setPresent] = useState(false) return (
                    Lazy + Unmount
                    ) } ``` #### Solid ```tsx import { Presence } from '@ark-ui/solid/presence' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const LazyMountAndUnmountOnExit = () => { const [present, setPresent] = createSignal(false) return (
                    Lazy + Unmount
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Lazy + Unmount
                    ``` ## API Reference **Component API Reference** #### React **Presence Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Solid **Presence Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Vue **Presence Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Svelte **Presence Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `ref` | `Element` | No | | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | --- # Presence (VUE) ## Examples By default the child component starts out as hidden and remains hidden after the `present` state is toggled off. This is useful for situations where the element needs to be hidden initially and continue to stay hidden after its presence is no longer required. **Example: basic** #### React ```tsx import { Presence } from '@ark-ui/react/presence' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const Basic = () => { const [present, setPresent] = useState(false) return (
                    Content
                    ) } ``` #### Solid ```tsx import { Presence } from '@ark-ui/solid/presence' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const Basic = () => { const [present, setPresent] = createSignal(false) return (
                    Content
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Content
                    ``` ### Lazy Mount To delay the mounting of a child component until the `present` prop is set to true, use the `lazyMount` prop: **Example: lazy-mount** #### React ```tsx import { Presence } from '@ark-ui/react/presence' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const LazyMount = () => { const [present, setPresent] = useState(false) return (
                    Lazy Mounted
                    ) } ``` #### Solid ```tsx import { Presence } from '@ark-ui/solid/presence' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const LazyMount = () => { const [present, setPresent] = createSignal(false) return (
                    Lazy Mounted
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Lazy Mounted
                    ``` ### Unmount on Exit To remove the child component from the DOM when it's not present, use the `unmountOnExit` prop: **Example: unmount-on-exit** #### React ```tsx import { Presence } from '@ark-ui/react/presence' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const UnmountOnExit = () => { const [present, setPresent] = useState(false) return (
                    Unmount on Exit
                    ) } ``` #### Solid ```tsx import { Presence } from '@ark-ui/solid/presence' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const UnmountOnExit = () => { const [present, setPresent] = createSignal(false) return (
                    Unmount on Exit
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Unmount on Exit
                    ``` ### Combining Lazy Mount and Unmount on Exit Both `lazyMount` and `unmountOnExit` can be combined for a component to be mounted only when it's present and to be unmounted when it's no longer present: **Example: lazy-mount-and-unmount-on-exit** #### React ```tsx import { Presence } from '@ark-ui/react/presence' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const LazyMountAndUnmountOnExit = () => { const [present, setPresent] = useState(false) return (
                    Lazy + Unmount
                    ) } ``` #### Solid ```tsx import { Presence } from '@ark-ui/solid/presence' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const LazyMountAndUnmountOnExit = () => { const [present, setPresent] = createSignal(false) return (
                    Lazy + Unmount
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Lazy + Unmount
                    ``` ## API Reference **Component API Reference** #### React **Presence Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Solid **Presence Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Vue **Presence Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Svelte **Presence Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `ref` | `Element` | No | | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | --- # Presence (SVELTE) ## Examples By default the child component starts out as hidden and remains hidden after the `present` state is toggled off. This is useful for situations where the element needs to be hidden initially and continue to stay hidden after its presence is no longer required. **Example: basic** #### React ```tsx import { Presence } from '@ark-ui/react/presence' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const Basic = () => { const [present, setPresent] = useState(false) return (
                    Content
                    ) } ``` #### Solid ```tsx import { Presence } from '@ark-ui/solid/presence' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const Basic = () => { const [present, setPresent] = createSignal(false) return (
                    Content
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Content
                    ``` ### Lazy Mount To delay the mounting of a child component until the `present` prop is set to true, use the `lazyMount` prop: **Example: lazy-mount** #### React ```tsx import { Presence } from '@ark-ui/react/presence' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const LazyMount = () => { const [present, setPresent] = useState(false) return (
                    Lazy Mounted
                    ) } ``` #### Solid ```tsx import { Presence } from '@ark-ui/solid/presence' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const LazyMount = () => { const [present, setPresent] = createSignal(false) return (
                    Lazy Mounted
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Lazy Mounted
                    ``` ### Unmount on Exit To remove the child component from the DOM when it's not present, use the `unmountOnExit` prop: **Example: unmount-on-exit** #### React ```tsx import { Presence } from '@ark-ui/react/presence' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const UnmountOnExit = () => { const [present, setPresent] = useState(false) return (
                    Unmount on Exit
                    ) } ``` #### Solid ```tsx import { Presence } from '@ark-ui/solid/presence' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const UnmountOnExit = () => { const [present, setPresent] = createSignal(false) return (
                    Unmount on Exit
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Unmount on Exit
                    ``` ### Combining Lazy Mount and Unmount on Exit Both `lazyMount` and `unmountOnExit` can be combined for a component to be mounted only when it's present and to be unmounted when it's no longer present: **Example: lazy-mount-and-unmount-on-exit** #### React ```tsx import { Presence } from '@ark-ui/react/presence' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const LazyMountAndUnmountOnExit = () => { const [present, setPresent] = useState(false) return (
                    Lazy + Unmount
                    ) } ``` #### Solid ```tsx import { Presence } from '@ark-ui/solid/presence' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const LazyMountAndUnmountOnExit = () => { const [present, setPresent] = createSignal(false) return (
                    Lazy + Unmount
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Lazy + Unmount
                    ``` ## API Reference **Component API Reference** #### React **Presence Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Solid **Presence Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Vue **Presence Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Svelte **Presence Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `ref` | `Element` | No | | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | --- # Presence (SOLID) ## Examples By default the child component starts out as hidden and remains hidden after the `present` state is toggled off. This is useful for situations where the element needs to be hidden initially and continue to stay hidden after its presence is no longer required. **Example: basic** #### React ```tsx import { Presence } from '@ark-ui/react/presence' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const Basic = () => { const [present, setPresent] = useState(false) return (
                    Content
                    ) } ``` #### Solid ```tsx import { Presence } from '@ark-ui/solid/presence' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const Basic = () => { const [present, setPresent] = createSignal(false) return (
                    Content
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Content
                    ``` ### Lazy Mount To delay the mounting of a child component until the `present` prop is set to true, use the `lazyMount` prop: **Example: lazy-mount** #### React ```tsx import { Presence } from '@ark-ui/react/presence' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const LazyMount = () => { const [present, setPresent] = useState(false) return (
                    Lazy Mounted
                    ) } ``` #### Solid ```tsx import { Presence } from '@ark-ui/solid/presence' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const LazyMount = () => { const [present, setPresent] = createSignal(false) return (
                    Lazy Mounted
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Lazy Mounted
                    ``` ### Unmount on Exit To remove the child component from the DOM when it's not present, use the `unmountOnExit` prop: **Example: unmount-on-exit** #### React ```tsx import { Presence } from '@ark-ui/react/presence' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const UnmountOnExit = () => { const [present, setPresent] = useState(false) return (
                    Unmount on Exit
                    ) } ``` #### Solid ```tsx import { Presence } from '@ark-ui/solid/presence' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const UnmountOnExit = () => { const [present, setPresent] = createSignal(false) return (
                    Unmount on Exit
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Unmount on Exit
                    ``` ### Combining Lazy Mount and Unmount on Exit Both `lazyMount` and `unmountOnExit` can be combined for a component to be mounted only when it's present and to be unmounted when it's no longer present: **Example: lazy-mount-and-unmount-on-exit** #### React ```tsx import { Presence } from '@ark-ui/react/presence' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const LazyMountAndUnmountOnExit = () => { const [present, setPresent] = useState(false) return (
                    Lazy + Unmount
                    ) } ``` #### Solid ```tsx import { Presence } from '@ark-ui/solid/presence' import { createSignal } from 'solid-js' import button from 'styles/button.module.css' import styles from 'styles/presence.module.css' export const LazyMountAndUnmountOnExit = () => { const [present, setPresent] = createSignal(false) return (
                    Lazy + Unmount
                    ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
                    Lazy + Unmount
                    ``` ## API Reference **Component API Reference** #### React **Presence Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Solid **Presence Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Vue **Presence Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | #### Svelte **Presence Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state | | `present` | `boolean` | No | Whether the node is present (controlled by the user) | | `ref` | `Element` | No | | | `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |