One choice from a set, wrapping the Base UI Radio and Radio Group. Arrow keys move the selection; the dot indicator renders itself.

Playground

Every control maps to a prop. The Code tab always shows the markup for exactly what you've configured.

States

Checked, unchecked, and disabled, with the disabled option keeping its label so the reason can sit right beside it. Radios stay round in pill mode (data-radius="pill", see Theming) because they were round already.

Styling states

State comes through data attributes (data-checked, data-disabled), so custom styling never needs JavaScript:

.ub-radio[data-checked] {
  background: var(--ub-success);
  border-color: var(--ub-success);
}

Props

Both parts pass the full Base UI API through. The essentials:

PropTypeDefaultDescription
RadioGroup.defaultValueanyThe option selected on first render, when uncontrolled.
RadioGroup.valueanyControlled selection. Pair with onValueChange.
RadioGroup.onValueChange(value) => voidCalled when the selection changes.
RadioGroup.disabledbooleanfalseDisables every radio inside.
Radio.valueanyIdentity of this option within the group.
Radio.disabledbooleanfalseDisables just this option.

Agent instructions

Working with a coding agent? Paste this into its context, or point it at llms.txt for the whole library.

Radio and RadioGroup, from @usebones/react.
- RadioGroup: defaultValue or value + onValueChange; disabled disables every radio inside. Radios go inside as <Radio value="..." />.
- Wrap each radio in a <label> with its text so the text is clickable.
- The dot indicator renders automatically; arrow keys move the selection. Radios stay round under data-radius="pill".
- Restyle in CSS via [data-checked], [data-disabled]; the dot is .ub-radio-indicator. Tokens only.