--- name: ark-ui description: Builds accessible UI components with Ark UI headless primitives for React, Vue, Solid, and Svelte. Use when creating custom-styled components with robust state management and accessibility built-in. --- # Ark UI Headless component library with 45+ accessible components powered by state machines. ## Quick Start ```bash npm install @ark-ui/react ``` ```tsx import { Accordion } from '@ark-ui/react' function App() { return ( What is React? React is a JavaScript library for building user interfaces. ) } ``` ## Core Concepts ### Anatomy Pattern Ark UI uses compound components with dot notation: ```tsx ``` ### Data Attributes for Styling Components expose state via data attributes: ```css /* Base styles */ [data-scope="accordion"][data-part="trigger"] { display: flex; justify-content: space-between; } /* State-based styles */ [data-state="open"] { background-color: #f0f0f0; } [data-state="closed"] { background-color: white; } [data-disabled] { opacity: 0.5; } [data-focus] { outline: 2px solid blue; } ``` ### With Tailwind CSS ```tsx Trigger Text ``` ## Components ### Accordion ```tsx import { Accordion } from '@ark-ui/react' import { ChevronDownIcon } from 'lucide-react' function AccordionDemo() { return ( {items.map((item) => ( {item.title} {item.content} ))} ) } ``` ### Dialog ```tsx import { Dialog, Portal } from '@ark-ui/react' function DialogDemo() { return ( Open Dialog Dialog Title Dialog description text here.
Cancel
) } ``` ### Menu ```tsx import { Menu, Portal } from '@ark-ui/react' function MenuDemo() { return ( Open Menu Edit Duplicate Delete ) } ``` ### Select ```tsx import { Select, Portal } from '@ark-ui/react' import { CheckIcon, ChevronDownIcon } from 'lucide-react' const items = [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, ] function SelectDemo() { return ( Framework {items.map((item) => ( {item.label} ))} ) } ``` ### Combobox ```tsx import { Combobox, Portal } from '@ark-ui/react' import { useState } from 'react' const allItems = [ { label: 'React', value: 'react' }, { label: 'Vue', value: 'vue' }, { label: 'Svelte', value: 'svelte' }, { label: 'Solid', value: 'solid' }, ] function ComboboxDemo() { const [items, setItems] = useState(allItems) const handleInputChange = ({ inputValue }) => { const filtered = allItems.filter((item) => item.label.toLowerCase().includes(inputValue.toLowerCase()) ) setItems(filtered) } return ( Framework {items.map((item) => ( {item.label} ))} ) } ``` ### Tabs ```tsx import { Tabs } from '@ark-ui/react' function TabsDemo() { return ( React Vue Svelte React content Vue content Svelte content ) } ``` ### Switch ```tsx import { Switch } from '@ark-ui/react' function SwitchDemo() { return ( Enable notifications ) } ``` ### Checkbox ```tsx import { Checkbox } from '@ark-ui/react' import { CheckIcon, MinusIcon } from 'lucide-react' function CheckboxDemo() { return ( Accept terms ) } ``` ### Slider ```tsx import { Slider } from '@ark-ui/react' function SliderDemo() { return ( Volume ) } // Range slider ``` ### Tooltip ```tsx import { Tooltip, Portal } from '@ark-ui/react' function TooltipDemo() { return ( Hover me Tooltip content ) } ``` ### Popover ```tsx import { Popover, Portal } from '@ark-ui/react' function PopoverDemo() { return ( Open Popover Popover Title This is the popover content. ) } ``` ### DatePicker ```tsx import { DatePicker, Portal } from '@ark-ui/react' function DatePickerDemo() { return ( Date {(api) => ( <> {api.weekDays.map((day, i) => ( {day.narrow} ))} {api.weeks.map((week, i) => ( {week.map((day, j) => ( {day.day} ))} ))} )} ) } ``` ### Toast ```tsx import { Toaster, createToaster } from '@ark-ui/react' const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 16, }) function ToastDemo() { return ( <> {(toast) => ( {toast.title} {toast.description} Close )} ) } ``` ## Controlled vs Uncontrolled ```tsx // Uncontrolled (internal state) {/* ... */} // Controlled (external state) const [value, setValue] = useState(['item-1']) setValue(details.value)}> {/* ... */} ``` ## API Patterns ### onValueChange ```tsx { console.log(details.value) // Selected value(s) console.log(details.items) // Selected item(s) }} > ``` ### onOpenChange ```tsx { console.log(details.open) // boolean }} > ``` ## Best Practices 1. **Use Portal** - Wrap overlays in Portal for proper stacking 2. **Style with data attributes** - Use `data-[state=open]` patterns 3. **Provide accessible labels** - Use Label components 4. **Handle keyboard** - All components have built-in keyboard support 5. **Use HiddenInput** - For form integration with checkboxes/switches ## Reference Files - [references/components.md](references/components.md) - Complete component list - [references/patterns.md](references/patterns.md) - Common patterns