Skip to content
omaris

Selection

Radio

MD3 radio button.

import { Radio } from 'omaris'
Learn

Examples

Group

RadioGroup is the fieldset: it carries the legend, the name and the helper line, so the radios inside only need a value and a label.

Delivery

Charged at checkout.

<script lang="ts">	import { Radio, RadioGroup } from 'omaris';​	let speed = $state('standard');</script>​<RadioGroup label="Delivery" bind:value={speed} supportingText="Charged at checkout.">	<Radio value="standard" label="Standard" description="3–5 working days, free" />	<Radio value="express" label="Express" description="Next day, 5,000 IQD" />	<Radio value="pickup" label="Collect in store" description="Ready in an hour" /></RadioGroup>

Horizontal and states

Horizontal suits a short set of short labels, and nothing else.

Size
Invalid
Disabled
<script lang="ts">	import { Radio, RadioGroup } from 'omaris';​	let size = $state('m');</script>​<div class="flex w-full flex-col gap-8">	<RadioGroup label="Size" orientation="horizontal" bind:value={size}>		<Radio value="s" label="S" />		<Radio value="m" label="M" />		<Radio value="l" label="L" />	</RadioGroup>​	<RadioGroup label="Invalid" invalid supportingText="Pick a plan to continue." value="">		<Radio value="free" label="Free" />		<Radio value="pro" label="Pro" />	</RadioGroup>​	<RadioGroup label="Disabled" disabled value="a">		<Radio value="a" label="Not changeable" />		<Radio value="b" label="Nor this" />	</RadioGroup></div>

When to use it

Use it for

  • One of two to seven options, all visible: a plan, a shipping method, a delivery day. RadioGroup carries the legend, name, value and supportingText. Each Radio needs only a value and a label.
  • Options that need a line of explanation. Put it in description on each radio.
  • A required question. Set required and invalid on the group and put the reason in supportingText; it turns red and is announced.
  • A short set of short labels, like Yes/No or S/M/L. Use orientation="horizontal", and nothing longer.

Not for

  • More than seven options, or options with nothing to explain → Select; searchable → Combobox.
  • A choice that takes effect at once, in a toolbar or over a table → Segmented Button.
  • Any number of options → Checkbox; one on/off → Switch.
  • Switching between sections of a page → Tabs.

Do

  • Give every group a label. It is the fieldset's legend, read before each option.
  • Bind value on the group, not group on each radio. Inside a RadioGroup a radio takes its name, tone and size from it. bind:group is for a radio on its own.
  • Preselect the default when the form has one. Leave it empty only when the person must choose, and mark the group required.
  • Put the most common option first, not the cheapest or the alphabetical one.

Don't

  • Use bare Radios without a RadioGroup unless you build your own fieldset. You lose the legend, the helper line and the shared name that lets arrow keys move between them.
  • Disable an option to say it is unavailable. Explain in description, or drop it.
  • Write labels as sentences. Keep them short and put detail in description.

Quick reference

tone Radio
  • primary (default)
  • secondary
  • tertiary
  • destructive
  • success
  • warning
  • info
size Radio
  • sm
  • md (default)
  • lg
orientation RadioGroup
  • vertical (default)
  • horizontal

API

Radio

MD3 radio button.

Inside a <RadioGroup> it takes its name, value binding, tone and size from the group. On its own it works as a plain controlled radio — bind group the way you would with Svelte's own bind:group.

The dot scales in from nothing rather than appearing, which is the detail that makes a radio feel like MD3 rather than a browser default.

import { Radio } from 'omaris'

Parts

Every element this renders is reachable from outside. Pass Tailwind for one part as classes={{ part: '…' }}; class covers the root and is merged last, so it always wins.

root
No description in the source yet.
control
No description in the source yet.
circle
The ring.
dot
The filled center, scaled from 0 when unselected.
input
No description in the source yet.
label
No description in the source yet.
description
No description in the source yet.

Props

value required
string

This radio's value. Required — it's what the group selects.

group bindable

Defaults to undefined

string | undefined

The selected value, when the radio is used outside a group. Bindable.

tone
RadioTone
primary
secondary
tertiary
destructive
success
warning
info
size
RadioSizeToken
sm
md
lg
label
string
description
string
invalid
boolean
haptics

Defaults to true

boolean

A haptic tap when it's picked. Follows the shared haptics store; false opts this radio out.

sound

Defaults to true

boolean

A sound cue when it's picked. Follows the shared sound store; false opts this radio out.

class
string
classes
RadioClasses

Per-part Tailwind overrides. class still covers the root.

children
Snippet
ref bindable

Defaults to null

HTMLInputElement | null

RadioGroup

The fieldset around a run of radios: legend, the options, a helper line.

import { RadioGroup } from 'omaris'

Parts

Every element this renders is reachable from outside. Pass Tailwind for one part as classes={{ part: '…' }}; class covers the root and is merged last, so it always wins.

root
No description in the source yet.
label
The group heading, rendered as the fieldset's legend.
options
Where the radios sit.
support
No description in the source yet.

Props

value bindable

Defaults to undefined

string

Selected value. Bindable.

name
string

Shared name for the radios. Generated when omitted.

orientation

Defaults to 'vertical'

'vertical' | 'horizontal'
vertical
horizontal
tone

Defaults to 'primary'

Tone
size

Defaults to 'md'

RadioSize
disabled
boolean

Inside a Field, defaults to the field's.

required
boolean

Inside a Field, defaults to the field's.

invalid
boolean

Inside a Field, defaults to the field's.

label
string

Group heading, rendered as the fieldset's legend.

supportingText
string

Helper line under the group. Turns red when invalid.

class
string
classes
RadioGroupClasses

Per-part Tailwind overrides. class still covers the root.

children
Snippet