Shadix.Components.Accordion (shadix v0.0.1)

Copy Markdown View Source

A vertically stacked set of collapsible sections, built purely on client-side JS commands and CSS — no LiveView hook and no server round-trip.

Each trigger's phx-click flips a data-state of "open"/"closed" (and the matching aria-expanded) on both itself and its paired content panel. The panel animates open/closed in pure CSS using the grid-template-rows 0fr → 1fr technique: the content lives inside a grid whose single row transitions between 0fr (collapsed) and 1fr (expanded), with the inner wrapper clipping overflow. This animates the panel's height smoothly without anyone having to measure it, and degrades to an instant toggle under prefers-reduced-motion.

Because the collapsed panel stays in the DOM (so it can animate) rather than being display:none, it carries inert while closed to keep it out of the tab order and the accessibility tree; the same phx-click toggles inert. The trigger's data-state also drives the chevron rotation via the [&[data-state=open]>svg]:rotate-180 utility lifted from shadcn.

Ids wire the pieces together: accordion_item/1 takes a unique :id, accordion_trigger/1 and accordion_content/1 take that same id and derive "#{id}-trigger" / "#{id}-content" so aria-controls and the toggle target line up stably.

NOTE: type="single" auto-closing of sibling items is simplified — items behave as independent toggles in this v1, so type is currently advisory and rendered as a data-type hint on the root.

Summary

Functions

Renders the accordion root, a vertical stack of accordion_item/1s.

The collapsible body of an item. :id is the item id.

A single accordion item; wraps a trigger and its content.

The clickable header of an item. :id is the item id.

Functions

accordion(assigns)

Renders the accordion root, a vertical stack of accordion_item/1s.

:type is advisory in this v1 (see moduledoc): both "single" and "multiple" render independent toggles and the value is exposed as data-type for styling/JS hooks.

Attributes

  • type (:string) - Defaults to "single". Must be one of "single", or "multiple".
  • class (:string) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required)

accordion_content(assigns)

The collapsible body of an item. :id is the item id.

Renders <div id="#{id}-content" role="region">, collapsed (data-state="closed" and inert) by default. The panel animates open/closed in pure CSS via the grid-template-rows 0fr → 1fr trick keyed off data-state; the inner overflow-hidden wrapper clips the content as the row collapses. Under prefers-reduced-motion the transition is dropped and it toggles instantly.

Attributes

  • id (:string) (required)
  • class (:string) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required)

accordion_item(assigns)

A single accordion item; wraps a trigger and its content.

:id must be unique per item and is reused by accordion_trigger/1 and accordion_content/1 to wire aria-controls and the toggle target.

Attributes

  • id (:string) (required)
  • class (:string) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required)

accordion_trigger(assigns)

The clickable header of an item. :id is the item id.

Renders a <button id="#{id}-trigger"> with aria-controls="#{id}-content", aria-expanded and a data-state that toggle on click, plus a chevron SVG that rotates when data-state="open". The same phx-click flips the paired content panel's data-state (which drives the CSS open/close animation) and its inert attribute.

Attributes

  • id (:string) (required)
  • class (:string) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required)