Radio group

Radios are for picking exactly one option out of a small, visible set. radio() renders one; choiceGroup() builds the whole set from an array and gives it the legend and role="radiogroup" that make it a group rather than a pile of inputs.

They share a name, so the browser handles the mutual exclusivity and the arrow-key navigation between them. Nothing here ships a script.

Basic radio group

Plan
choiceGroup({
  legend: 'Plan',
  name: 'plan',
  value: 'pro',
  options: [
    { value: 'free', label: 'Free' },
    { value: 'pro', label: 'Pro' },
    { value: 'team', label: 'Team' },
  ],
})

In a row

Short labels read better on one line. Long ones should stay stacked, which is the default.

Form factor
choiceGroup({
  legend: 'Form factor',
  name: 'form-factor',
  direction: 'row',
  value: 'desktop',
  options: ['desktop', 'mobile'],
})

Plain strings

When the value and the label are the same, pass strings.

Log level
choiceGroup({
  legend: 'Log level',
  name: 'log-level',
  direction: 'row',
  value: 'warn',
  options: ['info', 'warn', 'error', 'silent'],
})

Disabled options

Renderer
Full SSR needs a Node host, which this project does not have.
choiceGroup({
  legend: 'Renderer',
  name: 'renderer',
  value: 'static',
  options: [
    { value: 'static', label: 'Static' },
    { value: 'islands', label: 'Server islands' },
    { value: 'ssr', label: 'Full SSR', disabled: true },
  ],
  help: 'Full SSR needs a Node host, which this project does not have.',
})

One at a time

Use radio() directly when the options are not uniform enough to come from an array — for instance when each one carries its own description.

stack({ gap: 'md' },
  radio({ name: 'deploy', value: 'push', label: 'On every push', checked: true }),
  radio({ name: 'deploy', value: 'tag', label: 'On tagged releases only' }),
  radio({ name: 'deploy', value: 'manual', label: 'Manually' }),
)

Colors

stack({ direction: 'row', gap: 'lg', wrap: true },
  radio({ label: 'Primary', name: 'c1', checked: true, color: 'primary' }),
  radio({ label: 'Neutral', name: 'c2', checked: true, color: 'neutral' }),
  radio({ label: 'Success', name: 'c3', checked: true, color: 'success' }),
  radio({ label: 'Warning', name: 'c4', checked: true, color: 'warning' }),
  radio({ label: 'Danger', name: 'c5', checked: true, color: 'danger' }),
)

In a card

Build settings

Applied on the next deploy

Clean URLs
Images
card(
  cardHeader({ title: 'Build settings', subtitle: 'Applied on the next deploy' }),
  cardBody(
    stack({ gap: 'lg' },
      choiceGroup({
        legend: 'Clean URLs',
        name: 'clean-urls',
        direction: 'row',
        value: 'on',
        options: [
          { value: 'on', label: 'On' },
          { value: 'off', label: 'Off' },
        ],
      }),
      choiceGroup({
        legend: 'Images',
        name: 'images',
        value: 'optimise',
        options: [
          { value: 'optimise', label: 'Resize and convert' },
          { value: 'copy', label: 'Copy as-is' },
        ],
      }),
    ),
  ),
  cardFooter({ divided: true, style: 'justify-content: flex-end' },
    button({ type: 'submit' }, 'Save'),
  ),
)

Props

choiceGroup():

PropTypeDefaultDescription
legendChildLabel for the whole group.
namestringShared form name — what makes the radios exclusive.
optionsArray[]Strings, or { value, label, disabled } objects.
valuestring | number | ArrayWhich option is checked. An array for checkboxes.
type'radio' | 'checkbox''radio'Which control to build. Also picks the group role.
direction'row' | 'column''column'How the options are laid out.
helpChildHint under the group.

radio() takes the same props as checkbox(): label, color, checked, name, value and disabled.