Spoiler

v0.0.10

v0.0.10StableHeadlessStatelessAccessibleJS-moduleApache-2.0
Installation mix mishka.ui.gen.headless spoiler
Source View Source

Overview of the Phoenix and LiveView Headless Spoiler Component

The Mishka Chelekom Headless Spoiler is a Phoenix function component that keeps a long section of content short until the reader asks for more. It renders a root div, a content region and a control button wired as a disclosure with aria-expanded and aria-controls. The button toggles data-expanded on the root with the LiveView JS.toggle_attribute command, so there is no server round trip and no JS hook to install.

The component draws no clamp and no colors. The collapsed height, the fade and the label swap are your CSS, keyed on data-expanded. The control renders both labels and you hide the one that does not apply, through show_label_class and hide_label_class. The root, the content and the control take class, content_class and control_class.

Base UI Spoiler example - clamped paragraph with a toggle (Phoenix headless)

Base UI Spoiler example - clamped paragraph with a toggle (Phoenix headless)

A spoiler keeps a long section of text short until the reader asks for more. This copy is long enough to be clipped when collapsed. Press the control to reveal the rest, and press it again to fold it away.
heex
<.spoiler
  id="baseui-spoiler"
  class="group max-w-sm text-sm text-neutral-700 dark:text-neutral-300"
  content_class="max-h-12 overflow-hidden transition-all group-data-[expanded]:max-h-40"
  control_class="mt-1 text-sm font-medium text-neutral-900 underline dark:text-white"
  show_label_class="group-data-[expanded]:hidden"
  hide_label_class="hidden group-data-[expanded]:inline"
>
  A spoiler keeps a long section of text short until the reader asks for more. This copy is
  long enough to be clipped when collapsed. Press the control to reveal the rest, and press
  it again to fold it away.
</.spoiler>

Attributes

id is required, and the content region gets the id "<id>-content" for aria-controls. expanded sets the initial state and defaults to false. show_label is the control text while collapsed and defaults to "Show more". hide_label is the text while expanded and defaults to "Show less". The default slot holds the content and is required.

Parts & data attributes

The root is marked data-part="root" and has data-expanded only while the content is open. The other parts are content, control, show-label and hide-label, each with a structural class such as chelekom-spoiler__content. The control button also flips its own aria-expanded between "true" and "false" on each press.

The toggle happens in the browser, so the server is not told when the spoiler opens or closes.

Accessibility

The component follows the WAI-ARIA disclosure pattern. The control is a real button, so Enter and Space toggle it. Clamping the content with overflow-hidden does not remove the hidden text from the accessibility tree, so a screen reader still reads all of it.