Skip to content

Accordion

A disclosure component using native <details>/<summary> elements, supporting single and multiple open modes with keyboard navigation. Item titles accept plain strings or snippets.

Import

import { Accordion } from "@hyzer-labs/ui"

Demo

Panels ship no display, height, or overflow of their own, so you can animate the open and close yourself. The reference theme's summary-icon rotation honors --hz-duration-* / --hz-ease-*. See Motion for the token values and the @hyzer-labs/ui/motion script-side helpers built on them.

What is @hyzer-labs/ui?

It is a Svelte component library that prioritizes behavior, structure, and accessibility.

Is it accessible?

Every component ships its WAI-ARIA pattern, and the token engine grades each color pairing against WCAG AA.

Can I use it with React?

No. It is Svelte 5 only.

<!-- The panel snippet receives the item: render per-item content -->
<Accordion items={faqs}>
	{#snippet panel(item)}
		<p>{answers[item.id]}</p>
	{/snippet}
</Accordion>

Props

NameTypeDefaultNote
itemsAccordionItem[]Required. See AccordionItem below.
type'single' | 'multiple''single'
defaultOpenstring | string[][]
collapsiblebooleantruefalse keeps one panel open in single mode.
headingLevel2 | 3 | 4 | 5 | 63
panelSnippet<[AccordionItem]>Required. Renders each panel.
iconSnippetReplaces the default chevron.
onToggle(openIds: string[]) => void
classstringMerged after the hz-accordion class.

AccordionItem

NameTypeDefaultNote
idstringRequired. Must be unique.
titlestring | SnippetRequired. String for plain text; snippet for inner markup.
disabledbooleanfalse

Theme hooks

What this component promises your CSS. The reference theme styles exactly these — from @layer hz-theme, so your unlayered rules win. See Styling Components for the how.

Root class: .hz-accordion

Data attributes

HookValuesStyles
data-state'open' | 'closed'On .hz-accordion-item; rotates the icon.
data-type'single' | 'multiple'Mirrors the prop. The behaviour is native <details> grouping, not CSS, so nothing in the theme reads this — it is yours.
[aria-disabled]'true'Disabled styling hangs off aria-disabled on .hz-accordion-trigger — not off the data-disabled that also appears on the item. Tabs does the opposite; match the component you are styling.

Part classes

HookValuesStyles
.hz-accordion-itemchild elementThe <details> element.
.hz-accordion-triggerchild elementThe <summary>.
.hz-accordion-headingchild elementThe heading inside the summary, at your headingLevel.
.hz-accordion-iconchild elementThe disclosure chevron.
.hz-accordion-panelchild elementThe content. The component ships no display/height/overflow on it on purpose, so it is free for you to animate.

Accessibility

Built on native <details>, so no ARIA is needed for disclosure semantics. Arrow keys move between summaries, and Home/End jump to the first and last.

Disabled items have aria-disabled='true' and block interaction. Summaries wrap a real heading (headingLevel) so panels join the document outline.

References: APG Accordion pattern