Accordion
A vertically stacked set of interactive headings that each reveal an associated section of content.
Yes. It adheres to the WAI-ARIA design pattern.
#Installation
bunx --bun barefoot add accordion#Usage
Yes. It adheres to the WAI-ARIA design pattern.
Yes. It comes with default styles that match the other components' aesthetic.
Yes. It uses CSS transitions for smooth open/close animations.
1import {2 Accordion,3 AccordionItem,4 AccordionTrigger,5 AccordionContent,6} from '@/components/ui/accordion'#Examples
#Single Open
Yes. It adheres to the WAI-ARIA design pattern.
Yes. It comes with default styles that match the other components' aesthetic.
Yes. It uses CSS transitions for smooth open/close animations.
1"use client"23import { createSignal } from '@barefootjs/dom'4import {5 Accordion,6 AccordionItem,7 AccordionTrigger,8 AccordionContent,9} from '@/components/ui/accordion'1011function AccordionSingle() {12 const [openItem, setOpenItem] = createSignal<string | null>('item-1')1314 return (15 <Accordion>16 <AccordionItem value="item-1" open={openItem() === 'item-1'} onOpenChange={(v) => setOpenItem(v ? 'item-1' : null)}>17 <AccordionTrigger>Is it accessible?</AccordionTrigger>18 <AccordionContent>19 Yes. It adheres to the WAI-ARIA design pattern.20 </AccordionContent>21 </AccordionItem>22 <AccordionItem value="item-2" open={openItem() === 'item-2'} onOpenChange={(v) => setOpenItem(v ? 'item-2' : null)}>23 <AccordionTrigger>Is it styled?</AccordionTrigger>24 <AccordionContent>25 Yes. It comes with default styles that match your theme.26 </AccordionContent>27 </AccordionItem>28 <AccordionItem value="item-3" open={openItem() === 'item-3'} onOpenChange={(v) => setOpenItem(v ? 'item-3' : null)}>29 <AccordionTrigger>Is it animated?</AccordionTrigger>30 <AccordionContent>31 Yes. It's animated by default with CSS transitions.32 </AccordionContent>33 </AccordionItem>34 </Accordion>35 )36}#Multiple Open
This accordion allows multiple items to be open at once.
Each item manages its own open/close state independently.
Click any trigger to toggle that item without affecting others.
1"use client"23import { createSignal } from '@barefootjs/dom'4import {5 Accordion,6 AccordionItem,7 AccordionTrigger,8 AccordionContent,9} from '@/components/ui/accordion'1011function AccordionMultiple() {12 // Each item manages its own state independently13 const [item1Open, setItem1Open] = createSignal(false)14 const [item2Open, setItem2Open] = createSignal(false)15 const [item3Open, setItem3Open] = createSignal(false)1617 return (18 <Accordion>19 <AccordionItem value="item-1" open={item1Open()} onOpenChange={setItem1Open}>20 <AccordionTrigger>First Item</AccordionTrigger>21 <AccordionContent>22 Content for first item.23 </AccordionContent>24 </AccordionItem>25 <AccordionItem value="item-2" open={item2Open()} onOpenChange={setItem2Open}>26 <AccordionTrigger>Second Item</AccordionTrigger>27 <AccordionContent>28 Content for second item.29 </AccordionContent>30 </AccordionItem>31 <AccordionItem value="item-3" open={item3Open()} onOpenChange={setItem3Open}>32 <AccordionTrigger>Third Item</AccordionTrigger>33 <AccordionContent>34 Content for third item.35 </AccordionContent>36 </AccordionItem>37 </Accordion>38 )39}#As Child
This item uses a custom trigger element via asChild.
This item uses the default button trigger.
1"use client"23import { createSignal } from '@barefootjs/dom'4import {5 Accordion,6 AccordionItem,7 AccordionTrigger,8 AccordionContent,9} from '@/components/ui/accordion'1011function AccordionAsChild() {12 const [openItem, setOpenItem] = createSignal<string | null>(null)1314 return (15 <Accordion>16 <AccordionItem value="custom" open={openItem() === 'custom'} onOpenChange={(v) => setOpenItem(v ? 'custom' : null)}>17 <AccordionTrigger asChild>18 <button type="button" className="...">Custom Trigger</button>19 </AccordionTrigger>20 <AccordionContent>21 This item uses a custom trigger element via asChild.22 </AccordionContent>23 </AccordionItem>24 <AccordionItem value="standard" open={openItem() === 'standard'} onOpenChange={(v) => setOpenItem(v ? 'standard' : null)}>25 <AccordionTrigger>Standard Trigger</AccordionTrigger>26 <AccordionContent>27 This item uses the default button trigger.28 </AccordionContent>29 </AccordionItem>30 </Accordion>31 )32}#Accessibility
- Keyboard Navigation - Arrow Up/Down to navigate between triggers, Home/End to jump
- Activation - Enter/Space to toggle accordion item
- ARIA - Triggers use aria-expanded, aria-controls; Content uses aria-labelledby
- Disabled State - aria-disabled on disabled triggers, skipped in keyboard navigation
- Screen Readers - State changes are announced when items are expanded/collapsed
#API Reference
AccordionItem
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | - | A unique identifier for the accordion item. |
| open | boolean | false | Whether the accordion item is open. |
| disabled | boolean | false | Whether the accordion item is disabled. |
| onOpenChange | (open: boolean) => void | - | Event handler called when the open state changes. |
AccordionTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
| disabled | boolean | false | Whether the trigger is disabled. |
| asChild | boolean | false | Render child element as trigger instead of built-in button. |
AccordionContent
| Prop | Type | Default | Description |
|---|