Skip to content

Accordion

A flexible Accordion component built on Base UI’s accessible primitives. It renders a set of collapsible panels with built-in keyboard navigation, ARIA support, and automatic focus handling, ensuring an accessible experience by default with a simple API for single or multiple open items.

import { Accordion } from "@/rokkit200-ui/components/accordion/accordion";
<Accordion items={items} />

Setting selectionMode="multiple" determines whether multiple items can be open at the same time.

Setting defaultOpen="first" will expand the first item automatically.

This Accordion is a flexible wrapper around Base UI's accessible primitives. It adds layout, styling, selection modes (`single` | `multiple`), default open behavior, external control via ref (open/close), and customizable trigger rendering, while preserving accessibility and keyboard support.

This demo illustrates the imperative control capabilities of the Accordion. By using the ref and the AccordionApi, a parent component can open or close accordion items programmatically, independent of user interactions. It highlights how the Accordion can be both user-driven and externally controlled.

This demonstrates state synchronization between the Accordion and another UI element. In this specific case, the Accordion’s open/close state controls which images are displayed. As users interact with the Accordion, the images update in real time to reflect the current selection.

At the same time, the renderTrigger prop is used to customize the toggle icon, while function-based props such as headerClassName={(state) => ...}, itemClassName={(state) => ...}, and triggerClassName={(state) => ...} allow state-aware styling by receiving { id, index, open, openIds } for the current item during render.

Content 1

Accordion photo
PropTypeDefaultDescription
itemsAccordionItem[]Array of accordion items. Each item has an id, header, and panel content. Required.
headerTagkeyof React.JSX.IntrinsicElements"h3"Determines which HTML element is used for the accordion item header container (for example "h3", "h4", "div"). Useful for maintaining correct document heading hierarchy. Optional.
selectionMode"single" | "multiple""single"Determines whether only one item can be open at a time or multiple items can stay open. Optional.
defaultOpen"none" | "first""none"Determines which item is open by default. "first" opens the first item in the list. "none" keeps all items closed initially. Optional.
classNamestringApplied to the root Accordion container. Useful for styling with Tailwind or custom classes. Optional.
itemClassNamestring | ((state: ItemState) => string | undefined | null | false)Applied to each <Accordion.Item> element. Can be a function receiving { id, index, open, openIds } to enable state-aware styling. Optional.
headerClassNamestring | ((state: ItemState) => string | undefined | null | false)Applied to each <Accordion.Header> element. Supports function-based styling using the item state. Optional.
triggerClassNamestring | ((state: ItemState) => string | undefined | null | false)Applied to each <Accordion.Trigger> element. Can dynamically style the trigger based on the item’s open state. Optional.
triggerIconClassNamestring | ((state: ItemState) => string | undefined | null | false)Applied to the default trigger icon PlusIcon. When using renderTrigger, styling should be handled inside the custom render function. Optional.
panelClassNamestring | ((state: ItemState) => string | undefined | null | false)Applied to each <Accordion.Panel> element (the collapsible content container). Supports state-aware styling. Optional.
contentClassNamestring | ((state: ItemState) => string | undefined | null | false)Applied to the inner content wrapper inside each panel. Optional.
onChange(openItems: string[]) => voidCallback fired whenever the open items change. Provides the array of currently open item IDs. Useful for syncing accordion state with other UI (See Cross Communication example). Optional.
renderTrigger((open: boolean) => React.ReactNode) | React.ReactNodeAllows custom rendering of the trigger icon or content. If a function is provided, it receives the open state of the item. If a React node is provided, it will replace the default icon entirely. Optional.

See the Base UI documentation for more information.

Accessibility is a fundamental part of Base UI’s Accordion. It takes care of complex details such as ARIA and role attributes, keyboard navigation, pointer interactions, and focus management automatically. This ensures a fully accessible experience by default, while maintaining a clear and intuitive API for customization.

See the Base UI documentation for more information.