Components
A vertically stacked set of interactive headings that each reveal a section of content.
Playground
type="single" only one item stays open at a time; add collapsible so the open item can also be closed again. Items are divided by a bottom border and the caret flips automatically with the open state.import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@workspace/ui/components/accordion"
<Accordion type="single" collapsible defaultValue="item-1">
<AccordionItem value="item-1">
<AccordionTrigger>Is it accessible?</AccordionTrigger>
<AccordionContent>
Yes. It adheres to the WAI-ARIA accordion design pattern.
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger>Is it styled?</AccordionTrigger>
<AccordionContent>
Yes. Triggers, carets and content all read from the design tokens.
</AccordionContent>
</AccordionItem>
</Accordion>type="multiple" lets several items stay expanded at once — the value becomes an array of item values. Multiple accordions are always collapsible, so the collapsible prop does not apply.<Accordion type="multiple" defaultValue={["item-1", "item-2"]}>
<AccordionItem value="item-1">
<AccordionTrigger>Tokens</AccordionTrigger>
<AccordionContent>
CSS variables define every color, radius and font.
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger>Components</AccordionTrigger>
<AccordionContent>
Sixty building blocks composed from Radix primitives.
</AccordionContent>
</AccordionItem>
</Accordion>disabled on an AccordionItem to prevent it from being toggled: the trigger dims, ignores pointer events and is skipped by keyboard navigation. Disabling the root Accordion disables every item at once.<Accordion type="single" collapsible defaultValue="item-1">
<AccordionItem value="item-1">
<AccordionTrigger>Available</AccordionTrigger>
<AccordionContent>This item toggles normally.</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2" disabled>
<AccordionTrigger>Disabled</AccordionTrigger>
<AccordionContent>This content cannot be reached.</AccordionContent>
</AccordionItem>
</Accordion>rounded-md border px-4 and space them with gap-2 on the root for a card-per-item look.<Accordion type="single" collapsible defaultValue="item-1" className="gap-2">
<AccordionItem value="item-1" className="rounded-md border px-4">
<AccordionTrigger>Is it accessible?</AccordionTrigger>
<AccordionContent>
Yes. It adheres to the WAI-ARIA accordion design pattern.
</AccordionContent>
</AccordionItem>
</Accordion><Card className="w-full max-w-md">
<CardHeader>
<CardTitle>Frequently asked questions</CardTitle>
<CardDescription>
Everything about the Westy design system.
</CardDescription>
</CardHeader>
<CardContent>
<Accordion type="single" collapsible defaultValue="item-1">
<AccordionItem value="item-1">
<AccordionTrigger>Is it accessible?</AccordionTrigger>
<AccordionContent>
Yes. It adheres to the WAI-ARIA accordion design pattern.
</AccordionContent>
</AccordionItem>
</Accordion>
</CardContent>
</Card>dir prop (or a surrounding Direction provider) for its behavior but does not write a DOM attribute, while the styles flip through logical properties (text-start, ms-auto) that follow the HTML dir. Set both: the attribute on a wrapping element and the prop on the root.<div dir="rtl">
<Accordion type="single" collapsible defaultValue="item-1" dir="rtl">
<AccordionItem value="item-1">
<AccordionTrigger>هل المكوّن متاح للجميع؟</AccordionTrigger>
<AccordionContent>
نعم، يتبع نمط WAI-ARIA لسهولة الوصول.
</AccordionContent>
</AccordionItem>
</Accordion>
</div>aria-expanded and aria-controls, and each panel is a labelled region. Enter or Space toggles the focused item, ArrowDown and ArrowUp move focus between triggers, Home and End jump to the first and last, and disabled triggers are skipped.<div data-slot="accordion">
<div data-slot="accordion-item" data-state="open">
<h3 data-orientation="vertical">
<button aria-expanded="true" aria-controls="radix-:r1:">
Is it accessible?
</button>
</h3>
<div role="region" id="radix-:r1:" aria-labelledby="radix-:r0:">
Yes. It adheres to the WAI-ARIA accordion design pattern.
</div>
</div>
</div>| Component | Prop | Default |
|---|---|---|
| Accordion | type: "single" | "multiple" | required |
| Accordion | collapsible?: boolean (single only) | false |
| Accordion | defaultValue?: string | string[] | — |
| Accordion | value?: string | string[], onValueChange?: (value) => void | — |
| Accordion | disabled?: boolean | false |
| Accordion | dir?: "ltr" | "rtl" | inherited |
| Accordion | orientation?: "vertical" | "horizontal" | "vertical" |
| AccordionItem | value: string | required |
| AccordionItem | disabled?: boolean | false |
<Accordion data-slot="accordion" /> // Root — vertical flex column <AccordionItem data-slot="accordion-item" /> // divider border between items <AccordionTrigger data-slot="accordion-trigger" /> // <button aria-expanded> in a heading, caret icons <AccordionContent data-slot="accordion-content" /> // collapsible region, height animation
Tokens used
7 design tokens consumed by the Accordion component.
--ring
Ring
--muted-foreground
Muted Foreground
--foreground
Foreground
--border
Border
--radius-md
Radius 0.8× (8px)
--text-sm
Text Small (14px)
--spacing
Spacing unit (4px)