Accordion
A stack of headings that each expand to reveal a section of content.
A lookalike domain, acme-login.co, was registered on 21 October and serves a copy of the Acme sign-in page.
<Accordion defaultValue={["summary"]} className="max-w-md">
<AccordionItem value="summary">
<AccordionTrigger>What happened</AccordionTrigger>
<AccordionContent>
<p>
A lookalike domain, acme-login.co, was registered on 21 October and
serves a copy of the Acme sign-in page.
</p>
</AccordionContent>
</AccordionItem>
<AccordionItem value="impact">
<AccordionTrigger>Who is affected</AccordionTrigger>
<AccordionContent>
<p>
Employees and customers who sign in at acme.com. No credentials have
been observed in leak sources yet.
</p>
</AccordionContent>
</AccordionItem>
<AccordionItem value="action">
<AccordionTrigger>Recommended action</AccordionTrigger>
<AccordionContent>
<p>
Request a takedown from the registrar and add the domain to the
email gateway block list.
</p>
</AccordionContent>
</AccordionItem>
</Accordion>Usage
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@zenoxai/ui/components/accordion"
<Accordion defaultValue={["summary"]}>
<AccordionItem value="summary">
<AccordionTrigger>What happened</AccordionTrigger>
<AccordionContent>A lookalike domain was registered.</AccordionContent>
</AccordionItem>
</Accordion>
Use an accordion to shorten a long page of secondary detail: alert explanations, remediation
steps, settings grouped by topic. The value is always an array, even when only one item can be
open. Give every item a stable value so you can open it from defaultValue or control it
with value and onValueChange.
Do not hide information the user needs to act on. For a single show/hide region, use Collapsible. To switch between views of equal weight, use Tabs.
Examples
Multiple open items
By default, opening an item closes the others. Set multiple to let several stay open, for
example when the user compares groups of findings.
4 hosts expose TLS 1.0. 2 certificates expire within 30 days.
SPF and DMARC are configured. DKIM is missing on mx2.acme.com.
<Accordion multiple defaultValue={["web", "mail"]} className="max-w-md">
<AccordionItem value="web">
<AccordionTrigger>Web servers (12)</AccordionTrigger>
<AccordionContent>
<p>4 hosts expose TLS 1.0. 2 certificates expire within 30 days.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem value="mail">
<AccordionTrigger>Mail servers (3)</AccordionTrigger>
<AccordionContent>
<p>SPF and DMARC are configured. DKIM is missing on mx2.acme.com.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem value="dns">
<AccordionTrigger>DNS servers (2)</AccordionTrigger>
<AccordionContent>
<p>No findings in the last scan.</p>
</AccordionContent>
</AccordionItem>
</Accordion>Disabled item
Disable an item whose content is not ready yet. Say why in the trigger label.
<Accordion className="max-w-md">
<AccordionItem value="detection">
<AccordionTrigger>Detection rule</AccordionTrigger>
<AccordionContent>
<p>Typosquatting, edit distance 2 from a monitored domain.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem value="evidence" disabled>
<AccordionTrigger>Evidence (processing)</AccordionTrigger>
<AccordionContent>
<p>Screenshots and WHOIS records.</p>
</AccordionContent>
</AccordionItem>
</Accordion>Accessibility
- Each trigger is a button inside a heading, with
aria-expandedandaria-controlspointing to its panel. Arrow keys move focus between triggers; Enter and Space toggle the item. - The heading is always an
<h3>. Place the accordion where an<h3>fits the outline of the page, under an<h2>. - Closed panels are unmounted by default, so the browser’s find-in-page skips them. Set
hiddenUntilFoundonAccordionwhen users need to search the hidden text.
API reference
Generated from the TypeScript source. className, style and children are accepted everywhere and omitted below.
Accordion
Accordion is a vertical stack of sections whose bodies expand and collapse under their headings: an FAQ, groups of settings, a long detail view. For a single region to show and hide, use Collapsible; to switch between views of the same subject, Tabs.
| Prop | Type | Default |
|---|---|---|
defaultValue | AccordionValue<any>The uncontrolled value of the item(s) that should be initially expanded. | - |
disabled | booleanWhether the component should ignore user interaction. | false |
hiddenUntilFound | booleanAllows the browser's built-in page search to find and expand the panel contents. | false |
keepMounted | booleanWhether to keep the element in the DOM while the panel is closed. This prop is ignored when `hiddenUntilFound` is used. | false |
loopFocus | booleanDeprecated following the [APG guidance update](https://github.com/w3c/aria-practices/pull/3434) to remove roving focus. | - |
multiple | booleanWhether multiple items can be open at the same time. | false |
onValueChange | ((value: AccordionValue<any>, eventDetails: AccordionRootChangeEventDetails) => void)Event handler called when an accordion item is expanded or collapsed. Provides the new value as an argument. | - |
orientation | "horizontal" | "vertical"Deprecated following the [APG guidance update](https://github.com/w3c/aria-practices/pull/3434) to remove roving focus. | 'vertical' |
render | ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, State<any>>Allows you to replace the component's HTML element with a different tag, or compose it with another component. | - |
value | AccordionValue<any>The controlled value of the item(s) that should be expanded. | - |
AccordionItem
| Prop | Type | Default |
|---|---|---|
disabled | booleanWhether the component should ignore user interaction. | false |
onOpenChange | ((open: boolean, eventDetails: AccordionItemChangeEventDetails) => void)Event handler called when the panel is opened or closed. | - |
render | ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, AccordionItemState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. | - |
value | anyA unique value that identifies this accordion item. If no value is provided, a unique ID will be generated automatically. Use when controlling the accordion programmatically, or to set an initial open state. @example ```tsx <Accordion.Root value={['a']}> <Accordion.Item value="a" /> // initially open <Accordion.Item value="b" /> // initially closed </Accordion.Root> ``` | - |
AccordionTrigger
AccordionTrigger is the heading button that opens and closes its item. It renders inside an <h3>, so place the accordion under an h2.
| Prop | Type | Default |
|---|---|---|
nativeButton | booleanWhether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`). | true |
render | ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, AccordionTriggerState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. | - |
AccordionContent
| Prop | Type | Default |
|---|---|---|
hiddenUntilFound | booleanAllows the browser's built-in page search to find and expand the panel contents. | false |
keepMounted | booleanWhether to keep the element in the DOM while the panel is closed. This prop is ignored when `hiddenUntilFound` is used. | false |
render | ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, AccordionPanelState>Allows you to replace the component's HTML element with a different tag, or compose it with another component. | - |