Skip to main content
WireKit
Copy for LLM

Radio

A form control for single-select lists. Multiple radios sharing the same name form a mutually exclusive group.

Basic Usage

Radio group

With Hint

Radios with helper text per option

€9 billed each month

€90 per year — save 2 months

Card Variant

variant="card" turns each option into a bordered, fully-clickable card that highlights when selected — perfect for pricing tiers and plan pickers. The card reacts to its own input via CSS :has(), no JavaScript needed.

Pricing-tier cards

Sizes

sm, md (default), and lg scale the circle and its inner dot together, matching the size prop on Checkbox and Toggle.

Radio sizes

Disabled

Disabled options

With Error

Radio group with a group-level error message
Choose a plan:

Please select a plan.

When validation fails, apply the error prop to one of the radios (usually the last) so the message appears under the group. Wrap the group in a native <fieldset> + <legend> for the WCAG-standard group-label semantics — screen readers announce the legend before each radio in the set.

Livewire Integration

Bind every radio in the group to the same Livewire property via wire:model.live. The radios share a name so the browser already groups them; wire:model synchronizes the chosen value back to the component.

<x-wirekit::radio name="plan" value="free" label="Free" wire:model.live="selectedPlan" />
<x-wirekit::radio name="plan" value="pro"  label="Pro"  wire:model.live="selectedPlan" />

Props

Prop Type Default Description
label string|null null Text next to the radio
hint string|null null Helper text below
error string|null null Error message (also triggers aria-invalid)
value string|null null Value submitted when selected (required for grouping)
size string 'md' Circle size — sm, md, or lg
variant string 'default' default (inline) or card (the whole bordered card is the selectable target)
scope string|null null Scoped personalization name

The id is auto-generated as {name}-{value} when both are given, ensuring unique IDs within a radio group.

Accessibility

  • Native <input type="radio"> — browser provides full keyboard support:
    • Arrow keys navigate between options within the same name group
    • Space selects the focused radio
    • Tab moves focus to the first/checked radio of the next group
  • The visual circle and inner dot are decorative (aria-hidden="true").
  • For a screen-reader-announced group label, wrap related radios in a native <fieldset> with a <legend> — this is the WCAG-recommended pattern for grouped form controls and is announced before each radio in the set:
<fieldset>
    <legend>Choose a plan</legend>
    <x-wirekit::radio name="plan" value="free" label="Free" />
    <x-wirekit::radio name="plan" value="pro" label="Pro" />
</fieldset>

If <fieldset>'s default border or spacing is undesirable, reset it with style="border: 0; padding: 0;" rather than reaching for a <div role="group"> ARIA fallback — the native element wins on assistive-technology compatibility.

Keyboard Interaction

Key Action
Tab Move focus into the radio group
ArrowUp / ArrowLeft Move focus and selection to the previous radio in the group
ArrowDown / ArrowRight Move focus and selection to the next radio in the group
Space Select the focused radio (when entering the group with Tab)

Pitfalls

  • Don't omit name="..." on a radio group. All radios in the same group MUST share name — otherwise multi-selection is possible and the form posts unexpected data.
  • Don't use a radio group for binary on/off. A <x-wirekit::toggle> is the right pattern; radios are for ≥3 mutually exclusive choices.

Design Tokens

Token Purpose
--color-wk-accent Inner dot + active border
--color-wk-bg-input Circle background
--color-wk-border-strong / --color-wk-border-error Circle border
--color-wk-ring Focus ring

Further Reading

Was this page helpful?

Thanks — that helps.

Voting requires cookies or local storage. What we store