Accordion Vertically (or horizontally) stacked panels that expand and collapse one at a time.
A set of interactive headings that each reveal a section of content. The accordion keeps at most one panel open by default, supports keyboard navigation, and animates open/close transitions via CSS.
import { Accordion } from "@areia/slots" ;
document . querySelector ( "#root" ) !. innerHTML = `
<div
data-slot="accordion"
class="w-72 border-2 border-t-black border-l-black border-r-white border-b-white bg-white"
>
<div
data-slot="accordion-item"
data-value="item-1"
class="border-b border-neutral-500 last:border-b-0"
>
<button
data-slot="accordion-trigger"
class="win95-button flex w-full justify-between"
>
Item One
<span data-slot="accordion-trigger-icon" aria-hidden="true"></span>
</button>
<div data-slot="accordion-content" class="bg-white px-3 py-2 text-sm">
<div
data-slot="accordion-content-inner"
class="border-l-2 border-neutral-400 pl-2"
>
Content for item one.
</div>
</div>
</div>
<div
data-slot="accordion-item"
data-value="item-2"
class="border-b border-neutral-500 last:border-b-0"
>
<button
data-slot="accordion-trigger"
class="win95-button flex w-full justify-between"
>
Item Two
<span data-slot="accordion-trigger-icon" aria-hidden="true"></span>
</button>
<div data-slot="accordion-content" class="bg-white px-3 py-2 text-sm">
<div
data-slot="accordion-content-inner"
class="border-l-2 border-neutral-400 pl-2"
>
Content for item two.
</div>
</div>
</div>
</div>
` ;
const accordion = document . querySelector (
'[data-slot="accordion"]' ,
) ! ;
const controller = Accordion . createAccordion (accordion , {
multiple : false ,
orientation : "vertical" ,
} ) ;
import { Accordion } from "@areia/slots" ;
import { Accordion } from "@areia/slots" ;
// Auto-bind a single root
const root = document . querySelector ( '[data-slot="accordion"]' ) ;
const controller = Accordion . createAccordion (root , {
defaultValue : "item-1" ,
} ) ;
// Auto-bind all unbound roots in scope
const controllers = Accordion . create () ;
The accordion expects the following data-slot structure. Each item requires a data-value attribute used to identify it during expand, collapse, and toggle operations.
< div data-slot = "accordion" >
< div data-slot = "accordion-item" data-value = "item-1" >
< button data-slot = "accordion-trigger" >
Item One
< span
data-slot = "accordion-trigger-icon"
aria-hidden = "true"
></ span >
</ button >
< div data-slot = "accordion-content" >
< div data-slot = "accordion-content-inner" >
Content for item one.
</ div >
</ div >
</ div >
< div data-slot = "accordion-item" data-value = "item-2" >
< button data-slot = "accordion-trigger" >
Item Two
< span
data-slot = "accordion-trigger-icon"
aria-hidden = "true"
></ span >
</ button >
< div data-slot = "accordion-content" >
< div data-slot = "accordion-content-inner" >
Content for item two.
</ div >
</ div >
</ div >
</ div >
--accordion-panel-height — Set to the panel’s scrollHeight (in px) during open/close transitions, then reset to auto when settled.
--accordion-panel-width — Set to the panel’s scrollWidth (in px) during open/close transitions, then reset to auto when settled.
--radix-accordion-content-height / --radix-accordion-content-width — Radix-compatible aliases of the above.
The controller writes the following attributes on initialization and updates them as state changes:
The controller is returned by Accordion.createAccordion() and provides imperative control over the accordion’s state.
const controller = Accordion . createAccordion (root , {
defaultValue : "item-1" ,
} ) ;
// Expand programmatically
controller . expand ( "item-2" ) ;
// Collapse programmatically
controller . collapse ( "item-1" ) ;
// Toggle an item
controller . toggle ( "item-3" ) ;
// Read current state
console . log (controller . value) ; // ["item-2"]
// Clean up
controller . destroy () ; Was this page helpful?
Thanks for your feedback!