Collapsible

v0.0.10

v0.0.10StableHeadlessStatelessAccessibleJSApache-2.0
Installation mix mishka.ui.gen.headless collapsible
Source View Source

Overview of the Phoenix and LiveView Headless Collapsible Component

The Mishka Chelekom Headless Collapsible ships zero opinionated styling - only the semantic markup, full WAI-ARIA wiring, and paired-presence state (data-open/data-closed). Behavior is delegated to the shared Disclosure engine: the trigger toggles a single panel via aria-controls. Every part - item, trigger, and panel - is addressable through a *_class attribute, so you style it entirely with your own Tailwind classes while the accessibility and behavior keep working underneath.

Base UI Collapsible example (Phoenix headless)

Base UI Collapsible example (Phoenix headless)

heex
<.collapsible
  id="recovery-keys"
  class="w-48 text-neutral-950 dark:text-white"
  item_class="flex min-h-36 flex-col justify-center"
  trigger_class="group flex h-8 items-center justify-between gap-2 rounded-none border border-neutral-950 dark:border-white bg-white dark:bg-neutral-950 pl-3 pr-2 text-sm leading-none whitespace-nowrap font-normal text-neutral-950 dark:text-white select-none hover:not-data-[disabled]:bg-neutral-100 dark:hover:not-data-[disabled]:bg-neutral-800 active:not-data-[disabled]:bg-neutral-200 dark:active:not-data-[disabled]:bg-neutral-700 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white data-[disabled]:border-neutral-500 data-[disabled]:text-neutral-500 disabled:border-neutral-500 disabled:text-neutral-500 dark:data-[disabled]:border-neutral-400 dark:data-[disabled]:text-neutral-400"
  panel_class="flex h-[var(--accordion-panel-height)] flex-col justify-end overflow-hidden text-sm transition-[height] duration-150 ease-[ease-out] [&[hidden]:not([hidden='until-found'])]:hidden data-[ending-style]:h-0 data-[starting-style]:h-0"
>
  <:trigger>
    Recovery keys
    <svg
      width="16"
      height="16"
      viewBox="0 0 16 16"
      fill="currentColor"
      class="block transition-transform duration-100 ease-[ease-out] group-data-[panel-open]:rotate-90"
    >
      <path d="M6 12V4l4.5 4z" />
    </svg>
  </:trigger>
  <div class="flex flex-col gap-2 px-3.5 py-2">
    <div>alien-bean-pasta</div>
    <div>wild-irish-burrito</div>
    <div>horse-battery-staple</div>
  </div>
</.collapsible>

Parts & data attributes

Each part carries a stable data-part and a structural chelekom-collapsible__* class you can target, plus paired-presence state for open/closed transitions.

Partdata-partState / ARIAPurpose
Itemitemdata-value, data-open, data-disabled, data-on-open-changeWraps the trigger and panel pair.
Triggertriggeraria-expanded, aria-controls, aria-disabled, data-panel-openThe button that toggles the panel.
Panelpanelrole="region", aria-labelledby, data-open, data-closed, data-starting-style, data-ending-styleThe collapsible content region; stays mounted (hidden) when closed so the client engine can toggle it.

Accessibility

Follows the WAI-ARIA Disclosure pattern: the trigger exposes aria-expanded and aria-controls, the panel carries role="region" with aria-labelledby pointing back at the trigger, and Enter / Space toggle it from the keyboard.