Skip to main content

Accordion

Info:Controls html svelte astro Success: coverage 27/27

A stack of collapsible sections, one or many open at a time, driven by pointer or keyboard.

Live demo

live · @xoji/astro

Accordion

Single-open

What's your shipping time?How do returns work?Is there a warranty?
Orders placed before 2pm ship the same business day; everything else ships the next morning.
Unworn items are accepted within 30 days for a full refund — no restocking fee, no questions asked.
Every piece is covered against manufacturing defects for one year from the delivery date.

Multiple open · compact

AvailabilitySortSaved searches
In stock, on sale, free shipping.
Price, rating, newest first.
Sign in to save a search.

Accordion stacks a set of disclosure sections that expand and collapse. Each section pairs a [slot="header"] header with the [slot="panel"] that follows it; the component wraps every header in a heading and a role="button" trigger carrying aria-expanded and aria-controls, and turns each panel into a labelled role="region" that hides when collapsed.

By default it is single-open: opening one section closes the rest. multiple lets several stay open at once. Mark a header open to expand its section initially, or disabled to lock it. The heading level is h3 by default and settable with headingLevel, and three sizes (sm, md, lg) scale the trigger density. A chevron rotates with the open state, and pointer, Enter/Space, and the arrow/Home/End keys all drive it.

When to use

How this component composes with the rest of the set.

Pair headers and panels in order (a [slot="header"] followed by its [slot="panel"]) and repeat for each section.
Leave multiple off for an FAQ where one answer shows at a time; turn it on for independent filter or settings groups.
For a small fixed set of mutually exclusive views with their own content area, reach for Tabs instead.

Props

3 props, straight from the manifest.

PropTypeDefaultBindingsDescription
multiple boolean false
html svelte astro
Allows several sections to stay open at once; when off, opening one closes the others.
size Size
sm md lg
md
html svelte astro
Trigger density: `sm`, `md`, or `lg`.
headingLevel 2 | 3 | 4 | 5 | 6 3
html svelte astro
The heading level wrapping each trigger, so the accordion sits correctly in the document outline.

Appearance

Sizes

sm

.xoji-accordion--sm

Compact triggers.

md

default
.xoji-accordion

Default.

lg

.xoji-accordion--lg

Roomy triggers.

States

open

.xoji-accordion__trigger[aria-expanded="true"]

An expanded section: the trigger reads aria-expanded="true" and the chevron rotates.

trigger-hover

.xoji-accordion__trigger:hover

Pointer over a header: the hover tint paints behind it.

trigger-focus-visible

.xoji-accordion__trigger:focus-visible

Keyboard focus on a header: an inset token ring plus the transparent outline promoted in forced-colors mode.

disabled

.xoji-accordion__trigger:disabled

A locked header: muted and non-interactive.

Anatomy

The named parts that make up the component, with their selectors.

accordion

.xoji-accordion

The bordered container stacking the sections, with hairlines between them.

--font-sans --fg-0 --bg-1 --border-thin --line --radius-md

trigger

.xoji-accordion__trigger

The full-width header button that toggles its section; carries aria-expanded and the hover/press overlay.

--text-body --weight-medium --leading-tight --fg-0 --space-3 --space-4 --state-hover --state-press --border-normal --border-thick --ring --fg-disabled --duration-fast --ease-standard

chevron

.xoji-accordion__chevron

The disclosure caret in the trigger corner; rotates 180° when the section is open.

--fg-2 --duration-fast --ease-standard

panel

.xoji-accordion__panel

The collapsible role="region" holding the section content; hidden when collapsed.

--fg-1 --space-1 --space-4 --text-body --leading-normal

Tokens & coverage

What the component consumes, checked live against what the algorithm produces.

Success:fully covered 27/27 consumed tokens produced default register: 276 tokens

Live coverage check against the xoji-default register (derive(xojiDefault, { anchors })coverComponent(manifest, register)). Every token this component consumes must be a key the algorithm produces.

--bg-1 --border-normal --border-thick --border-thin --duration-fast --ease-standard --fg-0 --fg-1 --fg-2 --fg-disabled --font-sans --leading-normal --leading-tight --line --radius-md --ring --space-1 --space-2 --space-3 --space-4 --space-5 --state-hover --state-press --text-body --text-lg --text-sm --weight-medium

Slots

header
html svelte astro

Each section's header label, marked slot="header"; add open to expand it initially or disabled to lock it.

panel
html svelte astro

Each section's collapsible content, marked slot="panel", paired to the header before it by order.

Accessibility

Each header is a real <button> wrapped in a heading (h3 by default, set with headingLevel) so the sections land in the document outline and screen-reader rotor.
The trigger carries aria-expanded and aria-controls; its panel is a role="region" wired back with aria-labelledby, and hidden collapses it from the accessibility tree.
Pointer, Enter, and Space toggle a section; Up/Down arrows move focus between headers and Home/End jump to the first and last.
A header marked disabled is skipped by the arrow keys and cannot toggle.
Focus on a header shows an inset token ring plus a transparent outline the forced-colors base rule promotes to a real system outline.

Code

Single-open FAQ

Three sections where opening one collapses the others; the second starts open.

<xoji-accordion>
	<span slot="header">Shipping</span>
	<div slot="panel">Orders ship within two business days.</div>
	<span slot="header" open>Returns</span>
	<div slot="panel">Unworn items are accepted within 30 days.</div>
	<span slot="header">Warranty</span>
	<div slot="panel">Covered against defects for one year.</div>
</xoji-accordion>
<script lang="ts">
	import { Accordion } from "@xoji/svelte";
</script>

<Accordion>
	<span slot="header">Shipping</span>
	<div slot="panel">Orders ship within two business days.</div>
	<span slot="header" open>Returns</span>
	<div slot="panel">Unworn items are accepted within 30 days.</div>
</Accordion>
---
import { Accordion } from "@xoji/astro";
---

<Accordion multiple>
	<span slot="header">Shipping</span>
	<div slot="panel">Orders ship within two business days.</div>
	<span slot="header" open>Returns</span>
	<div slot="panel">Unworn items are accepted within 30 days.</div>
</Accordion>

Multiple open, with a disabled section

A compact accordion that lets several panels stay open, with one locked header.

<xoji-accordion multiple size="sm">
	<span slot="header" open>Filters</span>
	<div slot="panel">In stock, on sale, free shipping.</div>
	<span slot="header" open>Sort</span>
	<div slot="panel">Price, rating, newest.</div>
	<span slot="header" disabled>Saved searches</span>
	<div slot="panel">Sign in to save a search.</div>
</xoji-accordion>
<script lang="ts">
	import { Accordion } from "@xoji/svelte";
</script>

<Accordion>
	<span slot="header">Shipping</span>
	<div slot="panel">Orders ship within two business days.</div>
	<span slot="header" open>Returns</span>
	<div slot="panel">Unworn items are accepted within 30 days.</div>
</Accordion>
---
import { Accordion } from "@xoji/astro";
---

<Accordion multiple>
	<span slot="header">Shipping</span>
	<div slot="panel">Orders ship within two business days.</div>
	<span slot="header" open>Returns</span>
	<div slot="panel">Unworn items are accepted within 30 days.</div>
</Accordion>