|Kit

RadioGroup

A single-choice set of options on Ark UI's RadioGroup machine — inline labels, built-in label / description / error, native form submission, and full keyboard / ARIA.

RadioGroup is a single-choice control: a set of circular options, each with an inline label. The circles reuse the family's shared control surface, so they sit flush beside an Input, and label / description / error / required are built in via Field. It implements the kit's form-control contract — name submits, and ref / onBlur land on the group root — so it binds to react-hook-form, TanStack Form, or a plain <form> with no glue.

import { RadioGroup } from '@42/ui-react/radio-group';

<RadioGroup
  label="Coalition"
  items={[
    { value: 'federation', label: 'The Federation' },
    { value: 'order', label: 'The Order' },
    { value: 'alliance', label: 'The Alliance' },
  ]}
/>

The items prop also accepts bare strings, normalized to { value, label }:

<RadioGroup label="Size" items={['Small', 'Medium', 'Large']} />

Playground

Component

Loading preview

Props

Code

<Component  label="Coalition"  orientation="vertical"  size="md"  variant="default"/>

Orientation

Options stack vertically by default. Set orientation="horizontal" to lay them out in a wrapping row.

Code

<RadioGrouplabel="Coalition"orientation="horizontal"defaultValue="order"items={[  { value: 'federation', label: 'The Federation' },  { value: 'order', label: 'The Order' },  { value: 'alliance', label: 'The Alliance' },]}/>

Sizes

Five sizes — xs through xl — matching the rest of the family. The circle and its dot scale together.

Code

<RadioGroup size="xs" defaultValue="a" items={[{ value: 'a', label: 'xs' }]} /><RadioGroup size="sm" defaultValue="a" items={[{ value: 'a', label: 'sm' }]} /><RadioGroup size="md" defaultValue="a" items={[{ value: 'a', label: 'md' }]} /><RadioGroup size="lg" defaultValue="a" items={[{ value: 'a', label: 'lg' }]} /><RadioGroup size="xl" defaultValue="a" items={[{ value: 'a', label: 'xl' }]} />

Variants

Two variants decide the selected circle's fill. default is a neutral, monochrome circle that stays palette-independent; filled tints the circle with color. The two share one inner dot.

Code

<RadioGroupvariant="default"defaultValue="a"items={[{ value: 'a', label: 'Default' }]}/><RadioGroupvariant="filled"color="brand"defaultValue="a"items={[{ value: 'a', label: 'Filled' }]}/>

Colors

color tints the selected circle in the filled variant — the default variant stays monochrome. The resting circle is palette-independent, and the focus ring is always the brand ring. Set data-color once on the root and every kit palette tints for free.

Code

<RadioGroup variant="filled" color="brand" defaultValue="a" items={[{ value: 'a', label: 'brand' }]} /><RadioGroup variant="filled" color="green" defaultValue="a" items={[{ value: 'a', label: 'green' }]} /><RadioGroup variant="filled" color="blue" defaultValue="a" items={[{ value: 'a', label: 'blue' }]} /><RadioGroup variant="filled" color="purple" defaultValue="a" items={[{ value: 'a', label: 'purple' }]} /><RadioGroup variant="filled" color="red" defaultValue="a" items={[{ value: 'a', label: 'red' }]} />

Disabled & per-option disabled

disabled dims the whole group and blocks interaction. A single option can also be disabled by setting disabled on its items entry.

Code

<RadioGrouplabel="Coalition"defaultValue="federation"items={[  { value: 'federation', label: 'The Federation' },  { value: 'order', label: 'The Order (full)', disabled: true },  { value: 'alliance', label: 'The Alliance' },]}/><RadioGroup label="Coalition" disabled defaultValue="federation" items={[{ value: 'federation', label: 'The Federation' }, { value: 'order', label: 'The Order' }]} />

With description & error

description (helper text) and error sit below the group via the built-in Field. Passing error flips the circles to the invalid (red) state; required adds the semantic flag and a red asterisk on the label.

You can change this at any time.
Please choose a coalition

Code

<RadioGrouplabel="Coalition"description="You can change this at any time."defaultValue="order"items={[{ value: 'federation', label: 'The Federation' }, { value: 'order', label: 'The Order' }]}/><RadioGroup label="Pick a coalition" required items={[{ value: 'federation', label: 'The Federation' }, { value: 'order', label: 'The Order' }]} /><RadioGroup label="Pick a coalition" error="Please choose a coalition" items={[{ value: 'federation', label: 'The Federation' }, { value: 'order', label: 'The Order' }]} />

Controlled

Drive the selection from state. onChange hands you the next value (a string).

'use client';
import { useState } from 'react';
import { RadioGroup } from '@42/ui-react/radio-group';

export function CoalitionPicker() {
  const [coalition, setCoalition] = useState('federation');
  return (
    <RadioGroup
      label="Coalition"
      value={coalition}
      onChange={setCoalition}
      items={[
        { value: 'federation', label: 'The Federation' },
        { value: 'order', label: 'The Order' },
      ]}
    />
  );
}

Forms

Each option renders a hidden native <input type="radio"> sharing the group name, so a name wires the selection into native <form> submission and FormData.

<form action={save}>
  <RadioGroup
    name="coalition"
    label="Coalition"
    items={[
      { value: 'federation', label: 'The Federation' },
      { value: 'order', label: 'The Order' },
    ]}
  />
</form>

API

Prop

Type

Accessibility

  • Full RadioGroup model from Ark: arrow keys move between options and select, Space selects the focused option, focus shows the ring, and the group / label / description / error associations are wired (the latter via the built-in Field).
  • Each option is backed by a hidden native <input type="radio"> sharing the group name, exposing role="radio" with aria-checked.
  • invalid (or error) sets aria-invalid on the options.
  • RTL is honored via the document dir — circles and labels mirror automatically.

On this page