Accordion
Vertical stack of expandable sections. Single or multiple open at once, with built-in keyboard navigation.
Overview
Accordion is the coordinated-disclosure primitive: a vertical stack of sections where readers expand and collapse to reveal content in place. Built on Radix Accordion, it ships two modes via type: "single" (one open at a time, optionally with collapsible so the open item can also close) and "multiple" (any number open simultaneously).
Reach for Accordion when siblings should remain visible - the vertical context is preserved, so readers can scan headings without losing their place. When you want full context swaps, use Tabs instead. Don't nest more than two levels deep; depth past that becomes a scavenger hunt.
For a single, isolated "show more" toggle, prefer Collapsible - it's the building block Accordion is composed on.
Preview
'use client';import { Accordion, AccordionContent, AccordionItem, AccordionTrigger,} from '@gremorie/rx-display';export function AccordionPreview() { return ( <Accordion type="single" collapsible defaultValue="reg" className="w-full"> <AccordionItem value="reg"> <AccordionTrigger>What is the registry?</AccordionTrigger> <AccordionContent> The registry is the single source of truth for Gremorie primitives. Each item lists its files, dependencies, and peers so an agent can install it deterministically. </AccordionContent> </AccordionItem> <AccordionItem value="mcp"> <AccordionTrigger>What does the MCP server do?</AccordionTrigger> <AccordionContent> It exposes the registry as MCP tools so any compatible client can search, read, and apply Gremorie items. </AccordionContent> </AccordionItem> <AccordionItem value="rx"> <AccordionTrigger>What is rx-?</AccordionTrigger> <AccordionContent> rx- is the React edition prefix. ng- is the Angular edition prefix. Both ship side by side. </AccordionContent> </AccordionItem> </Accordion> );}Anatomy
Accordion the Radix Root; carries type + collapsible
└─ AccordionItem one section, identified by value
├─ AccordionTrigger the clickable header (renders the chevron)
└─ AccordionContent the collapsible body (animated open/close)Installation
bash npx gremorie@latest add rx-accordion bash pnpm dlx gremorie@latest add rx-accordion bash yarn dlx gremorie@latest add rx-accordion bash bunx --bun gremorie@latest add rx-accordion Usage
import {
Accordion,
AccordionItem,
AccordionTrigger,
AccordionContent,
} from "@gremorie/rx-display";
export function Example() {
return (
<Accordion type="single" collapsible defaultValue="item-1">
<AccordionItem value="item-1">
<AccordionTrigger>What is the registry?</AccordionTrigger>
<AccordionContent>
The single source of truth for Gremorie primitives.
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger>What does the MCP server do?</AccordionTrigger>
<AccordionContent>
Exposes the registry as MCP tools.
</AccordionContent>
</AccordionItem>
</Accordion>
);
}The Angular edition of this component ships from source today (see the workbench for the side-by-side); its registry entry is coming next.
API
<Accordion>
Wraps Radix Accordion.Root.
| Prop | Type | Default | Description |
|---|---|---|---|
type | "single" | "multiple" | - | Required. "single" lets one item open at a time; "multiple" lets any number open. |
collapsible | boolean | false | Only with type="single". When true, clicking the open item closes it. |
value | string | string[] | - | Controlled value(s) of the open item(s). string for single, string[] for multiple. |
defaultValue | string | string[] | - | Uncontrolled default. |
onValueChange | (value: string | string[]) => void | - | Fires when an item opens or closes. |
disabled | boolean | false | Disables all items. |
orientation | "vertical" | "horizontal" | "vertical" | Affects keyboard navigation (Arrow keys). |
dir | "ltr" | "rtl" | "ltr" | Reading direction. |
<AccordionItem>
A single section. Wraps Radix Accordion.Item.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | - | Required. Unique identifier - this is what value / defaultValue on Root references. |
disabled | boolean | false | Disables this specific item. |
Renders with border-b last:border-b-0 for clean stacking.
<AccordionTrigger>
The clickable header. Wraps Radix Accordion.Trigger inside an Accordion.Header for proper semantics. Includes a ChevronDown icon that rotates 180 degrees when the item opens ([&[data-state=open]>svg]:rotate-180).
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Extra classes merged via cn. |
<AccordionContent>
The collapsible content panel. Animates open and closed using data-[state=closed]:animate-accordion-up and data-[state=open]:animate-accordion-down. Wraps content in an inner div with pt-0 pb-4.
Composition
<Accordion>owns the state (type, controlledvalueor uncontrolleddefaultValue).- One or more
<AccordionItem>with uniquevalueprops. - Inside each item: an
<AccordionTrigger>(the header) followed by<AccordionContent>(the body).
The Trigger renders inside an internal Accordion.Header so the heading semantics are correct - you do not need to wrap the trigger in your own <h3>.
Variations
Multiple sections open
'use client';import { Accordion, AccordionContent, AccordionItem, AccordionTrigger,} from '@gremorie/rx-display';export function AccordionMultiplePreview() { return ( <Accordion type="multiple" defaultValue={['release-1', 'release-2']} className="w-full" > <AccordionItem value="release-1"> <AccordionTrigger>v1.0 - Initial release</AccordionTrigger> <AccordionContent>57 primitives across 8 packages.</AccordionContent> </AccordionItem> <AccordionItem value="release-2"> <AccordionTrigger>v1.1 - AI primitives</AccordionTrigger> <AccordionContent>Added Message, Prompt, Response.</AccordionContent> </AccordionItem> <AccordionItem value="release-3"> <AccordionTrigger>v1.2 - Patterns layer</AccordionTrigger> <AccordionContent> Composed patterns: DataTable, FormBuilder. </AccordionContent> </AccordionItem> </Accordion> );}With type="multiple", any number of items can stay open at once. Pass an array to defaultValue to open several on load - useful for release notes or feature breakdowns.
Disabled item
'use client';import { Accordion, AccordionContent, AccordionItem, AccordionTrigger,} from '@gremorie/rx-display';export function AccordionDisabledPreview() { return ( <Accordion type="single" collapsible className="w-full"> <AccordionItem value="account"> <AccordionTrigger>Account</AccordionTrigger> <AccordionContent> Update your profile, email, and password. </AccordionContent> </AccordionItem> <AccordionItem value="billing" disabled> <AccordionTrigger>Billing (upgrade required)</AccordionTrigger> <AccordionContent> Billing settings are available on paid plans. </AccordionContent> </AccordionItem> <AccordionItem value="notifications"> <AccordionTrigger>Notifications</AccordionTrigger> <AccordionContent> Choose which events send you an email. </AccordionContent> </AccordionItem> </Accordion> );}Set disabled on an individual AccordionItem to lock it. Disabled triggers render with aria-disabled="true" and are skipped during arrow-key navigation.
Controlled value
const [open, setOpen] = useState<string>('billing');
<Accordion type="single" collapsible value={open} onValueChange={setOpen}>
<AccordionItem value="account">
<AccordionTrigger>Account</AccordionTrigger>
<AccordionContent>...</AccordionContent>
</AccordionItem>
<AccordionItem value="billing">
<AccordionTrigger>Billing</AccordionTrigger>
<AccordionContent>...</AccordionContent>
</AccordionItem>
</Accordion>;Accessibility
- WAI-ARIA Accordion pattern: Radix sets
role="region"on each content panel witharia-labelledbypointing at its trigger; the trigger getsaria-expandedandaria-controls. - Keyboard:
Tabmoves between triggers;SpaceorEntertoggles the focused trigger;ArrowDown/ArrowUpnavigate between triggers (loops at the ends).HomeandEndjump to first and last. - Headings: each trigger is wrapped in an internal
Accordion.Header(renders as a<h3>by default) so screen readers announce the section as a heading. - Disabled items: render with
aria-disabled="true"and are skipped during arrow-key navigation. - Reduced motion: animations use
data-[state]selectors withprefers-reduced-motionqueries inherited from the keyframes config.
Related
- Collapsible - the single-section building block Accordion is composed on.
- Tabs - use when readers should context-swap rather than browse siblings.
- Card - common host for an Accordion inside a settings panel.