Accordion Item
- Stable
- WCAG 2.2 evidence
- RTL
One collapsible section of an FAQ or settings page. Built on
React Aria Disclosure: the title is a heading (level) that contains a button with aria-expanded and aria-controls; Enter
and Space toggle it, a disabled item leaves the tab order, and the panel is hidden while collapsed (WCAG 2.1.1, 4.1.2). The
whole header is the target (2.5.8), keyboard focus draws the 2 px ring inside it (2.4.7), and the state is shown by the
leading toggle turning from a plus into a minus, not by colour alone (1.4.1). State: isExpanded / defaultExpanded / onExpandedChange and isDisabled
(State=Disabled); Hover and Focused come from the pointer and keyboard. Inside an Accordion give each item an id. Do not hide content most people need, and do not use it for required form fields. Consumer duties: the title wording
(specific, not truncated) and the heading level.
import { AccordionItem } from "@nexera-ui/react";- 10
- examples
- 14
- props
- 4
- live controls
- 1
- platform
- 10
- WCAG criteria
- 4
- blocks use it
Try every prop. Copy the code.
Change the props and the code updates. Check light and dark, LTR and RTL, and phone width.
import { AccordionItem } from "@nexera-ui/react";
<AccordionItem />Examples 9
The same examples as Storybook, rendered live. Open Code to copy one.
Expanded
Figma State=Expanded: defaultExpanded (or isExpanded to control it).
import { AccordionItem } from "@nexera-ui/react";
<AccordionItem title="How is my leave balance calculated?" defaultExpanded>
You earn 1.67 days of annual leave each month. Unused days above 10 expire on 31 March. Public
holidays are not deducted.
</AccordionItem>;
Disabled
Figma State=Disabled: isDisabled takes the header out of the tab order.
import { AccordionItem } from "@nexera-ui/react";
<AccordionItem title="How is my leave balance calculated?" isDisabled>
You earn 1.67 days of annual leave each month. Unused days above 10 expire on 31 March. Public
holidays are not deducted.
</AccordionItem>;
Variants
Figma Variant: Divider, Card and Filled, each collapsed and expanded.
import { AccordionItem } from "@nexera-ui/react";
export function Variants() {
return (
<div className="flex flex-col gap-6">
{(["divider", "card", "filled"] as const).map((variant) => (
<div key={variant} className="flex flex-col gap-2">
<AccordionItem variant={variant} title={`${variant}, collapsed`} />
<AccordionItem variant={variant} title={`${variant}, expanded`} defaultExpanded />
</div>
))}
</div>
);
}
With icon subtitle and meta
Optional parts: icon, subtitle and meta appear when provided.
import { AccordionItem } from "@nexera-ui/react";
import { LuUsers } from "react-icons/lu";
const content =
"You earn 1.67 days of annual leave each month. Unused days above 10 expire on 31 March. Public holidays are not deducted.";
<AccordionItem
title="Engineering"
icon={<LuUsers />}
subtitle="Updated 1 October 2026"
meta="3 items"
defaultExpanded
>
{
<>
<p className="m-0">Ayesha Khan, Bilal Ahmed and Sana Iqbal.</p>
<p className="m-0">Any content fits in the panel: text, lists, forms or other components.</p>
</>
}
</AccordionItem>;
In an accordion
An Accordion shares the variant and lets one item stay open (allowsMultipleExpanded allows several).
import { Accordion, AccordionItem } from "@nexera-ui/react";
const title = "How is my leave balance calculated?";
const content =
"You earn 1.67 days of annual leave each month. Unused days above 10 expire on 31 March. Public holidays are not deducted.";
export function InAnAccordion() {
return (
<Accordion variant={args.variant ?? "divider"} defaultExpandedKeys={["leave"]}>
<AccordionItem id="leave" title={title} level={3}>
{content}
</AccordionItem>
<AccordionItem id="payroll" title="When is payroll run?" level={3}>
Payroll runs on the last working day of the month.
</AccordionItem>
<AccordionItem id="remote" title="Can I work remotely?" level={3}>
Yes, up to three days a week with your manager's approval.
</AccordionItem>
</Accordion>
);
}
Cards in an accordion
Cards and filled items in a group are 8 px apart.
import { Accordion, AccordionItem } from "@nexera-ui/react";
const title = "How is my leave balance calculated?";
const content =
"You earn 1.67 days of annual leave each month. Unused days above 10 expire on 31 March. Public holidays are not deducted.";
export function CardsInAnAccordion() {
return (
<Accordion variant="card" allowsMultipleExpanded defaultExpandedKeys={["leave"]}>
<AccordionItem id="leave" title={title}>
{content}
</AccordionItem>
<AccordionItem id="payroll" title="When is payroll run?">
Payroll runs on the last working day of the month.
</AccordionItem>
</Accordion>
);
}
Long content
Long and translated titles wrap in the header; nothing is truncated.
import { AccordionItem } from "@nexera-ui/react";
<AccordionItem
title="Wie wird mein verbleibender Urlaubsanspruch fuer das laufende Kalenderjahr einschliesslich Uebertrag berechnet?"
subtitle="Zuletzt aktualisiert am 1. Oktober 2026 von der Personalabteilung"
meta="3 Eintraege"
defaultExpanded
>
You earn 1.67 days of annual leave each month. Unused days above 10 expire on 31 March. Public
holidays are not deducted.
</AccordionItem>;
Right to left
Right-to-left: the toggle, icon and title sit at the start (right) and the meta at the end (left).
import { AccordionItem } from "@nexera-ui/react";
import { LuUsers } from "react-icons/lu";
<AccordionItem
title="كيف يتم احتساب رصيد إجازتي؟"
subtitle="آخر تحديث 1 أكتوبر 2026"
icon={<LuUsers />}
defaultExpanded
>
تكسب 1.67 يومًا من الإجازة السنوية كل شهر.
</AccordionItem>;
Narrow container
A 14 rem container: the header wraps and keeps the full width as its target.
import { AccordionItem } from "@nexera-ui/react";
<div className="max-w-56">
<AccordionItem
title="How is my leave balance calculated?"
subtitle="Updated 1 October 2026"
meta="3 items"
defaultExpanded
>
You earn 1.67 days of annual leave each month. Unused days above 10 expire on 31 March. Public
holidays are not deducted.
</AccordionItem>
</div>;
Props 14
Press "Try it" on a card to load that prop into the playground.
14 props shown
title*NexeraVisibleContentThe question or topic. It is the text of the heading and the accessible name of the trigger button. Wraps instead of truncating.
levelNexera1 | 2 | 3 | 4 | 5 | 6Heading level of the title, so the accordion fits the page's outline (WCAG 1.3.1, 2.4.6). Use the level below the section heading that contains the accordion.
subtitleNexeraReactNodeSecond line under the title. Shown when provided.
metaNexeraReactNodeShort text at the end of the header. Shown when provided.
iconNexeraReactNodeIcon before the title. 20 px, decorative: the title names the item. Shown when provided.
childrenNexeraReactNodeContent of the panel. Plain text is shown in
Body/Default and text/secondary; for several blocks wrap them in elements. Hidden while collapsed.
variantNexera"divider" | "card" | "filled"Visual style. Defaults to the enclosing Accordion's variant, else divider.
classNameNexerastringExtra classes for the item, merged last so they win over the defaults.
styleNexeraCSSPropertiesInline style for the item.
isDisabledReact AriabooleanWhether the disclosure is disabled.
onExpandedChangeReact Aria(isExpanded: boolean) => voidHandler that is called when the disclosure's expanded state changes.
isExpandedReact AriabooleanWhether the disclosure is expanded (controlled).
defaultExpandedReact AriabooleanWhether the disclosure is expanded by default (uncontrolled).
idReact AriaKeyAn id for the disclosure when used within a DisclosureGroup, matching the id used in
expandedKeys.
* Required. React Aria props shown are the ones most apps use; the component accepts the rest of its React Aria props too.
Accessible by default.
Built on React Aria, and covered by the WCAG 2.2 evidence generated on every build.
WCAG 2.2 evidence
7 direct · 3 supporting- 1.1.1Non-text ContentLevel A · tested directly
- 1.3.1Info and RelationshipsLevel A · tested directly
- 1.4.1Use of ColorLevel A · tested directly
- 1.4.4Resize TextLevel AA · supporting test
- 1.4.11Non-text ContrastLevel AA · supporting test
- 1.4.12Text SpacingLevel AA · supporting test
- 2.1.1KeyboardLevel A · tested directly
- 2.4.6Headings and LabelsLevel AA · tested directly
- 2.4.7Focus VisibleLevel AA · tested directly
- 4.1.2Name, Role, ValueLevel A · tested directly
Fits any width.
Nexera components respond to the space they are given. Drag the corner of the frame, or pick a width.
Styling hooks
Pass className to add Tailwind classes (merged last). State is exposed as data attributes, so you can style it with variants like data-pressed:.
data-disableddata-expandeddata-hovered
<AccordionItem className="data-disabled:opacity-90 shadow-sm" />Used in blocks
- Order summaryCommerce and payments
- PayslipCommerce and payments
- Help articleMedia and content
- FAQMedia and content
Related components
- AreaChartA stacked area chart: layers piled up over time with the title, range switch, actions and legend of the card.
- AvailabilityRowOne person's availability across a window of the day: an avatar with initials and the name, and a timeline with the busy periods drawn as bars.
- AvatarA person or organisation shown as a photo, initials or an icon.
- AvatarGroupA row of overlapping avatars with a "+N" chip for the rest.
- AvatarLabelAn avatar with a name and an optional subtitle beside it, for a person in a list, a header or a mention.
- BadgeShort status or category label: `Tone` x `Variant` x `Size`, with an optional dot, leading icon and remove button.
- BadgeGroupA pill that pairs a small badge with a short message, for an announcement or a status line.
- BadgeOverflowThe "+N" pill that stands in for the badges a row has no room for.