Accordion

Fold questions, settings, and details into sections that open in place, one at a time or all together.

Plans are billed at the start of each month for every active seat. Seats you add mid-month are prorated, and you can download every invoice from Settings.

Installation

You can add the accordion using our CLI or manually:

Dark mode ready - this component follows BoardUI semantic tokens automatically. Set up theme switching.

The CLI copies the component source (with its internal dependencies) into your project and installs any required npm packages.

npx boardui@latest add accordion

Using a shared UI package or custom import aliases? Configure your installation paths before running the CLI. Copy-paste examples use the default imports.

Anatomy

Accordion groups the sections and AccordionItem is one section: a heading with a button that opens its panel. Give every item an id so you can open it from defaultExpandedKeys or control it.

The panel eases open while its content fades in, settles a few pixels, and sharpens from a soft blur. A closed panel stays in the page, hidden until found, so the browser's find-in-page still reaches its text and opens it.

Contained

variant="contained" sets each item on a tray, the look of the FAQ on the BoardUI home page. indicator="plus" swaps the chevron for a plus that turns into a close.

Yes. Upgrades apply right away, and downgrades take effect at the end of the current billing period, so you never lose access you have paid for.

<Accordion variant="contained" indicator="plus" defaultExpandedKeys={["plans"]}> <AccordionItem id="billing" title="How does billing work?">…</AccordionItem> <AccordionItem id="plans" title="Can I change plans later?">…</AccordionItem> <AccordionItem id="data" title="What happens to my data if I cancel?">…</AccordionItem></Accordion>

Separated, with icons

variant="separated" gives every item its own card. Add an icon and a description for settings groups, and allowsMultipleExpanded to let several stay open. isDisabled locks an item.

import { RiBankCardLine, RiNotification3Line, RiShieldKeyholeLine } from "@remixicon/react"; <Accordion variant="separated" allowsMultipleExpanded defaultExpandedKeys={["notifications"]}> <AccordionItem id="notifications" icon={RiNotification3Line} title="Notifications" description="Email, push, and Slack"> <Switch defaultSelected>Email me about mentions</Switch> … </AccordionItem> <AccordionItem id="security" icon={RiShieldKeyholeLine} title="Security" description="Two-factor sign-in and sessions">…</AccordionItem> <AccordionItem id="billing" icon={RiBankCardLine} title="Billing" description="Managed by your workspace owner" isDisabled>…</AccordionItem></Accordion>

Controlled

Keep the open sections in your own state with expandedKeys and onExpandedChange, for example to expand or collapse them all at once.

Plans are billed at the start of each month for every active seat. Seats you add mid-month are prorated, and you can download every invoice from Settings.

const [expanded, setExpanded] = useState<Set<Key>>(new Set(["billing"])); <Button variant="secondary" size="small" onClick={() => setExpanded(new Set(ids))}>Expand all</Button><Button variant="secondary" size="small" onClick={() => setExpanded(new Set())}>Collapse all</Button> <Accordion allowsMultipleExpanded expandedKeys={expanded} onExpandedChange={setExpanded}> {faq.map((item) => ( <AccordionItem key={item.id} id={item.id} title={item.question}> <p>{item.answer}</p> </AccordionItem> ))}</Accordion>

Right-to-left

Wrap the accordion in DirectionProvider. Titles align to the right and the indicator moves to the left edge.

تُحتسب الخطط في بداية كل شهر لكل مقعد نشط، ويمكنك تنزيل كل فاتورة من الإعدادات.

import { DirectionProvider } from "@/components/foundations/direction/direction"; <DirectionProvider locale="ar"> <Accordion defaultExpandedKeys={["billing"]}> <AccordionItem id="billing" title="كيف تعمل الفوترة؟">…</AccordionItem> <AccordionItem id="plans" title="هل يمكنني تغيير الخطة لاحقًا؟">…</AccordionItem> </Accordion></DirectionProvider>

Keyboard and accessibility

Each header is a button inside a heading (level 3 by default, set with headingLevel). Tab moves between headers, and Enter or Space opens and closes a section. Screen readers hear whether it is expanded and which panel it controls.

Reduced motion opens and closes sections instantly.