Components

Radio Group

A React radio group with circular Liquid Glass controls, labels, descriptions, and keyboard navigation.

RadioGroup renders a labelled group of circular glass radio controls. Each option can include a label and supporting description, and the entire row is clickable.

Options are passed through the items array; each item's value maps to the group value. Arrow keys move the selection between options, and the selected value is submitted through a hidden native radio input.

Basic example

label and description name the group and explain its purpose. Set defaultValue to start with an option selected, or use value with onValueChange for a controlled group.

PlanChoose the plan that fits your team.
FreeFor personal projects and experiments.ProFor growing teams that need more room.TeamFor larger organizations with shared billing.

Sizes

Supports xs / sm / md / lg / xl, defaulting to md. The control, indicator, label, description, and spacing scale together.

Size xs
First optionSecond option
Size sm
First optionSecond option
Size md
First optionSecond option
Size lg
First optionSecond option
Size xl
First optionSecond option

Controlled usage

value and onValueChange let external state fully control the selection. onValueChange also receives event details.

Shipping
Standard shippingArrives in 3–5 days.Express shippingArrives in 1–2 days.Store pickupReady today at your local store.

Selected: Standard shipping

Disabled and read-only

Set disabled on the group to disable every option, or on a single item to disable only that option. readOnly keeps the group focusable while preventing changes.

Disabled group
FreeProTeam
Read only
FreeProTeam
One disabled option
FreeProTeam

Accessibility

RadioGroup exposes a radiogroup named by label or by aria-label / aria-labelledby. Each option is a radio with its visible label and description linked automatically.

Arrow keys move between options and update the selection, and Space selects the focused option. The selected value is submitted through a hidden native radio; set required when a choice is mandatory. See the accessibility guide for form patterns.

API reference

RadioGroup

PropTypeDefaultDescription
labelReactNode—Visible label for the group.
descriptionReactNode—Supporting text under the group label, linked with aria-describedby.
aria-labelstring—Accessible name when no visible label is rendered.
aria-labelledbystring—ID reference for an external accessible name.
aria-describedbystring—ID reference for external supporting text. A visible description is merged with this value.
itemsreadonly RadioGroupItemProps[]—Options rendered by the group.
valueValue—Controlled selected value.
defaultValueValue—Initial selected value when uncontrolled.
onValueChange(value: Value, details) => void—Called when the selected value changes.
disabledbooleanfalseDisables every option.
readOnlybooleanfalsePrevents changes while remaining focusable.
requiredbooleanfalseRequires a selection for form submission.
namestring—Form field name.
formstring—ID of the form that owns the hidden inputs.
inputRefRef<HTMLInputElement>—Ref to the hidden native input.
size"xs" | "sm" | "md" | "lg" | "xl""md"Control, indicator, and text size.
renderReactElement | ((props, state) => ReactElement)—Replaces the group element.
refRef<HTMLDivElement>—Ref forwarded to the group element.
classNamestring—Tailwind classes merged into the group root.
styleCSSProperties—Inline styles merged into the same element as className.
ui{ root?: ClassValue; header?: ClassValue; label?: ClassValue; description?: ClassValue; items?: ClassValue; item?: ClassValue; box?: ClassValue; glass?: ClassValue; overlay?: ClassValue; indicator?: ClassValue; dot?: ClassValue; wrapper?: ClassValue; itemLabel?: ClassValue; itemDescription?: ClassValue }—Tailwind classes for internal slots, keyed by data-slot.

RadioGroupItem

PropTypeDefaultDescription
valueValue—Value that identifies the option in the group value.
labelReactNode—Visible label next to the control. It becomes the accessible name unless aria-label or aria-labelledby is provided.
descriptionReactNode—Supporting copy under the label, linked with aria-describedby when the option has a name.
disabledbooleanfalseDisables this option.
readOnlybooleanfalsePrevents changes to this option while remaining focusable.
requiredbooleanfalseMarks this option as required for form submission.
inputRefRef<HTMLInputElement>—Ref to the hidden native input.
aria-labelstring—Accessible name when no visible label is rendered.
aria-labelledbystring—ID of an external label.
aria-describedbystring—ID of external supporting text.
nativeButtonbooleanfalseWhether the rendered element is a native <button>.
renderReactElement | ((props, state) => ReactElement)—Replaces the option element.
refRef<HTMLSpanElement>—Ref forwarded to the option element.
classNamestring—Tailwind classes merged into the option root.
styleCSSProperties—Inline styles merged into the same element as className.
ui{ item?: ClassValue; box?: ClassValue; glass?: ClassValue; overlay?: ClassValue; indicator?: ClassValue; dot?: ClassValue; wrapper?: ClassValue; itemLabel?: ClassValue; itemDescription?: ClassValue }—Tailwind classes for this option's internal slots, keyed by data-slot.
AttributeDescription
data-checkedPresent when the option is selected.
data-uncheckedPresent when the option is not selected.
data-disabledPresent when the option or group is disabled.
data-readonlyPresent when the option is read-only.
data-requiredPresent when the option is required.
data-validPresent on every option when the group is valid and wrapped in Field.
data-invalidPresent on every option when the group is invalid and wrapped in Field.
data-touchedPresent on every option after the group is touched while wrapped in Field.
data-dirtyPresent on every option after the group value changes while wrapped in Field.
data-filledPresent on every option when the group has a selection while wrapped in Field.
data-focusedPresent on every option when any option is focused while wrapped in Field.
data-starting-stylePresent when the indicator begins animating in.
data-ending-stylePresent when the indicator is animating out.
data-slotMarks internal parts (root, header, label, description, items, item, box, glass, overlay, indicator, dot, wrapper, item-label, item-description) for styling.

Theming

The component uses the shared glass material. Tune shared --ui-glass-* tokens on a parent, use className for layout, and use ui for internal slots keyed by data-slot. Component-specific values live in src/theme/radio-group.ts. See the theming guide for token layers and presets.

  • Checkbox — For independent boolean choices.
  • Select — When the option list is long.
  • Switch — For an immediate on/off setting.