Components
Accordion
A vertically stacked set of headers that each reveal a section of content, letting users expand only what they need.
Basic usage
Use type="single" with collapsible so only one section is open at a time. Every AccordionItem needs a unique value. The open and close slide is driven by the accordion-down / accordion-up keyframes that @comitor/ui/styles.css already imports — nothing to configure.
Multiple open sections
Set type="multiple" to let several sections stay open at once. In this mode defaultValue takes an array of item values.
Disabled items
Add disabled to an individual AccordionItem to lock it. It is skipped during keyboard navigation and dimmed to 50% opacity.
Restyling the parts
The default look is a stack of dividers. Because every part merges your className through cn, a card list is a two-class change on AccordionItem.
Where each className actually lands
AccordionItem→ merged ontoborder-b last:border-b-0.AccordionTrigger→ merged onto the button. The chevron is appended by the component and rotates through[&[data-state=open]>svg]:rotate-180, so pass your own icon as a sibling rather than expecting to replace it.AccordionContent→ applied to the inner padding wrapper (pt-0 pb-4), not to the animated Radix element. That means the height animation and itsoverflow-hiddencannot be turned off fromclassName— useCollapsibleif you need full control of the transition.
Props
Every part forwards the full Radix prop set and exports its own prop type — AccordionProps, AccordionItemProps, AccordionTriggerProps and AccordionContentProps.
Accordion — the root that owns which items are open.
| Prop | Type | Default | Description |
|---|---|---|---|
typerequired | 'single' | 'multiple' | — | Whether one or several items can be open at the same time. |
collapsible | boolean | false | When type is 'single', allows closing the open item so all items can be collapsed. |
defaultValue | string | string[] | — | The item(s) open by default in uncontrolled mode. Use an array when type is multiple. |
value | string | string[] | — | The controlled open item(s). Pair with onValueChange. |
onValueChange | (value: string | string[]) => void | — | Callback fired when the open item(s) change. |
disabled | boolean | false | Disables every item in the accordion. |
orientation | 'vertical' | 'horizontal' | 'vertical' | Which arrow keys move focus between triggers. The shipped styling assumes vertical. |
dir | 'ltr' | 'rtl' | 'ltr' | Reading direction, affecting arrow-key navigation. |
className | string | — | Additional Tailwind classes. The root carries no styling of its own. |
AccordionItem — one header plus its panel.
| Prop | Type | Default | Description |
|---|---|---|---|
valuerequired | string | — | Unique id for the item — this is what defaultValue and value refer to. |
disabled | boolean | false | Locks this item only. Its trigger becomes a natively disabled button. |
className | string | — | Merged onto the default border-b last:border-b-0 divider. |
AccordionTrigger and AccordionContent.
| Prop | Type | Default | Description |
|---|---|---|---|
childrenrequired | React.ReactNode | — | On AccordionTrigger, the header label; the chevron is appended for you. |
className | string | — | On AccordionTrigger, merged onto the button. On AccordionContent, applied to the inner padding wrapper (pt-0 pb-4) rather than the animated element. |
asChild | boolean | false | On the Radix type but unusable here: AccordionTrigger appends the chevron as a second child, and Radix Slot throws on more than one child. Restyle the trigger through className instead. |
Accessibility
- Follows the WAI-ARIA Accordion pattern — each trigger is a
<button>wired witharia-expandedandaria-controls, and the panel points back witharia-labelledby. AccordionTriggerrenders its ownAccordionPrimitive.Header, which is a fixed<h3>. Place the accordion so that level fits the surrounding heading outline — there is no prop to change it.- Fully keyboard operable: Enter and Space toggle a section, while Arrow keys, Home, and End move focus between triggers.
- Each trigger shows a brand gold
focus-visiblering —ring-ring/50offset against the page background — and the chevron rotates to reflect the open or closed state. - Disabled items render a natively
disabledbutton carryingdata-disabled, so they leave the tab order and the arrow-key ring, and dim to 50% opacity. - With
type="single"and nocollapsible, the open trigger is markedaria-disabledbecause it can no longer be toggled shut — addcollapsibleif that reads as a bug to your users.