Accordion#

A stack of disclosures under one model. Each item is a native <details> with its <summary> as the trigger, so the platform provides the semantics and the keyboard; zero adds the group rule — at most one open in single mode, any number under multiple, and collapsible={false} to keep at least one open. The model is the array of open item values.

Import#

TSX
import { Accordion } from '@sigx/zero/accordion';

Accordion is a compound: Accordion.Root, Accordion.Item, Accordion.Trigger, Accordion.Panel. It is also re-exported from the @sigx/zero root, together with accordionAnatomy and useAccordionContext.

Usage#

TSX
import { component } from 'sigx';
import { Accordion } from '@sigx/zero/accordion';

const Faq = component(({ signal }) => {
    const state = signal({ open: ['shipping'] });

    return () => (
        <Accordion.Root model={() => state.open}>
            <Accordion.Item value="shipping">
                <Accordion.Trigger>How long does shipping take?</Accordion.Trigger>
                <Accordion.Panel>…</Accordion.Panel>
            </Accordion.Item>
            <Accordion.Item value="returns">
                <Accordion.Trigger>Can I return an order?</Accordion.Trigger>
                <Accordion.Panel>…</Accordion.Panel>
            </Accordion.Item>
            <Accordion.Item value="legacy" disabled>
                <Accordion.Trigger>Older orders</Accordion.Trigger>
                <Accordion.Panel>…</Accordion.Panel>
            </Accordion.Item>
        </Accordion.Root>
    );
});

model={() => state.open} binds the open values both ways — activating a trigger writes state.open, and writing state.open opens and closes the items. Leave the model off and pass defaultValue to keep the state inside the component; valueChange fires either way. See Models.

Multiple open items#

TSX
<Accordion.Root defaultValue={['a', 'b']} multiple>

Without multiple opening an item replaces the array with [value], closing whichever item was open; under multiple it appends, and every item opens and closes independently.

Always one open#

TSX
<Accordion.Root defaultValue={['a']} collapsible={false}>

By default the open item can be closed again. collapsible={false} refuses to close the last open item — the trigger click is a no-op while it is the only one — which is the "exactly one section visible" layout.

Anatomy#

PartElementStatesFlagsNotes
rootdivThe group container. Carries the variant axes.
itemdetailsopen | closeddisabledThe native open attribute is rendered from the model. Inside root.
triggersummaryopen | closeddisabled, focus-visible, pressed, press-animatingaria-expanded, aria-controls → its panel, aria-disabled. Publishes press feedback. Inside item.
paneldivopen | closedCarries the id its trigger controls. Inside item.

Every part carries data-scope="accordion" and data-part="<part>". The root has no states — open-ness is per item, so a design system styles item, trigger and panel on their open / closed selectors and uses the root for the box (border, radius, dividers between items). A <summary> has no disabled attribute, so a disabled trigger announces through aria-disabled="true" and stays a tab stop; disabled on the root disables every item. A closed <details> hides everything after its summary, so a closed rule on the panel never paints. See The anatomy contract.

Props#

Accordion.Root#

PropTypeDefaultDescription
modelstring[]Two-way binding of the open item values.
defaultValuestring[][]Initial value when uncontrolled.
valueChangeevent (value: string[])Fires whenever the set of open items changes.
multiplebooleanfalseAllow more than one item open at a time.
collapsiblebooleantrueWhether the last open item may be closed.
disabledbooleanfalseDisables every item; each item and trigger renders data-disabled.
color / size / variant / axes / modsdesign-system vocabularyThe variant axes, rendered as data-* on root.
classstringExtra classes on the root element.

Accordion.Item#

PropTypeDefaultDescription
valuestringrequiredThe value this item contributes to the model.
disabledbooleanfalseFreezes this item; renders data-disabled on the item and its trigger.
classstringExtra classes on the <details>.

Accordion.Trigger#

Only class. Renders the summary part around its children.

Accordion.Panel#

Only class. Renders the panel part around its children.

Keyboard#

KeyAction
Enter / SpaceToggle the focused item (native <summary> activation, routed through the model and the group rule).
Tab / Shift+TabMove between triggers; an open panel's content follows its trigger.

Every trigger is an ordinary tab stop — a <summary> is focusable by itself, and the component adds no roving arrow keys.

In the shipped design systems#

Both @sigx/zero-basic and @sigx/zero-daisyui wire color (all eight recommended roles) and size (xsxl) on accordion, so <Accordion.Root color="primary" size="lg"> is styled in both. Neither wires a variant or any mods on the scope; under a design system's /register import those props are therefore absent. See Typed vocabulary.

Collapsible for a single disclosure · Tabs when exactly one section is visible and the headings sit in a row.