--- title: Radio Group description: Radio groups present mutually exclusive options. Only one choice can be selected at a time within the group. category: Forms --- import { meta as RadioGroupMeta, Default } from '@/content/stories/radio-group'; import Canvas from '@/components/component-docs/canvas'; import Demo from '@/components/component-docs/demo'; export const config = { dependencies: { components: [Canvas, Demo], scripts: [ '../../components/component-docs/demo.script.tsx', '../../components/component-docs/canvas.script.tsx', '../../components/component-docs/controls.script.tsx', ], }, }; # 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`. ```tsx import { RuiRadio, RuiRadioGroup, RuiRadioGroupControl } from '@ecopages/radiant-ui/radio-group'; import { RuiField } from '@ecopages/radiant-ui/field'; import { RuiLabel } from '@ecopages/radiant-ui/label'; Plan Free Pro ``` ## Custom markup `` coordinates any light-DOM tree that matches its query contract. The `Rui*` helpers stamp these targets; they are not required. ```tsx import '@ecopages/radiant-ui/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 (``). 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` | `` | 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 from `label`. - Arrow keys move selection between radio options. - Visually indicate the selected option; do not rely on position alone.