Radio
The Radio component lets people choose a single option from a set. It’s a compound component: Radio.Root provides the group context and manages selection, and each Radio.Item is a selectable option. Radio.Item must always be used inside a Radio.Root.
Variations
Optional
The radio group can be marked as optional via the optional prop on Radio.Root.
If the Radio.Root has a label, the optional indicator will appear next to the label.
If there’s no label, the optional indicator will be shown next to each individual radio item.
Disabled
The radio group can be marked as disabled via the disabled prop on Radio.Root, which disables all radio items within the group.
Alternatively, the disabled prop can be passed to individual Radio.Item to disable them selectively.
Error state
The radio group can be marked as error via the error prop on Radio.Root.
With tooltip
tooltipContent is used to display the content of the tooltip. tooltipProps is used to pass additional props to the tooltip.
Orientation
The Radio.Root component accepts an optional orientation prop, which defines the layout direction of the radio and its group label.
Available options are horizontal and vertical (default).
Installation
import { Radio } from "@harnessio/ui/components";
function Example() { const [group1Value, setGroup1Value] = React.useState("option1");
return ( <Radio.Root label="Label text" caption="Caption text" value={group1Value} onValueChange={setGroup1Value} > <Radio.Item value="option1" label="Option 1" caption="This is option 1" /> <Radio.Item value="option2" label="Option 2" caption="This is option 2" /> </Radio.Root> );}Anatomy
Radio is a compound component built on Radix UI’s radio group. Wrap the options in Radio.Root and render one Radio.Item per choice.
<Radio.Root value={value} onValueChange={setValue} label="Label text"> <Radio.Item value="option1" label="Option 1" caption="This is option 1" /> <Radio.Item value="option2" label="Option 2" caption="This is option 2" /></Radio.Root>Radio.Root— the group container and context. Control the selection withvalue+onValueChange(or leave it uncontrolled withdefaultValue). It also carries the group-levellabel,caption,optional,error,disabled,orientation, and tooltip.Radio.Item— a single option.valueis required;labelandcaptiondescribe it. An item is disabled when its owndisabledis set or the group is disabled.
Best practices
Do
- Use radios when there are a few mutually exclusive options that are all worth showing at once; use a select when the list is long.
- Give the group a
label, and keep each item label short with an optionalcaptionfor detail. - Preselect a sensible default when one exists, so people aren’t forced to make a choice they don’t care about.
Don’t
- Don’t use a radio group for a single on/off choice — use a checkbox or switch.
- Don’t disable the whole group to communicate an error; use the
errorstate and keep the options readable.
Content
- Write item labels as parallel, self-contained phrases (“Everyone”, “Only me”).
- Use
captionfor the consequence or detail of an option, not to restate the label.
Accessibility
Keyboard
- Built on Radix’s radio group:
Tabmoves focus into the group, and the arrow keys move the selection between items. Only the selected item (or the first item, if none is selected) is in the tab order.
Labeling
- Each item’s
labelis wired to its input viahtmlFor/id, so clicking the label selects the item. If you omitlabel, provide an accessible name yourself. - The group exposes
radiogroupsemantics and items exposeradio, courtesy of Radix.
Focus & states
- The
errorprop toggles the group’s error styling; it does not, on its own, detect whether an item is selected. Drive it from your own validation.
Properties
The tooltipProps prop uses the IconWithTooltipProps shape:
interface IconWithTooltipProps extends Omit<TooltipProps, "children"> { className?: string; /** * If disabled, the tooltip will not be shown */ disabled?: boolean; iconProps?: IconPropsV2;}Radio.Root
Prop | Required | Default | Type |
|---|---|---|---|
| value | false | string | |
| onValueChange | false | (value: string) => void | |
| defaultValue | false | string | |
| name | false | string | |
| label | false | string | |
| caption | false | string | |
| disabled | false | boolean | |
| error | false | false | boolean |
| optional | false | false | boolean |
| orientation | false | 'vertical' | 'vertical' | 'horizontal' |
| tooltipContent | false | Exclude<ReactNode, boolean | null | undefined> | |
| tooltipProps | false | IconWithTooltipProps | |
| labelSuffix | false | ReactNode | |
| className | false | string | |
| wrapperClassName | false | string |
Radio.Item
Prop | Required | Default | Type |
|---|---|---|---|
| value | true | string | |
| label | false | string | ReactElement | |
| caption | false | string | ReactElement | |
| disabled | false | boolean | |
| id | false | string | |
| className | false | string |