Radio group

SvRadioGroup: a plan picker and a shipping selector with a disabled option, roving arrow-key focus and label + validation.

A live, editable Svelte 5 component example from the SvGrid gallery (Buttons & Toggles). Read the SvGrid UI component docs for the full API.

What this example shows

SvRadioGroup - a production plan picker and a shipping-method selector. Arrow-key navigable (WAI-ARIA radiogroup), with label + validation. Copy-paste ready.

Imports, features and API used

Imports: @svgrid/grid

Source code (310-radio-group.svelte)

<script lang="ts">
  /**
   * SvRadioGroup - a production plan picker and a shipping-method selector.
   * Arrow-key navigable (WAI-ARIA radiogroup), with label + validation. Copy-paste
   * ready.
   */
  import { SvRadioGroup } from '@svgrid/grid'

  const plans = [
    { value: 'starter', label: 'Starter - $0 / mo' },
    { value: 'pro', label: 'Pro - $29 / mo' },
    { value: 'team', label: 'Team - $99 / mo' },
    { value: 'enterprise', label: 'Enterprise - contact us' },
  ]
  const shipping = [
    { value: 'standard', label: 'Standard (5-7 days)' },
    { value: 'express', label: 'Express (2 days)' },
    { value: 'overnight', label: 'Overnight', disabled: true },
  ]
  let plan = $state<string | number | null>('pro')
  let ship = $state<string | number | null>(null)
  let submitted = $state(false)
  const shipError = $derived(submitted && !ship ? 'Choose a shipping method' : undefined)
</script>

<div class="wrap">
  <header>
    <h2>Radio group</h2>
    <p>Single choice with roving arrow-key focus (WAI-ARIA radiogroup) - plans, shipping, payment.</p>
  </header>

  <div class="cols">
    <section>
      <h3>Choose a plan</h3>
      <SvRadioGroup options={plans} value={plan} onChange={(v) => (plan = v)} />
    </section>

    <section>
      <SvRadioGroup
        options={shipping}
        value={ship}
        label="Shipping method"
        required
        invalid={!!shipError}
        error={shipError}
        onChange={(v) => (ship = v)}
      />
      <button class="btn" onclick={() => (submitted = true)}>Place order</button>
    </section>
  </div>
</div>

<style>
  .wrap { padding: 20px; max-width: 640px; display: flex; flex-direction: column; gap: 16px; }
  header h2 { margin: 0 0 4px; font-size: 20px; font-weight: 700; }
  header p { margin: 0; color: var(--sg-muted, #64748b); font-size: 13.5px; line-height: 1.5; }
  .cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 28px; align-items: start; }
  section h3 { margin: 0 0 10px; font-size: 12px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--sg-muted, #64748b); }
  .btn { margin-top: 14px; font: inherit; font-size: 13px; font-weight: 600; padding: 7px 16px; border: 0; border-radius: 8px; background: var(--sg-accent, #2563eb); color: var(--sg-on-accent, #fff); cursor: pointer; }
</style>

View this example on GitHub

Related documentation

Related articles

More Buttons & Toggles examples

  • Buttons & toggles - The UI kit press/toggle primitives: SvButton (variants/sizes/loading), SvRepeatButton (hold-to-repeat), SvToggleButton, SvSwitchButton, SvCheckBox (+ indeterminate), SvRadioGroup (arrow-key nav) and SvRating (half stars). Theme-driven, standalone or as grid cell controls.
  • Button group - SvButtonGroup: a segmented button bar - single-select (radio semantics, a view switcher), multi-select (a toggle set / formatting toolbar) or plain actions. Roving tabindex + arrow keys, and the shared editor contract (label, validation, dir/RTL).
  • Button - SvButton in production: a toolbar (variants primary/secondary/outline/ghost/danger), sizes, icon slots, a loading state and a full-width CTA. Copy-paste-ready blocks.
  • Repeat button - SvRepeatButton: hold-to-repeat with acceleration - a quantity stepper and a volume control block.
  • Toggle button - SvToggleButton: a pressed on/off button (aria-pressed) - a text-formatting toolbar and pin / live state toggles.