Radio
A radio group component for selecting a single option from a list of options.
Anatomy
Import and assemble the component:
1import { Radio } from "@raystack/apsara";23<Radio.Group>4 <Radio />5 <Radio />6</Radio.Group>
Usage
Size
Two sizes. large is the default; small fits dense lists. Set size on Radio.Root and every item follows.
1<Radio.Group defaultValue="1" size="large">2 <Flex gap={3} align="center">3 <Radio value="1" id="sl1" />4 <label htmlFor="sl1">Large Option One</label>5 </Flex>6 <Flex gap={3} align="center">7 <Radio value="2" id="sl2" />8 <label htmlFor="sl2">Large Option Two</label>9 </Flex>10</Radio.Group>
Orientation
vertical (the default) stacks the options, which scans faster for more than three. horizontal suits short binary choices in a row.
1<Radio.Group defaultValue="1" orientation="vertical">2 <Flex gap={3} align="center">3 <Radio value="1" id="ov1" />4 <label htmlFor="ov1">Option One</label>5 </Flex>6 <Flex gap={3} align="center">7 <Radio value="2" id="ov2" />8 <label htmlFor="ov2">Option Two</label>9 </Flex>10 <Flex gap={3} align="center">11 <Radio value="3" id="ov3" />12 <label htmlFor="ov3">Option Three</label>13 </Flex>14</Radio.Group>
With labels
Radio buttons should always be accompanied by labels for accessibility and usability.
1<Radio.Group defaultValue="1">2 <Flex gap={3} align="center">3 <Radio value="1" id="L1" />4 <label htmlFor="L1">Option One</label>5 </Flex>6 <Flex gap={3} align="center">7 <Radio value="2" id="L2" />8 <label htmlFor="L2">Option Two</label>9 </Flex>10 <Flex gap={3} align="center">11 <Radio value="3" id="L3" />12 <label htmlFor="L3">Option Three</label>13 </Flex>14</Radio.Group>
State
Radio buttons support different states to indicate interactivity and selection.
1<Radio.Group defaultValue="1">2 <Flex gap={3} align="center">3 <Radio value="1" id="d1" />4 <label htmlFor="d1">Default Option</label>5 </Flex>6</Radio.Group>
Form example
Radio buttons can be used in forms with proper validation and submission handling.
1<form2 onSubmit={(e) => {3 e.preventDefault();4 const formData = new FormData(e.target);5 alert(JSON.stringify(Object.fromEntries(formData)));6 }}7>8 <Flex direction="column" gap={5}>9 <Radio.Group name="plan" defaultValue="monthly">10 <Flex gap={3} align="center">11 <Radio value="monthly" id="mp" />12 <label htmlFor="mp">Monthly Plan</label>13 </Flex>14 <Flex gap={3} align="center">15 <Radio value="yearly" id="yp" />
Controlled
Pass value with onValueChange on Radio.Group to own the selection — needed when the choice drives something else on the page or is submitted with a form.
1(function ControlledRadio() {2 const [plan, setPlan] = React.useState("team");34 return (5 <Flex direction="column" gap={5}>6 <Radio.Group value={plan} onValueChange={setPlan}>7 <Flex align="center" gap={3}>8 <Radio value="solo" id="solo" />9 <Label htmlFor="solo">Solo</Label>10 </Flex>11 <Flex align="center" gap={3}>12 <Radio value="team" id="team" />13 <Label htmlFor="team">Team</Label>14 </Flex>15 </Radio.Group>
API Reference
Group
Groups radio buttons and manages their shared state.
Prop
Type
Root
Renders an individual radio button.
Prop
Type
Slots
Every rendered part carries a stable data-slot attribute for styling and testing:
| Slot | Element |
|---|---|
radio-group | The Radio.Group container |
radio | The radio button itself |
radio-indicator | The indicator inside the radio button |
Accessibility
- Follows the WAI-ARIA Radio Group pattern
- Supports keyboard navigation with arrow keys within the group
- Uses
role="radiogroup"for the group androle="radio"for items - Selected state is communicated via
aria-checked