Accordion
Sections that open and close under their headings, such as FAQs or a checkout's order summary. Each item is a native details element, so it works with no JavaScript, and items that share a name open one at a time.
Import
import { Accordion } from '@nizivo/react/accordion';
// Once per app (Getting started), after
// @nizivo/tokens/tokens.css and @nizivo/react/css/base.css
import '@nizivo/react/css/accordion.css';Static or interactive
Server. No client JavaScript: each item is a native <details> with its <summary> as the
heading, so it opens and closes before and without hydration, from the pointer and the keyboard.
The browser's find in page opens a closed item that holds the match.
How to choose.
Parts
Accordion.Root holds the items. Each Accordion.Item is a <details>, with an
Accordion.Trigger (its <summary>: the heading, with a chevron at its end) and an
Accordion.Panel (the content). defaultOpen opens an item on the first render; after that the
browser keeps the open state.
One at a time
Give Accordion.Root a name and every item that sets none gets it: opening one closes the
others, with no script, as <details name> does. The name groups items across the whole page, so
use one no other accordion on the page uses. Without a name, items open independently. Firefox 129,
the oldest Firefox Nizivo supports, does not group them: there, several items can be open at once.
The heading
The trigger's text is a heading for its panel, not a page heading: put an <h3> (or the level the
page needs) inside it when the items should appear in a screen reader's headings list. indicator
replaces the chevron, which is decorative.
Examples
Basic
Frequently asked questions: one answer open at a time (name), with no client JavaScript.
Source only
defaultOpen), which would move focus on this page, so it is shown as source only.import type { JSX } from 'react';
import { Accordion } from '@nizivo/react/accordion';
export function AccordionExample(): JSX.Element {
return (
<Accordion.Root name="shipping-faq" style={{ maxInlineSize: 560 }}>
<Accordion.Item defaultOpen>
<Accordion.Trigger>When will my order ship?</Accordion.Trigger>
<Accordion.Panel>
Orders placed before 2 pm ship the same working day. You get a tracking link by email.
</Accordion.Panel>
</Accordion.Item>
<Accordion.Item>
<Accordion.Trigger>Can I change my delivery address?</Accordion.Trigger>
<Accordion.Panel>
Yes, until the order ships. Open the order from your account and choose Edit address.
</Accordion.Panel>
</Accordion.Item>
<Accordion.Item>
<Accordion.Trigger>How do returns work?</Accordion.Trigger>
<Accordion.Panel>
Return any unused item within 30 days. The return label is free for orders over €50.
</Accordion.Panel>
</Accordion.Item>
</Accordion.Root>
);
}
Order Summary
A checkout's collapsible order summary: independent items, without name.
Order summary (3 items) · €84.00
Add a promo code
import type { JSX } from 'react';
import { Accordion } from '@nizivo/react/accordion';
export function AccordionOrderSummaryExample(): JSX.Element {
return (
<Accordion.Root style={{ maxInlineSize: 400 }}>
<Accordion.Item>
<Accordion.Trigger>Order summary (3 items) · €84.00</Accordion.Trigger>
<Accordion.Panel>Sand mug ×2 · €48.00. Stoneware bowl ×1 · €36.00.</Accordion.Panel>
</Accordion.Item>
<Accordion.Item>
<Accordion.Trigger>Add a promo code</Accordion.Trigger>
<Accordion.Panel>Codes apply at the payment step.</Accordion.Panel>
</Accordion.Item>
</Accordion.Root>
);
}
Parts
Use the parts through the namespace (Accordion.Root) or by their flat names (AccordionRoot); both work from Server Components.
Accordion.Root
Server component Renders data-slot="accordion" with the class nz-accordion. Props: AccordionRootProps. Source: src/accordion/accordion.tsx.
| Name | Type | Default | Description |
|---|---|---|---|
children | ReactNode | – |
|
name | string | – | Makes the items exclusive: each |
render | RenderProp<NoState> | – | Must render a |
- Also takes every attribute of
<div>;childrenis redeclared above. (ComponentPropsWithRef<"div">)
render takes an element, or, in client code, a function of the props and no state.
Accordion.Item
Server component Renders data-slot="accordion-item" with the class nz-accordion-item. Props: AccordionItemProps. Source: src/accordion/accordion.tsx.
| Name | Type | Default | Description |
|---|---|---|---|
children | ReactNode | – | An |
defaultOpen | boolean | false | Open on the first render. The browser keeps the open state after that. |
name | string | – | The exclusive group; set by |
render | RenderProp<NoState> | – | Must render a |
- Also takes every attribute of
<details>exceptopen;children,nameare redeclared above. (Omit<ComponentPropsWithRef<"details">, "open">)
render takes an element, or, in client code, a function of the props and no state.
Accordion.Trigger
Server component Renders data-slot="accordion-trigger" with the class nz-accordion-trigger. Props: AccordionTriggerProps. Source: src/accordion/accordion.tsx.
| Name | Type | Default | Description |
|---|---|---|---|
childrenrequired | ReactNode | – | |
indicator | ReactNode | – | Replaces the chevron at the end. Decorative ( |
render | RenderProp<NoState> | – | Must render a |
- Also takes every attribute of
<summary>;childrenis redeclared above. (ComponentPropsWithRef<"summary">)
render takes an element, or, in client code, a function of the props and no state.
Accordion.Panel
Server component Renders data-slot="accordion-panel" with the class nz-accordion-panel. Props: AccordionPanelProps. Source: src/accordion/accordion.tsx.
| Name | Type | Default | Description |
|---|---|---|---|
render | RenderProp<NoState> | – | Must render a |
- Also takes every attribute of
<div>. (ComponentPropsWithRef<"div">)
render takes an element, or, in client code, a function of the props and no state.
Other exports
AccordionItemPropstypeimport type { AccordionItemProps } from '@nizivo/react/accordion'The props of
Accordion.Item, listed above.AccordionPanelPropstypeimport type { AccordionPanelProps } from '@nizivo/react/accordion'The props of
Accordion.Panel, listed above.AccordionRootPropstypeimport type { AccordionRootProps } from '@nizivo/react/accordion'The props of
Accordion.Root, listed above.AccordionTriggerPropstypeimport type { AccordionTriggerProps } from '@nizivo/react/accordion'The props of
Accordion.Trigger, listed above.
Data attributes and slots
Style parts by class (.nz-<slot>) and state by data attribute. Attribute meanings come from contracts/vocabulary.json.
| Slot | Rendered by | Data attributes |
|---|---|---|
accordion.nz-accordion | Accordion.Rootroot (takes render) | none |
accordion-indicator.nz-accordion-indicator | Accordion.Triggerinner element (CSS only) | none |
accordion-item.nz-accordion-item | Accordion.Itemroot (takes render) | none |
accordion-panel.nz-accordion-panel | Accordion.Panelroot (takes render) | none |
accordion-title.nz-accordion-title | Accordion.Triggerinner element (CSS only) | none |
accordion-trigger.nz-accordion-trigger | Accordion.Triggerroot (takes render); interactive, focus: self | none |
CSS hooks
Set a hook on the component's class or any ancestor to restyle it without specificity games; leave it unset for the default shown.
| Hook | Default | Read as |
|---|---|---|
--nz-accordion-border | --nz-border-subtle |
|
--nz-accordion-padding-inline | --nz-space-0 |
|
--nz-accordion-trigger-fg | --nz-text-primary |
|
Layers: nz.components. Classes: .nz-accordion, .nz-accordion-indicator, .nz-accordion-item, .nz-accordion-panel, .nz-accordion-title, .nz-accordion-trigger.
Tokens this stylesheet reads (15)
--nz-border-subtle, --nz-border-width-default, --nz-duration-fast, --nz-easing-standard, --nz-font-body-m, --nz-font-label-m-strong, --nz-icon-secondary, --nz-radius-sm, --nz-size-icon-sm, --nz-space-0, --nz-space-3, --nz-space-4, --nz-text-primary, --nz-text-secondary, --nz-tracking-label-m
Accessibility
These parts are interactive. Each gets the focus outline and touch-action rule from @nizivo/react/css/base.css (the nz.base layer), so the floor survives a restyle:
accordion-trigger: draws the focus outline itself on keyboard focus.
Keyboard
| Keys | Action |
|---|---|
| Tab | Moves focus to the next item's heading. |
| Enter, Space | On a heading, opens or closes its item. |
Source: native <details> and <summary> (accordion.tsx). The browser lane (test/browser/accordion.spec.tsx) checks the pointer, Tab, Enter and Space, exclusive items and the chevron.
Figma
Node ids from design/component-map.json, which nz gen writes from component.json. The links open the Nizivo Figma library, which may ask you to sign in.
- Canonical: Figma node
7370:88 - Ghost masters: none