Overview of the Phoenix and LiveView Headless Radio Group Component
The Mishka Chelekom Headless Radio Group
ships zero opinionated styling
- only the semantic markup, full WAI-ARIA
radio group wiring, roving tabindex (Arrow keys move and select, Home/End jump to the
first/last enabled option), and live paired-presence state
(
data-checked
/
data-unchecked
).
The group itself and every item
are addressable through
class
and the
data-part
attribute they carry, so you style it entirely with your own Tailwind
classes while the accessibility and behavior keep working underneath.
Base UI Radio Group example (Phoenix headless)
<.radio_group id="baseui-radio-group-hero" name="baseui-radio-group-hero" value="pro" class="flex w-72 flex-col gap-2 [&_[data-part=item]]:flex [&_[data-part=item]]:items-center [&_[data-part=item]]:gap-2 [&_[data-part=item]]:rounded-md [&_[data-part=item]]:border [&_[data-part=item]]:border-neutral-950 dark:[&_[data-part=item]]:border-white [&_[data-part=item]]:bg-white dark:[&_[data-part=item]]:bg-neutral-950 [&_[data-part=item]]:px-3 [&_[data-part=item]]:py-2 [&_[data-part=item]]:text-left [&_[data-part=item]]:text-sm [&_[data-part=item]]:text-neutral-950 dark:[&_[data-part=item]]:text-white [&_[data-part=item]]:before:size-4 [&_[data-part=item]]:before:shrink-0 [&_[data-part=item]]:before:rounded-full [&_[data-part=item]]:before:border [&_[data-part=item]]:before:border-neutral-950 dark:[&_[data-part=item]]:before:border-white [&_[data-part=item]]:before:content-[''] [&_[data-part=item][data-checked]]:before:border-4 [&_[data-part=item][data-checked]]:before:border-neutral-950 dark:[&_[data-part=item][data-checked]]:before:border-white [&_[data-part=item][data-disabled]]:cursor-not-allowed [&_[data-part=item][data-disabled]]:opacity-40 focus-visible:[&_[data-part=item]]:outline-2 focus-visible:[&_[data-part=item]]:outline-offset-2 focus-visible:[&_[data-part=item]]:outline-neutral-950 dark:focus-visible:[&_[data-part=item]]:outline-white" > <:option value="free">Free</:option> <:option value="pro">Pro</:option> <:option value="enterprise">Enterprise</:option> <:option value="legacy" disabled>Legacy (unavailable)</:option> </.radio_group>
Parts & data attributes
Each item carries a stable
data-part
and a structural
chelekom-radio-group__*
class you can target, plus live paired-presence state kept in sync by the
RadioGroup
hook.
| Part | data-part | State / ARIA | Purpose |
|---|---|---|---|
| Root | (the group div) | role="radiogroup", aria-disabled, aria-readonly, aria-required, data-orientation, data-disabled | The container; wires ARIA and holds the RadioGroup hook. |
| Item | item | role="radio", aria-checked, aria-disabled, data-checked, data-unchecked, data-disabled | A selectable option; only the checked (or first enabled) item is tabbable. |
| Hidden input | (rendered when name is set) | type="hidden", required | Carries the selected value so the group submits with a form. |
Accessibility
Follows the
WAI-ARIA Radio Group pattern
: only one item is in the tab sequence at a time (roving tabindex), Arrow
Down/Right selects the next option, Arrow Up/Left the previous one (wrapping),
Home
/
End
jump to the first/last enabled option, and disabled items are skipped entirely.