Skip to main content
Urbicon UI

RadioGroup

Accessible radio group for single-option selection with semantic intents, keyboard navigation, and form integration.

Playground

Notification preference
Orientation
Variant
Size
<RadioGroup
  intent="primary"
  size="md"
  variant="outlined"
>
  <RadioItem value="all" label="All notifications" />
  <RadioItem value="mentions" label="Mentions only" />
  <RadioItem value="none" label="None" />
</RadioGroup>

01 Examples

Plan picker with descriptions

Pair each option with secondary text — the most common pattern for plan pickers, settings and preferences. Bound to value, so the selection drives the surrounding UI.
Choose your plan

Selected: pro

<div class="border-border-subtle bg-surface-elevated w-full space-y-4 rounded-2xl border p-5">
  <RadioGroup label="Choose your plan" bind:value={selectedPlan} intent="success">
    <RadioItem
      value="free"
      label="Free"
      description="3 projects, 1 GB storage, community support"
    />
    <RadioItem
      value="pro"
      label="Pro — $12/mo"
      description="Unlimited projects, 100 GB, priority support"
    />
    <RadioItem
      value="enterprise"
      label="Enterprise"
      description="Custom limits, SLA, dedicated account manager"
    />
  </RadioGroup>
  <p class="text-text-tertiary text-xs">
    Selected: <span class="text-text-primary font-medium">{selectedPlan}</span>
  </p>
</div>

Per-item disabled

Disable individual options while the rest of the group stays interactive. Keyboard navigation skips disabled items.
Shipping speed
<RadioGroup label="Shipping speed" value="standard">
  <RadioItem value="standard" label="Standard (3-5 days)" />
  <RadioItem value="express" label="Express (1-2 days)" disabled />
  <RadioItem value="overnight" label="Overnight" />
</RadioGroup>

Helper & error

Group-level helper and error text follow the same form-field contract as Input — error overrides helper when both are set.
Frequency
You can change this later in settings
Agreement
<RadioGroup label="Frequency" helper="You can change this later in settings">
  <RadioItem value="daily" label="Daily" />
  <RadioItem value="weekly" label="Weekly" />
</RadioGroup>
<RadioGroup label="Agreement" error="Please select an option to continue">
  <RadioItem value="accept" label="I accept" />
  <RadioItem value="decline" label="I decline" />
</RadioGroup>

Theme Selector

Horizontal layout for compact inline choices.
Appearance
<div class="border-border-subtle bg-surface-elevated rounded-2xl border p-5">
  <RadioGroup
    label="Appearance"
    orientation="horizontal"
    bind:value={selectedTheme}
    intent="neutral"
  >
    <RadioItem value="light" label="Light" />
    <RadioItem value="dark" label="Dark" />
    <RadioItem value="system" label="System" />
  </RadioGroup>
</div>

02 Customization

Card Options via slotClasses

RadioGroup styles the group shell (root, group, label, message); each RadioItem owns its item, indicator, dot, label, and description slots. Here every option becomes a bordered card that highlights while selected — the has-[:checked] variant reads the native input inside the item.
Region
<RadioGroup label="Region" value="eu" slotClasses={{ group: 'gap-2' }}>
  <RadioItem
    value="eu"
    label="EU (Frankfurt)"
    description="GDPR-friendly, lowest latency in Europe"
    slotClasses={{
      item: 'w-full rounded-xl border border-border-subtle p-3 has-[:checked]:border-primary has-[:checked]:bg-primary/5'
    }}
  />
  <RadioItem
    value="us"
    label="US (Virginia)"
    description="Closest to North American users"
    slotClasses={{
      item: 'w-full rounded-xl border border-border-subtle p-3 has-[:checked]:border-primary has-[:checked]:bg-primary/5'
    }}
  />
</RadioGroup>

unstyled (per item) drops the indicator and label styling while the native radio semantics, roving tabindex, and arrow-key navigation keep working. When the card treatment above is your app's standard option style, register it once as a BlocksProvider preset (presets.RadioGroup / presets.RadioItem) instead of repeating slotClasses — see Customization.

03 Accessibility

Native Semantics

Built on native <input type="radio"> elements inside a role="radiogroup" container for correct form behavior and assistive technology support. The group label is linked via aria-labelledby, and error/helper text via aria-describedby.

Keyboard

Tab into the group focuses the selected (or first) item. Arrow keys move between options and select automatically. Vertical groups use Up/Down, horizontal groups use Left/Right. Navigation wraps around at both ends.

Focus Management

Uses roving tabindex: only the selected item (or the first item when nothing is selected) is in the tab order. Disabled items are skipped during arrow key navigation. Focus rings use focus-visible: via the peer pattern for keyboard-only visibility.

Reduced Motion

All Mint effects and transitions respect prefers-reduced-motion. The dot transition is purely visual and does not affect interaction.

04 API Reference

21 props
21 props 1 required
Prop
Type
Default
Description

05 Types

Local type definitions used by this component.

14 types
Name
Kind
Category
Used by
Description

06 Installation

Import

import { RadioGroup, RadioItem } from '@urbicon-ui/blocks';