- Components
Accordion
A stack of headings that each open and close a panel. One open at a time, or several.
npx shadcn add @klarhimmel/accordionWhen to use
Use for
A list of questions or settings groups where people read a few and skip the rest.
Not for
Content everyone must read. Show it. Not for switching views. Use Tabs.
Pairs with
Text, Badge, Card.
Preview
Rooms are ready from 15:00. If you arrive earlier we keep your bags at the desk.
Yes, twelve spaces behind the building. They are free for guests and cannot be booked in advance.
Dogs stay in the ground-floor rooms for a small cleaning fee. Ask us when you book.
Free until 48 hours before arrival. After that the first night is charged.
accordion.tsx
import { Theme } from '@/components/klarhimmel/theme/style';
import { Accordion, AccordionItem } from '@/components/klarhimmel/ui/accordion';
export default function Example() {
return (
<Theme theme="brand">
<Accordion defaultValue="checkin">
<AccordionItem value="checkin" title="When can I check in?">From 15:00.</AccordionItem>
<AccordionItem value="parking" title="Is there parking?">Yes, behind the building.</AccordionItem>
</Accordion>
</Theme>
);
}Install
Import
import { Accordion, AccordionItem } from '@/components/klarhimmel/ui/accordion';- Lands in
- components/klarhimmel/ui/accordion.tsx, plus cn() and the theme item if they are missing. Import theme.css after Tailwind.
- Render in
- Render it inside <Theme>, once near the root of your app. Tokens and fonts are scoped to it, so outside it the component is unstyled.
Examples
Multiple
Several panels can stay open at once, and one item is switched off.
Served 07:00 to 10:00 in the garden room.Open 06:00 to 21:00. Towels are in your room.Closed for the season.Call the desk and we leave the key in a box by the door.import { Accordion, AccordionItem } from '@/components/klarhimmel/ui/accordion'; export default function AccordionMultiple() { return ( <div className="mx-auto flex w-[min(36rem,calc(100cqw-3rem))] flex-col gap-3"> <p className="text-kh-small text-kh-muted">Several panels can stay open at once, and one item is switched off.</p> <Accordion type="multiple" defaultValue={['breakfast', 'spa']}> <AccordionItem value="breakfast" title="Breakfast">Served 07:00 to 10:00 in the garden room.</AccordionItem> <AccordionItem value="spa" title="Spa">Open 06:00 to 21:00. Towels are in your room.</AccordionItem> <AccordionItem value="bike" title="Bike hire" disabled>Closed for the season.</AccordionItem> <AccordionItem value="late" title="Late arrival">Call the desk and we leave the key in a box by the door.</AccordionItem> </Accordion> </div> ); }Controlled
Twelve rooms on three floors.Sauna, plunge pool and a quiet room.Open: rooms
import { useState } from 'react'; import { Accordion, AccordionItem } from '@/components/klarhimmel/ui/accordion'; import { Button } from '@/components/klarhimmel/ui/button'; export default function AccordionControlled() { const [open, setOpen] = useState('rooms'); return ( <div className="flex w-[min(36rem,calc(100cqw-3rem))] flex-col gap-3"> <div className="flex gap-2"> <Button size="sm" variant="secondary" onClick={() => setOpen('rooms')}>Open rooms</Button> <Button size="sm" variant="secondary" onClick={() => setOpen('spa')}>Open spa</Button> <Button size="sm" variant="ghost" onClick={() => setOpen('')}>Close all</Button> </div> <Accordion value={open} onValueChange={setOpen}> <AccordionItem value="rooms" title="Rooms">Twelve rooms on three floors.</AccordionItem> <AccordionItem value="spa" title="Spa">Sauna, plunge pool and a quiet room.</AccordionItem> </Accordion> <p role="status" className="text-kh-small text-kh-muted">Open: {open || 'none'}</p> </div> ); }
API reference
| Prop | Type | Default | Description |
|---|---|---|---|
type | 'single' | 'multiple' | 'single' | One panel open at a time, or any number. |
value / defaultValue / onValueChange | string | string[] | - | Open item value (a string when single, a list when multiple). |
collapsible | boolean | true | Single mode only. With false the open item cannot be closed. |
AccordionItem value | string | - | Required. Identifies the item. |
AccordionItem title | ReactNode | - | Required. The heading text; it is the button. |
AccordionItem level | 2 | 3 | 4 | 5 | 3 | Heading level, to fit the page outline. |
AccordionItem disabled | boolean | false | The item stays closed and is skipped by the arrow keys. |
className | string | - | Extra classes, merged after the component's own. |
Accessibility
| Key | Does |
|---|---|
Enter / Space | Opens or closes the focused panel |
Down / Up | Moves focus to the next or previous heading, wrapping |
Home / End | Moves focus to the first or last heading |
Tab | Moves on; closed panels are skipped |
Each trigger sits in a heading. Choose its level so the page outline stays correct.
Accessibility