Navigation
Accordion
A stack of expandable answers.
When to use it: Use it to hide optional detail while keeping headings visible.
Example
import {
Accordion,
AccordionHeader,
AccordionItem,
AccordionPanel,
AccordionTrigger,
} from "@comp0/react";
import { ChevronDownIcon } from "@heroicons/react/16/solid";
export function Example() {
return (
<Accordion
as="div"
className="divide-y divide-zinc-950/10 rounded border border-zinc-950/10 dark:divide-white/10 dark:border-white/10"
defaultValue="shipping"
>
<AccordionItem value="shipping">
<AccordionHeader className="m-0">
<AccordionTrigger className="group flex w-full items-center justify-between px-3 py-2.5 text-left text-base text-zinc-900 sm:py-2 sm:text-sm dark:text-zinc-100">
Shipping{" "}
<ChevronDownIcon
className="size-4 text-zinc-400 transition-transform duration-150 ease-out group-data-open:rotate-180 motion-reduce:transition-none"
aria-hidden="true"
/>
</AccordionTrigger>
</AccordionHeader>
<AccordionPanel className="docs-accordion-panel grid grid-rows-[1fr] overflow-hidden transition-[grid-template-rows] duration-150 ease-out motion-reduce:transition-none [&[hidden]]:grid-rows-[0fr]">
<div className="min-h-0 overflow-hidden">
<div className="px-3 pb-3 text-base text-zinc-600 sm:text-sm dark:text-zinc-400">
Orders leave our warehouse in two business days.
</div>
</div>
</AccordionPanel>
</AccordionItem>
<AccordionItem value="returns">
<AccordionHeader className="m-0">
<AccordionTrigger className="group flex w-full items-center justify-between px-3 py-2.5 text-left text-base text-zinc-900 sm:py-2 sm:text-sm dark:text-zinc-100">
Returns{" "}
<ChevronDownIcon
className="size-4 text-zinc-400 transition-transform duration-150 ease-out group-data-open:rotate-180 motion-reduce:transition-none"
aria-hidden="true"
/>
</AccordionTrigger>
</AccordionHeader>
<AccordionPanel className="docs-accordion-panel grid grid-rows-[1fr] overflow-hidden transition-[grid-template-rows] duration-150 ease-out motion-reduce:transition-none [&[hidden]]:grid-rows-[0fr]">
<div className="min-h-0 overflow-hidden">
<div className="px-3 pb-3 text-base text-zinc-600 sm:text-sm dark:text-zinc-400">
Returns are accepted within 30 days.
</div>
</div>
</AccordionPanel>
</AccordionItem>
</Accordion>
);
}Anatomy
Dashed frames are invisible state providers; shaded shapes own real DOM. Numbered pins match the list below.
A wireframe sketch of the assembled component. Each numbered marker matches a part in the list that follows.
Accordion
Open-item state provider. Does not add a DOM element.
AccordionItem
Owns an item wrapper. Owns a DOM element.
AccordionHeader
Heading wrapper. Owns a DOM element.
AccordionTrigger
Native button that opens its panel. Owns a DOM element.
AccordionPanel
Revealed region. Owns a DOM element.
Step by step
- 1
Add the main part
Start Accordion with one AccordionItem and value.
- 2
Add the supporting parts
Put Header and Trigger before the matching Panel.
- 3
Make the behavior clear
Use defaultValue for the item that should begin open.
Exampletsx <Accordion defaultValue="one"><AccordionItem value="one"><AccordionHeader><AccordionTrigger>Details</AccordionTrigger></AccordionHeader><AccordionPanel>More information.</AccordionPanel></AccordionItem></Accordion>
Keyboard
- ↓
- Moves to next trigger.
- ↑
- Moves to previous trigger.
- ↵
- Toggles the item.
- Space
- Toggles the item.
Forms and accessibility
No native form behavior.
Accessibility checklist
- Write trigger headings that describe the hidden content.
- Keep the expanded state visually clear.
- Do not hide important error messages inside a collapsed item.
API reference
import { Accordion, AccordionHeader, AccordionItem, AccordionPanel, AccordionTrigger } from "@comp0/react";Accordion
Context onlyOpen-item state provider.
| Prop | Type | Description |
|---|---|---|
type | "single" | "multiple" | How many items may stay open. |
value | string | string[] | Controlled open items. |
defaultValue | string | string[] | Initial open items. |
onChange | (value) => void | Receives the next open items. |
collapsible | boolean | Allows closing the last open item. |
AccordionItem
DOM elementOwns an item wrapper.
| Prop | Type | Description |
|---|---|---|
value | string | Identity used by the root’s open state. |
disabled | boolean | Disables the item. |
AccordionHeader
DOM elementHeading wrapper.
| Prop | Type | Description |
|---|---|---|
level | 1 | 2 | 3 | 4 | 5 | 6 | Heading element to render; defaults to h3. |
AccordionTrigger
DOM elementNative button that opens its panel.
| Prop | Type | Description |
|---|---|---|
disabled | boolean | Disables this trigger on top of the item's disabled state. |
AccordionPanel
DOM elementRevealed region.
| Prop | Type | Description |
|---|---|---|
role | "region" | "group" | Use group when many panels would flood landmarks. |
Style hooks
Attributes that appear while a state is true. Target them with Tailwind data variants such as data-open:bg-zinc-100, or with any CSS selector.
[data-open]on AccordionItem, AccordionTrigger, AccordionPanel
- The item is expanded.
[data-disabled]on AccordionItem, AccordionTrigger
- The trigger is disabled.