Radio Group
Radio groups present mutually exclusive options. Only one choice can be selected at a time within the group.
Try it
Usage
Set value for the selected option and provide radio inputs as children. Wrap in RuiField for form integration. Set name on the group (or the field) to list inner radios on native FormData.
import { RuiRadio, RuiRadioGroup, RuiRadioGroupControl } from '@ecopages/radiant-ui/radio-group';
import { RuiField } from '@ecopages/radiant-ui/field';
import { RuiLabel } from '@ecopages/radiant-ui/label';
<RuiField name="plan">
<RuiLabel>Plan</RuiLabel>
<RuiRadioGroup value="pro" name="plan" label="Plan">
<RuiRadioGroupControl>
<RuiRadio value="free">Free</RuiRadio>
<RuiRadio value="pro">Pro</RuiRadio>
</RuiRadioGroupControl>
</RuiRadioGroup>
</RuiField>Custom markup
<rui-radio-group> coordinates any light-DOM tree that matches its query contract. The Rui* helpers stamp these targets; they are not required.
import '@ecopages/radiant-ui/radio-group';
<rui-radio-group value="pro" name="plan" label="Plan">
<div data-radio-group-root role="radiogroup" class="rui-radio-group">
<label class="rui-radio">
<input type="radio" class="rui-radio__input" value="free" />
<span class="rui-radio__control" aria-hidden="true"></span>
<span class="rui-radio__label">Free</span>
</label>
<label class="rui-radio">
<input type="radio" class="rui-radio__input" value="pro" />
<span class="rui-radio__control" aria-hidden="true"></span>
<span class="rui-radio__label">Pro</span>
</label>
</div>
</rui-radio-group>BEM classes are presentation-only. Do not set name, checked, or disabled on radios — the host owns those.
Mutually exclusive choices
Use radio groups when options are mutually exclusive. For independent toggles that share one field value, use a checkbox group; for a single on/off toggle, use a checkbox.
Theming
Radio group surfaces map to semantic roles, never Tailwind palette steps:
| Part | CSS roles |
|---|---|
Option row (.rui-radio) | on-background text, space-inline gap |
Control dot (.rui-radio__control) | border, background; primary when checked |
Checked dot (::after) | primary fill |
| Focus ring | focus-ring |
| Disabled | opacity-disabled |
The custom control dot is decorative (aria-hidden), the visually hidden native radio input carries the accessible state. Override at the theme layer, not in component CSS.
API
RuiRadioGroup is a custom element (<rui-radio-group>). Compose its options with RuiRadioGroupControl and RuiRadio, or use the convenience options prop to generate the same structure.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
value | string | '' | Selected radio value. |
name | string | '' | Form field name shared by all radios in the group. |
label | string | '' | Accessible name when no visible legend is composed in the view. |
disabled | boolean | false | Disables every radio in the group. |
Light-DOM contract
| Target | Required | Host writes | Author owns |
|---|---|---|---|
[data-radio-group-root] | yes | aria-label, aria-disabled | the group node |
input[type="radio"] | yes (per option) | name, checked, disabled | value, data-disabled |
Do not set name, checked, or disabled on radios. Nested hosts: none.
Events
| Event | Detail | Description |
|---|---|---|
rui-change | { value: string } | Emitted after the selected value changes. |
Props
| Prop | Type | Description |
|---|---|---|
options | RuiRadioOption[] | { value, label, disabled? } entries rendered by the view. |
View helpers
| Component | Target stamped | Notes |
|---|---|---|
RuiRadioGroup | <rui-radio-group> | Accepts options or children. |
RuiRadioGroupControl | [data-radio-group-root] | role="radiogroup" container. |
RuiRadio | input[type="radio"] | Label-wrapped option with value. |
CSS classes
Public BEM classes (documented via @cssclass):
| Class | Description |
|---|---|
.rui-radio-group | Group surface (role="radiogroup"). |
.rui-radio | Option label row (authored by the RuiRadioGroup view). |
.rui-radio__input | Visually hidden native radio input. |
.rui-radio__control | Custom control dot (mirrors check state). |
.rui-radio__label | Option text. |
Theme roles
| Part | CSS variables consumed |
|---|---|
| Option row | --on-background, --space-inline |
| Control dot | --border, --background, --primary |
| Focus | --focus-ring |
| Disabled | --opacity-disabled |
Accessibility
- The group exposes
role="radiogroup"with an accessible name fromlabel. - Arrow keys move selection between radio options.
- Visually indicate the selected option; do not rely on position alone.