Components
Accordion
Accordion
An accordion expands to expose hidden information - great for condensing a page and letting the reader reveal content on demand, for a cleaner default view.
As of v4 the accordion is interactive out of the box with Phoenix.LiveView.JS - no Alpine.js required.
Basic
Collapsible sections with proper button semantics and keyboard toggling.
<.accordion class="w-full max-w-xl mx-auto">
<:item heading="Is it accessible?">
Yes - proper button semantics, aria-expanded, and keyboard toggling out of the box.
</:item>
<:item heading="Can several be open at once?">
Not by default. Pass the multiple attr to allow more than one open section.
</:item>
<:item heading="Does it follow the theme?">
Borders, radius and text tiers all come from the design tokens.
</:item>
</.accordion>
Bordered
The bordered variant wraps each row in the panel surface.
<.accordion variant="bordered" class="w-full max-w-xl mx-auto">
<:item heading="What's included?">
Auth, billing, orgs, admin and an AI-ready component library.
</:item>
<:item heading="Is it a subscription?">
One purchase, unlimited projects. No recurring fee.
</:item>
</.accordion>
Ghost
The minimal variant - hairline dividers, no surrounding box.
<.accordion variant="ghost" class="w-full max-w-xl mx-auto">
<:item heading="How do I install it?">
Add the Hex dep, run mix deps.get, and point Tailwind at the source.
</:item>
<:item heading="Does it need JavaScript?">
Interactivity is LiveView.JS only - no Alpine as of v4.
</:item>
</.accordion>
Dynamic
Data-driven - pass a list of entries and render each with the item slot. Handy for FAQ or CMS content.
<.accordion
class="w-full max-w-xl mx-auto"
entries={[
%{heading: "Where do the entries come from?", content: "A plain list of maps you pass in."},
%{
heading: "How is each row rendered?",
content: "The item slot receives the entry via :let."
},
%{heading: "Can the content be anything?", content: "Yes - it's a slot, so any markup works."}
]}
>
<:item :let={entry}>{entry.content}</:item>
</.accordion>
Properties
| Attribute | Type | Default | Description |
|---|---|---|---|
class
|
any |
nil
|
CSS class for parent container |
container_id
|
string |
||
entries
|
list |
[%{}]
|
|
multiple
|
boolean |
false
|
When true, multiple sections can be expanded simultaneously |
on_toggle
|
{:struct, Phoenix.LiveView.JS} |
%Phoenix.LiveView.JS{ops: []}
|
additional JS commands to run when an accordion section is toggled (LiveView.JS only) |
open_index
|
integer |
nil
|
Index of item to be open at render |
rest
|
global |
||
size
|
string |
"md"
|
sm tightens paddings and type for dense UIs (settings panels, sidebars)
one of: "sm", "md"
|
variant
|
string |
"default"
|
default is the shadcn row style (hairline dividers, no boxes); bordered is the boxed card-accordion. ghost is a legacy alias of default (identical look) slated for removal in a future major
one of: "default", "bordered", "ghost"
|
:item
slot
|
slot |
CSS class for parent container |