Tinyrack

Radio Group

Owns one-of-many selection, keyboard navigation, and one native form value.

Contract

DecisionChoose
labelaria-label, aria-labelledby, or a fieldset legend
valuedefaultValue for uncontrolled state, or value with onValueChange
availabilityreadOnly keeps the selected option focusable; disabled removes interaction and form data
formgroup-level name, form, and required; reset restores defaultValue
keyboardarrow keys move focus and selection, skip disabled options, and wrap

The group allows exactly one selected value. It uses two-axis arrow navigation and has no public orientation prop; style visual direction with layout classes.

Install

pnpm add @tinyrack/ui

Scroll inside the code area to read long lines.

Styles

@import '@tinyrack/ui/components/radio-group.css';

Scroll inside the code area to read long lines.

Imports

import { TRRadioGroup } from '@tinyrack/ui/components/radio-group';
import { TRRadio } from '@tinyrack/ui/components/radio';

Scroll inside the code area to read long lines.

Playground

Usage

Examples

Set availability for the whole choice

Require one value

Associate an external form

External owner and reset permalink

`form` associates the group's hidden radio inputs with another form. Native reset restores the uncontrolled default.

API

Value, availability, and forms

PropType / defaultPurpose
value, defaultValueunknown, no selectionControls or initializes the selected child value.
onValueChange(value, details) => voidReports selection; details.cancel() can reject it.
disabled, readOnlyboolean, falseRemoves the group, or keeps its selected value focusable and immutable.
name, form, requirednative form propsConfigures serialization, external ownership, and constraint validation.
inputRefRef<HTMLInputElement>Accesses the group's hidden native input.

Uncontrolled groups restore defaultValue on owner-form reset; controlled groups remain governed by value. Disabled groups are omitted from FormData.

Composition and accessibility

Render uniquely valued TRRadio.Root children and give the group an accessible name. Wrap each option in a TRField.Item with a TRField.Label; the item scopes its label to the radio inside it, so options need no id or htmlFor. Every TRField.Item needs a TRField.Root ancestor, so wrap the item — or the whole group — in one TRField.Root. The root supports Base UI render, ref, native events and attributes, and state-driven className and style. It is SSR-safe and preserves selection during hydration.

The module exports TRRadioGroup, TRRadioGroupProps, and TRRadioGroupState. CSS is opt-in.