Accordion
Preview: Divided
One collapsible section. Group several in an Accordion. Height animates via --disclosure-panel-height.
Import
import { Accordion, AccordionItem } from '@marbleui/ui'Props
<Accordion>
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | 'divided' | 'separated' | 'divided' | divided: hairlines between items (use default AccordionItems). separated: gaps (use variant="card" items). |
Also accepts React Aria props (80).
<AccordionItem>alias of Disclosure
| Prop | Type | Default | Description |
|---|---|---|---|
| children *required | ReactNode | — | |
| title *required | ReactNode | — | |
| icon | ReactNode | — | |
| level | 1 | 2 | 3 | 4 | 5 | 6 | 3 | Heading level of the trigger (default 3). Match it to the surrounding outline. |
| variant | 'default' | 'card' | 'divided' |
Also accepts React Aria props (79).
Accessibility
Keyboard interaction, focus management and ARIA semantics come from the underlying primitive: React Aria DisclosureGroup. Follow the primitive's docs for the full keyboard map.
Usage notes
Group of collapsible sections, such as an FAQ. For a single standalone collapsible section use Disclosure; for mutually exclusive content panels use Tabs.
<Accordion defaultExpandedKeys={['trial']}>
<AccordionItem id="trial" title="Is there a free trial?">Yes, 14 days.</AccordionItem>
<AccordionItem id="cancel" title="Can I cancel anytime?">Yes.</AccordionItem>
</Accordion>
AccordionItemisDisclosure; every item needs a uniqueid.- By default only one item is open. Add
allowsMultipleExpandedto allow several. - Controlled:
expandedKeysandonExpandedChange; uncontrolled:defaultExpandedKeys. variant="separated"onAccordionpairs withvariant="card"on the items; the defaultdividedpairs with default items.
Example source · show· hide
import { Accordion, AccordionItem } from './accordion'
const faq = [
{ id: 'trial', q: 'Is there a free trial?', a: 'Yes. Every plan starts with 14 days free, no card required.' },
{ id: 'cancel', q: 'Can I cancel anytime?', a: 'Cancel from billing settings. You keep access until the end of the period.' },
{ id: 'seats', q: 'How do seats work?', a: 'You pay for active members. Guests and viewers are always free.' },
]
export const styles = {
Divided: () => (
<Accordion className="w-[26rem]" defaultExpandedKeys={['trial']}>
{faq.map((f) => (
<AccordionItem key={f.id} id={f.id} title={f.q}>{f.a}</AccordionItem>
))}
</Accordion>
),
Separated: () => (
<Accordion variant="separated" className="w-[26rem]" allowsMultipleExpanded>
{faq.map((f) => (
<AccordionItem key={f.id} id={f.id} variant="card" title={f.q}>{f.a}</AccordionItem>
))}
</Accordion>
),
}Source: packages/ui/src/accordion/accordion.tsx
Catalog
- Category
- layout
- Priority
- Foundation
- Primitive
- react-aria
- React Aria
- DisclosureGroup
- Base UI
- Accordion