Alert
Get Started
Introduction
Components
Accordion
Badge
Button
Card
Checkbox
Command
Dialog
Dropdown Menu
Input
Select
Switch
Table
Tabs
Toast
Tooltip
Forms
Controlled Input
Field Arrays
Submit
Validation

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.
closed
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

PropTypeDefaultDescription
valuestring-A unique identifier for the accordion item.
openbooleanfalseWhether the accordion item is open.
disabledbooleanfalseWhether the accordion item is disabled.
onOpenChange(open: boolean) => void-Event handler called when the open state changes.

AccordionTrigger

PropTypeDefaultDescription
disabledbooleanfalseWhether the trigger is disabled.
asChildbooleanfalseRender child element as trigger instead of built-in button.

AccordionContent

PropTypeDefaultDescription