RadioGroup
StableA set of radio buttons for picking exactly one option, with a visible group name.
Also known as radio, radio buttons, option buttons
Install with npm install @tattva/ui (setup), or copy the code from the kit in Downloads.
With descriptions
function Example() {
const [v, setV] = useState("balanced");
return (
<RadioGroup label="Response style" value={v} onChange={setV} options={[
{ value: "fast", label: "Fast", description: "Short answers, less checking." },
{ value: "balanced", label: "Balanced", description: "A mix of speed and care." },
{ value: "careful", label: "Careful", description: "Slower, checks its work." },
]} />
);
}Each option has a short hint under its label.
When to use it
Lets a person pick exactly one of a few options, with every option visible at once. Each option can carry a short hint.
Made of: Legend · Radio circle · Label · Hint
Use it for
- A few options that need explaining, such as a response style.
- A form choice where the person should see all the options before picking.
- A choice that is saved later, not applied at once.
Not for
- A compact switch between views that applies at once: use SegmentedControl.
- Many options: use Select.
- Picking several options: use Checkbox.
- A single on or off setting: use Switch.
Do and avoid
Do
- Start with the most common option picked.
- Keep labels short and put detail in the hint.
- Keep the value in your own code and pass it back as value.
- Use the same shape of label for every option.
Avoid
- Do not use a RadioGroup for a long list of options. Use a Select.
- Do not use it for a setting that applies the moment it is picked. Use a SegmentedControl or a Switch.
- Do not hide the legend if people may not know what the question is.
- Do not disable the picked option without saying why.
On a phone
- Each option row is at least 44px tall on touch screens, and the whole row is tappable.
- The vertical layout is a single column; the horizontal layout wraps onto new lines when the options do not fit.
- Option labels and descriptions wrap rather than truncate.
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| optionsrequired | { value: string; label: ReactNode; description?: string; disabled?: boolean }[] | none | The choices. Each value must be unique in the group. |
| valuerequired | string | none | The picked value. The component is fully controlled. Use a value that matches no option for nothing picked. |
| onChangerequired | (value: string) => void | none | Called with the value of the option the person picked. |
| labelrequired | string | none | Name of the group, drawn as the legend. |
| hideLabel | boolean | none | Hides the legend visually. Screen readers still read it. |
| orientation | "vertical" | "horizontal" | "vertical" | Stack the options or lay them in a row that wraps. |
| invalid | boolean | none | Red border on every circle and aria-invalid on each radio. Show the error text yourself. |
| disabled | boolean | none | Disables the whole group through the fieldset. |
| name | string | none | Shared name of the radios. Set it if the group is inside a native form. Otherwise one is made for you. |
| className | string | none | Classes for the fieldset. |
"Show code under the preview gives the code for the example on the stage."
In Figma
In Figma, one RadioGroup switches all of this from its properties panel, across 8 variants. Each property sets the React prop beside it, so design and code use the same names.
| Figma property | React | Values |
|---|---|---|
| Hide label | hideLabel | On or off |
| Orientation | orientation | Vertical, Horizontal |
| Invalid | invalid | On or off |
| Label | label | Any text |
States
States this part has beyond its default look. Build each one your screen can reach. States set by a property are in the Code tab.
- hover
- The pointer shows a hand over an enabled row, and the label is part of the click target.
- focus
- A visible focus ring appears around the circle in focus when you reach the group with the keyboard.
- nothing picked
- When value matches no option, no circle is filled and Tab reaches the first enabled option.
Tokens
Change one of these and every part that uses it follows.
--accent--border-strong--danger--surface--dur-fast--focus-ring
Built in
- It is a fieldset with a legend, so screen readers announce the group name.
- The options are native radios with one shared name. Tab moves into the group, and the arrow keys move between options and pick them. This comes from the browser.
- Only the picked option is in the tab order. When nothing is picked, Tab reaches the first option.
- Each label is the name of its radio, and the hint is read after it.
- On touch screens each row is at least 44px tall.
- In high-contrast mode the circle and the dot use system colors.
What you need to do
- Give the group a label that names the question, such as "Response style". It is required.
- When the group is invalid, show the error as text. The red border is not enough on its own.
- Pick a starting value when you can. A group with nothing picked is easy to skip.
Built toward WCAG 2.2 AA and checked automatically; no independent audit yet. Read the accessibility guide