RadioGroup
4 partsA set of mutually exclusive options where only one may be selected at a time,
built on role="radiogroup" with full keyboard roving focus (arrow keys move
and select, Space selects, Home/End and PageUp/PageDown jump to ends). The
container and state owner: it tracks the selected value (controlled via
v-model or uncontrolled via defaultValue), provides context to
RadioGroupItem, and renders a hidden form input when name is set and the
group lives inside a <form>.
Values are not limited to strings — numbers, booleans, null, and plain
objects are supported and compared structurally (override with by). Reach
for it whenever a user must pick exactly one choice from a small, visible
list.
Demo
Anatomy
Import the parts and compose them. Each part forwards attributes to its underlying element.
import {
Radio,
RadioGroupIndicator,
RadioGroupItem,
RadioGroupRoot,
} from '@robonen/primitives/forms/radio-group';
<RadioGroupRoot>
<Radio />
<RadioGroupIndicator />
<RadioGroupItem />
</RadioGroupRoot>API Reference
Radio
RadioA standalone radio, usable on its own outside a `RadioGroupRoot`. It owns its own `checked` state (controlled via `v-model:checked` or uncontrolled), and — when given a `name` inside a `<form>` — renders a hidden native input so its value participates in form submission and native validation. Like `RadioGroupItem` it emits a cancelable `select` event before toggling; call `event.preventDefault()` to veto.
| Prop | Type | Description |
|---|---|---|
id? | string | Element id, also used to derive an aria-label from an associated <label for=id>. |
value? | AcceptableValue | The value submitted with the owning form when name is set. |
disabled? | boolean | When true, the radio cannot be interacted with. |
required? | boolean | Marks the radio as required for assistive tech and native validation. |
name? | string | Name of the hidden form field submitted with the owning <form>. |
checked? | boolean | Two-way bound value (v-model:checked). |
| Event | Payload |
|---|---|
update:checked | [value: boolean] |
RadioGroupIndicator
IndicatorRenders its content only when the parent `RadioGroupItem` is selected, mirroring that state via `data-state`. Place the filled dot or check mark inside it. Wrapped in `Presence`, so it can animate out via CSS leave animations; use `forceMount` to keep it mounted for animation control.
| Prop | Type | Description |
|---|---|---|
forceMount? | boolean | Keep the indicator mounted regardless of checked state (for exit animations / measuring). |
RadioGroupItem
ItemA single selectable option within a `RadioGroupRoot`, rendered by default as a native `<button role="radio">`. Clicking, pressing Space, or arrow-keying onto it selects its `value`; it reflects selection via `data-state` and participates in the group's roving tab order. Provides context to a nested `RadioGroupIndicator`. Emits a cancelable `select` event before the value commits — call `event.preventDefault()` to veto the selection.
| Prop | Type | Description |
|---|---|---|
value | T | The value this item represents — any structural value, not just strings. |
disabled? | boolean | When true, the item cannot be selected or focused. |
required? | boolean | Marks the item as required (merged with the group-level required). |
id? | string | Associates a <label for=id>; its text becomes the radio's aria-label. |
RadioGroupRoot
RootA set of mutually exclusive options where only one may be selected at a time, built on `role="radiogroup"` with full keyboard roving focus (arrow keys move and select, Space selects, Home/End and PageUp/PageDown jump to ends). The container and state owner: it tracks the selected value (controlled via `v-model` or uncontrolled via `defaultValue`), provides context to `RadioGroupItem`, and renders a hidden form input when `name` is set and the group lives inside a `<form>`. Values are not limited to strings — numbers, booleans, `null`, and plain objects are supported and compared structurally (override with `by`). Reach for it whenever a user must pick exactly one choice from a small, visible list.
| Prop | Type | Description |
|---|---|---|
defaultValue? | T | The value of the radio item that should be checked when initially rendered (uncontrolled). |
disabled? | boolean | When true, prevents the user from interacting with radio items. |
required? | boolean | Marks the group, and every item, as required for assistive tech and native validation. |
name? | string | Name of the hidden form field submitted with the owning <form>. |
orientation? | 'horizontal' | 'vertical' | The orientation arrow navigation follows. |
dir? | RovingDirection | Reading direction. When omitted, inherits from the active ConfigProvider
(falling back to 'ltr'), so an app-wide RTL setting flips arrow navigation. |
loop? | boolean | When true, arrow navigation wraps from the last item to the first and vice versa. |
by? | RadioCompareBy | How an item value is compared against the selected value. Omitted →
structural deep equality; a function → custom comparator; a string →
compare that property key. |
modelValue? | T | undefined | Two-way bound value (v-model). |
| Event | Payload |
|---|---|
update:modelValue | [value: T | undefined] |