Accordion
Vertically stacked collapsible sections, built on Radix.
Accordion groups content into collapsible sections. Built on Radix: open one at a time
(type="single") or several (type="multiple"). Compose each section from AccordionItem +
AccordionHeading (the trigger) + AccordionSlot (the panel). The chevron rotates and the
panel animates open via CSS grid rows (respecting reduced-motion).
Installation
pnpm add @infinitibit_gmbh/ui @infinitibit_gmbh/theme-default
Usage
import '@infinitibit_gmbh/theme-default/theme.css';
import '@infinitibit_gmbh/ui/styles.css';
import {
Accordion,
AccordionItem,
AccordionHeading,
AccordionSlot,
} from '@infinitibit_gmbh/ui';
export function Example() {
return (
<Accordion type="single" collapsible>
<AccordionItem value="a">
<AccordionHeading>Section A</AccordionHeading>
<AccordionSlot>Content A</AccordionSlot>
</AccordionItem>
</Accordion>
);
}
Single vs multiple
type="single" keeps one section open at a time (add collapsible to allow closing it);
type="multiple" lets several stay open.
Heading sizes
AccordionHeading scales its title with size — sm (12/16), md (14/20, default), or lg
(16/24). The padding stays constant; only the title typography changes.
<AccordionHeading size="lg">Large heading</AccordionHeading>
Action link
Pass a link to put an action — typically a Hyperlink — at the far right of the heading row.
It renders beside the trigger, not inside it, so it stays valid, focusable HTML and clicking
it follows the href instead of toggling the section.
import { Hyperlink } from '@infinitibit_gmbh/ui';
<AccordionHeading link={<Hyperlink href="/docs">Learn more</Hyperlink>}>
This is panel header
</AccordionHeading>;
Loading
Set loading on AccordionSlot to swap the panel body for a centered activity indicator while
async content resolves.
<AccordionSlot loading>{/* content, shown once ready */}</AccordionSlot>
API
Accordion
| Prop | Type | Default | Description |
|---|---|---|---|
type | 'single' | 'multiple' | — | Expansion mode |
value | string | string[] | — | Controlled open section(s) |
defaultValue | string | string[] | — | Initial open section(s) |
onValueChange | (value) => void | — | Called when the open section changes |
collapsible | boolean | — | (single) allow closing the open one |
AccordionItem
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | The section's value (required) |
disabled | boolean | — | Non-interactive section |
AccordionHeading
The trigger row. Forwards native Radix Trigger props.
| Prop | Type | Default | Description |
|---|---|---|---|
size | 'sm' | 'md' | 'lg' | 'md' | Title typography scale (sm 12/16 · md 14/20 · lg 16/24) |
link | ReactNode | — | Action rendered at the row's far right, beside the trigger |
AccordionSlot
The panel. Forwards native Radix Content props.
| Prop | Type | Default | Description |
|---|---|---|---|
loading | boolean | false | Show a centered activity indicator instead of children |
Accessibility
- The trigger carries
aria-expandedandaria-controlspointing to its panel. - Enter/Space toggle the focused section; arrow keys move between headings (Radix).
- Closed panels are removed from the accessibility tree; the focus ring uses
:focus-visible.