Pricing

Radio handbook

v1.4.0 · @snowui-design-system/components

License: Before reading component documentation, source, or npm usage instructions for the first time, read the full LICENSE. Reuse that review for the same task and version. Public API configuration and internal implementation changes have different license implications. All components use the unified runtime package; source rights remain governed by the license.

Overview

Choose one option from a mutually exclusive set, suitable for form settings where every option should be visible.

When to use it

Use Radio for a single choice among visible options. Use Checkbox for independent choices and Segmented for compact mode selection. Give the group and each option accessible names.

  • Bind the same group state across options and give each option a distinct, stable value. Use null for an initially unselected group.

  • Clicking the selected option again can clear the selection to undefined. Do not assume a radio choice is irrevocable; provide readable labels.

Quick start

This example shows the recommended basic composition. See the sections below for more cases and composition limits.

<script lang="ts">	import { Radio } from '@snowui-design-system/components';	let subscribed = $state(false);</script> <Radio bind:checked={subscribed}>Email me product updates</Radio>

API

Keyword Type Default Description
checked boolean false Standalone state supports bind:checked. Clicking or pressing Space toggles it, including clearing an existing selection.
group any — Bind the same group state across Radio items with distinct values. Set the initial group to the chosen value, or null for no selection. Clicking the selected option again clears it.
value any — The value corresponding to the current option should be strictly equal to the group; the same group should use a unique and stable value.
size ResourceSize | number — Control size including transparent hit space. Supports 12/16/20/24/28/32/40/48/80 and custom values; inherits size context when omitted, otherwise defaults to 16.
disabled boolean false Prevent pointer and keyboard changes and remove the option from tab order while preserving its current selection state.
variant "outline" | "filled" "filled" Filled uses the coarse selection of the middle ring, and outline uses the thin outer frame and center point; both have the same selection behavior.
singleLine boolean true Labels and controls use one line by default, with stable attachments. A constrained label may show an ellipsis while retaining its complete accessible name and original children. Set false for complex multiline content. Compose Text lines={1} when a full-text tooltip is needed.
gap number — Inherited Frame gap token index. Omit it for the existing component gap; an explicit value overrides the preferred gap. Effective spacing stays at least 4 CSS px, including zero and root-font or gap-scale reductions. Larger preferred gaps are preserved.
children Snippet — The label displayed next to the circular control can combine the title and description; it is recommended to always provide readable labels.
enableResponsive boolean false The responsive capability switch passed to Frame; process the layout according to the responsive configuration of Frame.
enableContext boolean false Forward the general context capability switch to Frame. It does not control Radio’s own size-context or Image badge-context reading.

See the base component documentation for inherited capabilities not redeclared here. This table lists only named public Props declared by this component.

Usage boundaries and details

Keyword

Keyword Type Default Description
as 'badge' - Role: Image corner badge.

It is recommended to provide the name role="radiogroup" in the outer layer of the group. Use Tab focus and Space switching; the current component manages group values through binding, and does not provide in-group direction key navigation. The remaining attributes such as name and required are passed to the outer Frame, which is not equivalent to the form attributes of the native input of the inner layer.

Layout model

Main layout model: inline shell layout. See specs/maintainers/LayoutProtocol.md §12.4.

Radio belongs to the inline shell subcategory of "control visual body + label":

  • The root node keeps inline-flex, and the content is Hug as a whole.

  • .snowui-radio-visual is the control visual body of fixed Hug.

  • .snowui-radio-label is an optional label. It hugs its contents when there is room and can shrink with a single-line ellipsis when constrained. Original content and the complete native accessible name are preserved.

  • visual and label spacing uses --snowui-radio-gap. Set a preferred value with gap or --snowui-radio-gap-override; effective spacing stays at least 4 CSS px.

  • size indicates the space size of the control containing transparent white space, which does not change the layout strategy of the label.

  • The white space around is size / 16, and the width and height of the visible graphic are size × 0.875; for example, size={32} occupies 32×32px, the graphic is 28×28px, and the four sides are 2px each. The white and graphics are scaled with the size, root font size and size Token, and the white white can still be clicked.

  • The white space is held by the shared control shell, and the label is located outside the shell; the inner frame continues to be calculated according to the nominal size of 0.0625, and the rounded corners, Dot and selected rings are calculated according to the visible graphic size.

  • as="badge" only means that Radio is the corner pendant of Image, and does not change the internal layout model of Radio.


