Skip to content

Radio Group — Guidelines

When to use

PatternUse
catnip-radio-groupLabelled single-select from an options array (Figma Radio button Examples).
catnip-radio aloneSingle option, or a row you place yourself outside a radio group.
catnip-dropdownMany options in a compact panel.

Binding

vue
<catnip-radio-group
  label="Choose one"
  required
  intent="danger"
  supporting-text="Resolve the option-level errors below."
  .options="options"
  .modelValue="selected"
  @update:modelValue="selected = $event.detail[0] ?? $event.detail"
/>
js
const selected = ref("a");

const options = ref([
  {
    value: "a",
    label: "Option A",
    intent: "danger",
    supportingText: "Error message"
  },
  { value: "b", label: "Option B" },
  { value: "c", label: "Option C" }
]);

Bind .options and .modelValue on the host (see Component API).

Validation (group + per option)

Use two levels:

LevelSet onExample
Groupcatnip-radio-groupintent, supporting-text“Select a valid option.”
RowEach options[] item → intent, supportingText“This option is currently unavailable.”

Per-row intent is only neutral or danger (same as catnip-radio). Group intent also supports warning and success for the field supporting-text block.

Static row errors

Put intent and supportingText directly on the option object.

supportingText on an option accepts a string, string[], or { text, intent?, icon? } (same as Input).

Accessibility

  • The group uses role="radiogroup" with aria-labelledby pointing at the field label when visible.
  • Row intent="danger" sets aria-invalid on that radio's native input.
  • Toggling updates modelValue on the radio group host.
  • Keyboard navigation behaves exactly like native radio groups (arrow keys change selection, tab focuses the checked option).

Catnip Design System by Signicat