Vertically (or horizontally) stacked panels that expand and collapse one at a time.
Accordion
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
import { Accordion } from "@areia/slots" ;
Usage
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 ();
Expected Markup
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 >
Data Slots
CSS Custom Properties
--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.
Generated Attributes
The controller writes the following attributes on initialization and updates them as state changes:
Events
Outbound
Inbound
API Reference
Options
Controller
Controller
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 ();