Radio / RadioGroup

Single-item radio button and a convenience RadioGroup component — supports default, card and button variants with vertical or horizontal orientation.

Import

ts
import Radio      from '$lib/components/Radio.svelte';
import RadioGroup from '$lib/components/RadioGroup.svelte';

Usage

Use Radio directly with bind:group, or use RadioGroup for an options array.

svelte
<script lang="ts">
  let picked = $state('email');
</script>

<Radio bind:group={picked} value="email" label="Email" hint="Sent to your address" />
<Radio bind:group={picked} value="sms"   label="SMS"   hint="Sent to your phone" />

RadioGroup — default variant

Pass an options array and bind:value.

Notifications

Who can see posts

svelte
<script lang="ts">
  let notify = $state('all');
</script>

<RadioGroup
  bind:value={notify}
  options={[
    { value: 'all',      label: 'All activity',  hint: 'Every like, comment and follow' },
    { value: 'mentions', label: 'Mentions only', hint: 'When someone tags you' },
    { value: 'none',     label: 'None',           hint: 'Completely silent' },
  ]}
/>

Horizontal orientation

Add orientation="horizontal" to lay options side by side.

svelte
<RadioGroup
  bind:value={gender}
  orientation="horizontal"
  options={[
    { value: 'm',    label: 'Male' },
    { value: 'f',    label: 'Female' },
    { value: 'nb',   label: 'Non-binary' },
    { value: 'skip', label: 'Prefer not to say' },
  ]}
/>

Disabled

Set disabled: true on individual options to prevent selection.

svelte
<RadioGroup
  value="standard"
  options={[
    { value: 'free',     label: 'Free',     disabled: true },
    { value: 'standard', label: 'Standard' },
    { value: 'business', label: 'Business', disabled: true },
  ]}
/>

Card variant

Full-width cards with accent border when selected — great for plan pickers.

svelte
<RadioGroup
  bind:value={plan}
  variant="card"
  options={[
    { value: 'free',     label: 'Free',     hint: '3 posts/day · basic analytics' },
    { value: 'pro',      label: 'Pro',      hint: 'Unlimited posts · advanced analytics' },
    { value: 'business', label: 'Business', hint: 'Everything in Pro · team workspace' },
  ]}
/>

Card — horizontal

Cards laid side by side with orientation="horizontal".

Button / Segmented

Tab-bar style selector with variant="button".

svelte
<RadioGroup
  bind:value={period}
  variant="button"
  options={[
    { value: 'day',   label: 'Day'   },
    { value: 'week',  label: 'Week'  },
    { value: 'month', label: 'Month' },
    { value: 'year',  label: 'Year'  },
  ]}
/>

Example — plan selection form

Combining card and button variants in a subscription upgrade form.

Choose your plan

Upgrade or downgrade any time.

Billing

Plan

API Reference — Radio

PropTypeDefaultDescription
value unknownThe value this radio represents.
group unknownundefinedBindable — currently selected value. Matches checked state when equal to value.
label stringLabel text rendered next to the radio circle.
hint stringSecondary helper text below the label.
disabled booleanfalsePrevents interaction and reduces opacity.
onchange (v: unknown) => voidCallback fired when this radio is selected.

API Reference — RadioGroup

PropTypeDefaultDescription
options Option[]Array of { value, label, hint?, disabled? } objects.
value unknownundefinedBindable — the currently selected value.
variant 'default' | 'card' | 'button''default'Visual style of the group.
orientation 'vertical' | 'horizontal''vertical'Layout direction of the options.
onchange (v: unknown) => voidCallback fired when selection changes.
class stringExtra CSS classes applied to the wrapper.