Accordion
Stacked sections that expand and collapse, animated with Alpine's x-collapse plugin.
<x-atlas::accordion>
Stock items leave the same working day. Made-to-order worktops take about three weeks.
Yes, within thirty days and unused. Cut-to-size items are the exception, as they cannot be resold.
We deliver throughout Belgium and Germany. Elsewhere in the EU, ask us for a quote first.
<x-atlas::accordion>
<x-atlas::accordion.item title="How long does delivery take?">
<p>Stock items leave the same working day. Made-to-order worktops take about three weeks.</p>
</x-atlas::accordion.item>
<x-atlas::accordion.item title="Can I return an order?">
<p>Yes, within thirty days and unused. Cut-to-size items are the exception, as they cannot be resold.</p>
</x-atlas::accordion.item>
<x-atlas::accordion.item title="Do you deliver outside the Netherlands?">
<p>We deliver throughout Belgium and Germany. Elsewhere in the EU, ask us for a quote first.</p>
</x-atlas::accordion.item>
</x-atlas::accordion>
Each item owns its state: a small Alpine scope holding expanded, a trigger button
that flips it, and a body animated by the x-collapse plugin. That means any number of
items can be open at once — there is no shared scope enforcing one. Use an accordion when the
reader wants one or two answers out of many, and tabs when they are
comparing alternatives that all deserve the same room.
x-collapse is an Alpine plugin, not part of the core. Register it before
Alpine.start() — a plugin added afterwards never reaches DOM Alpine has already
processed, and the body would then open with no animation or not at all.
Content prop
The slot wins whenever it is not empty; content is the fallback, echoed unescaped for
HTML that has already been rendered elsewhere. Never put user input through it.
Core and plugin updates, a security scan, and a monthly report.
On the first Tuesday of the month, outside office hours.
<x-atlas::accordion>
<x-atlas::accordion.item
title="What is included in maintenance?"
content="<p>Core and plugin updates, a security scan, and a monthly report.</p>"
/>
<x-atlas::accordion.item
title="When do you run updates?"
content="<p>On the first Tuesday of the month, outside office hours.</p>"
/>
</x-atlas::accordion>
Composed body
Bodies are ordinary slots, so anything can go inside — lists, buttons, a whole card. Content inside a collapsed item is still in the DOM, so keep it cheap and do not hide anything the page depends on being visible.
Yes. Changes take effect at the start of the next billing period, up or down.
<x-atlas::accordion>
<x-atlas::accordion.item title="Which plan should I choose?">
<x-atlas::list>
<x-atlas::list.item>Starter — one site, monthly updates.</x-atlas::list.item>
<x-atlas::list.item>Growth — five sites, weekly updates and staging.</x-atlas::list.item>
<x-atlas::list.item>Enterprise — unlimited sites and out-of-hours cover.</x-atlas::list.item>
</x-atlas::list>
<x-atlas::button href="/components">Compare the plans</x-atlas::button>
</x-atlas::accordion.item>
<x-atlas::accordion.item title="Can I change plan later?">
<p>Yes. Changes take effect at the start of the next billing period, up or down.</p>
</x-atlas::accordion.item>
</x-atlas::accordion>
Single disclosure
The wrapper adds nothing but a block container, so a lone item is a perfectly good disclosure for one optional block of detail.
Solid European oak, 40 mm, finished with a matte hardwax oil. Moisture content 8–10%.
<x-atlas::accordion.item title="Technical details">
<p>Solid European oak, 40 mm, finished with a matte hardwax oil. Moisture content 8–10%.</p>
</x-atlas::accordion.item>
aria-controls points at an id that is never rendered on the body, and
aria-expanded is set both on the item and on the button. variant="icon"
renders the icon component with no name, which produces an empty indicator — leave it unset until
the package gives it an icon.
Related components
Reference
<x-atlas::accordion>
Slots
-
- Name
default- Type
- slot
- Description
- The items. The wrapper is presentation only — each item holds its own open state.
<x-atlas::accordion.item>
-
- Name
title- Type
- string
- Description
- Heading shown in the trigger. Rendered as an h3; nothing is rendered when it is empty.
-
- Name
content- Type
- string
- Description
- Body as raw HTML, used only when the slot is empty. It is echoed unescaped, so never pass user input.
-
- Name
variant- Type
- string | icon
- Description
- icon replaces the plus-minus indicator with the icon component — see the caveat below.
Slots
-
- Name
default- Type
- slot
- Description
- The body. Takes precedence over the content prop.