Usage examples

<script lang="ts">  let checked = $state(false);  import { Radio } from '@snowui-design-system/components';  let selected = $state('option1');</script>  <Radio bind:checked>Single option</Radio>  <Radio bind:group={selected} value="option1">Option 1</Radio><Radio bind:group={selected} value="option2">Option 2</Radio><Radio bind:group={selected} value="option3">Option 3</Radio>  <Radio bind:group={selected} value="filled" variant="filled">Filled style</Radio>  <Radio bind:checked size={20}>Large radio</Radio>

Outline

  • Not selected: gray border, transparent background

  • Select: theme color dots, gray border

Filled (default)

  • Not selected: gray border, transparent background

  • Select: theme color background, white dots

State

  • Unchecked: Unchecked status

  • Checked: Selected status

  • Disabled: Disabled status

Group behavior

When using the group attribute:

  • Automatically manage the single-choice logic in the same group

  • Selecting one will automatically cancel other options.

  • Clicking the currently selected item again will uncheck it.

  • After canceling the current selection, the group value will be cleared to undefined

  • The value of group is equal to the value of the selected item.

Accessibility

  • Use the native <input type="radio"> as the basic semantics, and add the "click again to cancel" logic in the component.

  • Support Tab key focus

  • Support Space key selection and cancellation

  • Group selection uses bindings. The component does not currently provide arrow-key navigation within the group.

  • In the disabled state, tabindex=-1

Radio style coverage

Read the full LICENSE first; reuse that review for the same task, version, and scope.

First use public component Props to match the desired appearance, preserving the existing look where possible. If changes are necessary, follow the style selection and override order: use your own class (including Tailwind already in the project) or an instance style. The names below are public overrides actually consumed by source; check their scope and do not modify private DOM. Choose the correct SnowUI token family. External apps need not install SnowUI website utilities.

Variable Purpose and default reference
--snowui-radio-border-motion-duration-override The duration of the dynamic effect of the border (see the component source code for the default value)
--snowui-radio-border-motion-easing-override Border dynamic effect curve (see the component source code for the default value)
--snowui-radio-border-width-override Border width (see the component source code for the default value)
--snowui-radio-color-override Color (see the component source code for the default value)
--snowui-radio-dot-size-override Dot size (size px, see the component source code for the default value)
--snowui-radio-filled-border-override Filled mode border (see the component source code for the default value)
--snowui-radio-gap-override Gap (default var(--gap-1) = 4px)
--snowui-radio-label-font-size-override Label font-size (see the component source code for the default value)
--snowui-radio-label-line-height-override Label line-height (see the component source code for the default value)
--snowui-radio-motion-duration-override Dynamic duration (see the component source code for the default value)
--snowui-radio-motion-easing-override Dynamic curve (see the component source code for the default value)
--snowui-radio-primary-override Main color (see the component source code for the default value)
--snowui-radio-radius-override Border-radius (see the component source code for the default value)
--snowui-radio-size-override Overall size (size px, see the component source code for the default value)

Design Guide · Token · Combination Boundary

Radio type and status

Required Props: no named required Props.

Bidirectional binding: bind:checked, bind:group.

Inheritance statement: Omit<FrameProps, "size">. The inheritance ability is subject to the public document of the base class; the fields in Omit have been excluded and cannot be used as they are according to the base class.

Share Frame API · Return API

The following type declarations are actually referenced by public Props and come from source. A Svelte Snippet denotes a content fragment; ComponentProps denotes the Props of the corresponding component.

ResourceSize

Source: components/src/context.ts

export type ResourceSize = 12 | 16 | 20 | 24 | 28 | 32 | 40 | 48 | 80;