Radio Group
A set of radio buttons where only one option can be selected—paired labels, sizes, and grouped keyboard focus.
RadioGroup wraps Radio items so exactly one value is selected. Radio supports size: small | medium (default medium). Use Label with htmlFor / id on each Radio for an accessible name. The root reads dir from ThemeProvider for RTL-aware behavior.
Installation
The component is exported from @by/experience-system. Add the package with your package manager:
pnpm add @by/experience-systemIn this monorepo, depend on the workspace package (for example via workspace:* or your catalog) so imports resolve to packages/experience-system.
Composition
Use the following composition to build a RadioGroup:
RadioGroup
└── Radio (with optional Label)RadioGroup is the Radix RadioGroup.Root and Radio is RadioGroup.Item with Experience System sizing. Pair each Radio with a Label (via htmlFor / id) for an accessible name. Behavior follows Radix Radio Group.
Usage
import { Label, Radio, RadioGroup } from '@by/experience-system';RadioGroup and Radio are client components ('use client'). Use them inside a Client Component or a dynamic import when using the Next.js App Router. Wrap your tree in ThemeProvider so tokens and direction apply correctly.
<RadioGroup defaultValue="option-1" name="example">
<div className="flex items-center gap-2">
<Radio id="option-1" value="option-1" />
<Label htmlFor="option-1">Option 1</Label>
</div>
<div className="flex items-center gap-2">
<Radio id="option-2" value="option-2" />
<Label htmlFor="option-2">Option 2</Label>
</div>
</RadioGroup>Examples
Sizes
size changes the control footprint—compare small and medium on Radio.
Disabled
Disable individual items with disabled on Radio, or the whole group with disabled on RadioGroup.
With description
Controlled selection (value / onValueChange) with richer Label content—useful for plans, tiers, or settings cards.
API Reference
Pieces map to Radix UI Radio Group primitives. The tables below mirror the upstream API in full; layout defaults (grid gap-3), the size variant on Radio, and dir sourced from ThemeProvider are Experience System additions.
RadioGroup
RadioGroup contains all the parts of a radio group. Exported as RadioGroup; forwards RadioGroup.Root props from radix-ui. Layout defaults to grid gap-3; override with className. dir is supplied from ThemeProvider when not set explicitly.
| Prop | Type | Default |
|---|---|---|
asChild | boolean | false |
defaultValue | string | No default value |
value | string | No default value |
onValueChange | function | No default value |
disabled | boolean | false |
name | string | No default value |
required | boolean | false |
orientation | enum | undefined (no aria-orientation) |
dir | enum | From ThemeProvider |
loop | boolean | true |
| Data attribute | Values |
|---|---|
[data-disabled] | Present when disabled |
Radio
Radio — a selectable item in the group (Radix RadioGroup.Item). Requires a unique value. The indicator (RadioGroup.Indicator) is rendered internally; styling lives in variants.ts.
| Prop | Type | Default |
|---|---|---|
asChild | boolean | false |
value | string | No default value (required) |
disabled | boolean | No default value |
required | boolean | No default value |
id | string | No default value |
size | enum | "medium" (experience system: "small" | "medium") |
| Data attribute | Values |
|---|---|
[data-state] | "checked" | "unchecked" |
[data-disabled] | Present when disabled |
Accessibility
Radix manages roving tabindex, keyboard activation, and role="radiogroup" / role="radio" semantics. Ensure each option has a visible Label (or aria-label) tied to the Radio id, and give the group itself a name via the surrounding Field / Label or aria-labelledby when used outside a labelled form region.
Keyboard interactions
| Key | Description |
|---|---|
Tab | Moves focus to the checked item, or the first item if none is checked. |
Space | Selects the focused Radio when not already checked. |
ArrowDown / ArrowRight | Moves focus to the next item, wrapping when loop is true. |
ArrowUp / ArrowLeft | Moves focus to the previous item, wrapping when loop is true. |
Source in the repo: packages/experience-system/src/components/RadioGroup/RadioGroup.tsx and Radio.tsx. Agent-oriented contracts: packages/experience-system/src/components/RadioGroup/RadioGroup.instructions.md.