jixoai-ui
the terminal design language
loading the style sheet…
Skip to content
docs · print medium: screen

registry:ui · native radio/checkbox

toggle-group — native segments, one field

A joined segment row of NATIVE inputs that submits as ONE form field. single rides label>input[type=radio] under one name — native arrow-walk, one tab stop, native exclusivity (re-press does NOT clear; an explicit none item is the optional-empty pattern). multiple rides checkboxes — every active value submits as its own FormData entry in DOM order (getAll on the server), never a CSV. DOM checked is the uncontrolled truth; bind:value is the projection (change → value, external writes → DOM, form.reset() re-syncs). The jx-form-field bridge is gone — name participates natively (REQUIRED for single: radio grouping is name-scoped). The paint law is the standard-layer jx-html-tgroup utility (single-sourced in jixoai.css) — the component owns only the Svelte law.

native radio/checkbox FormData multi-entry .jx-tgroup · Part A

toggle-group

Single swaps; multiple stacks — the bound values surface in the echo footer, one row per mode.

toggle-group-usage.svelte svelte
<ToggleGroup name="demo-align" type="single" label="alignment" bind:value={single}>
  <ToggleGroupItem value="left">left</ToggleGroupItem>
  <ToggleGroupItem value="center">center</ToggleGroupItem>
  <ToggleGroupItem value="right">right</ToggleGroupItem>
</ToggleGroup>

<ToggleGroup name="demo-style" type="multiple" label="text style" bind:value={many}>
  <ToggleGroupItem value="bold">bold</ToggleGroupItem>
  <ToggleGroupItem value="italic">italic</ToggleGroupItem>
  <ToggleGroupItem value="underline">underline</ToggleGroupItem>
</ToggleGroup>

demo

segmented → toggle-group type=single

antd's Segmented maps to the single mode — same one-active-submit contract. The mapping is SEMANTIC, not 1:1 paint: antd's sliding selection indicator and its exact keyboard walk are not imitated; if a future case needs the slide indicator or a strict single tab stop, that becomes a dedicated API upgrade — not a silent divergence.

mapping
<!-- antd: <Segmented options={['daily','weekly','monthly']} /> -->
<ToggleGroup name="range" type="single" label="range">
  <ToggleGroupItem value="daily">daily</ToggleGroupItem>
  <ToggleGroupItem value="weekly">weekly</ToggleGroupItem>
  <ToggleGroupItem value="monthly">monthly</ToggleGroupItem>
</ToggleGroup>

types

Toggle group variants

Single replaces the active value; multiple keeps an ordered set of pressed values.

toggle-group · variants

toggle-group-types-demo.svelte svelte
<script lang="ts">
  import { ToggleGroup, ToggleGroupItem } from '@ui/toggle-group/index';
</script>

<div class="grid w-full gap-4 sm:grid-cols-2">
  <div class="border border-border p-4"><ToggleGroup name="types-single" type="single" label="alignment"><ToggleGroupItem value="left">left</ToggleGroupItem><ToggleGroupItem value="center">center</ToggleGroupItem></ToggleGroup></div>
  <div class="border border-border p-4"><ToggleGroup name="types-multiple" type="multiple" label="style"><ToggleGroupItem value="bold">bold</ToggleGroupItem><ToggleGroupItem value="italic">italic</ToggleGroupItem></ToggleGroup></div>
</div>

usage

Usage

Compose a group from ToggleGroupItem parts; item values become the form payload identity.

Toggle group usage
<script lang="ts">
  import { ToggleGroup, ToggleGroupItem } from '@ui/toggle-group/index';
</script>

<ToggleGroup name="align" type="single" label="alignment" bind:value>
  <ToggleGroupItem value="left">left</ToggleGroupItem>
  <ToggleGroupItem value="center">center</ToggleGroupItem>
  <ToggleGroupItem value="right">right</ToggleGroupItem>
</ToggleGroup>

<ToggleGroup name="style" type="multiple" label="text style" bind:value>
  <ToggleGroupItem value="bold">bold</ToggleGroupItem>
  <ToggleGroupItem value="italic">italic</ToggleGroupItem>
</ToggleGroup>

a11y

Accessibility

The group is a labelled landmark over real native inputs — the radio semantics (arrow-walk, one tab stop, checked state) come from the platform, not ARIA re-creation.

Keyboard

KeyAction
TabEnter the group once (single) / walk items (multiple)
Arrow ← → ↑ ↓Walk single-mode segments (native radio)
SpaceToggle the focused segment

ARIA

AttributeValueDescription
roleradiogroup | groupNames the set as one landmark (single | multiple)
aria-labellabelProvides the group accessible name
input checkednativeThe real radio/checkbox state IS the item state

theming

Density and tokens

Group buttons use the shared hit target, inset, and typography tokens.

xs
sm
default
lg
TokenDefaultSource
--jx-hit28 / 32 / 40 / 48pxdensity
--jx-inset8 / 8 / 12 / 16pxdensity
--jx-text11 / 12 / 13 / 15pxdensity
--jx-line16 / 18 / 20 / 24pxdensity

axes

Universal props

The eight-axis surface (explicit-props): size · shape · radius · density · color · theme · elevation · motion — each axis takes named steps, auto (inherit the ambient context; stamps nothing), an exact number (px · coefficient · dp · hue per axis), or query() for responsive/container-conditional values. The group supplies the lanes to its item radios through the §11 broadcast.

ToggleGroup · universal props

toggle-group-universal.svelte svelte
<!-- the group forwards; the items inherit -->
<ToggleGroup name="scale" label="scale" density="small">
  <ToggleGroupItem value="sm">small</ToggleGroupItem>
  <ToggleGroupItem value="md">medium</ToggleGroupItem>
</ToggleGroup>

api

API

The root owns value semantics; item parts contribute their string identities.

Properties

PropertyTypeDefaultDescription
name string—Form field name for submitted values.
type 'single' | 'multiple''single'Select one value or a set.
value bindstring | string[][]Active value(s), bindable.
label * stringrequiredAccessible group label.
disabled booleanfalseDisables the whole group.
onchange (value) => void—Called after the active value changes (the native event, checked inputs in DOM order).
onValueChange (value: string | string[]) => void—The value-callback twin of onchange — the root fires both.
required booleanfalseForwards to the inputs in single mode only (multiple mode never submits a required constraint).
chrome 'frame' | 'ghost''frame' (the CONTROL_CHROME ambient ??)The ControlChrome posture — stamped data-chrome; a frame-owning row dissolves in-row (the borderless-chrome law).
children * SnippetrequiredToggleGroupItem parts.

Universal props

PropertyTypeDefaultDescription
size'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopethe base scale — root font-size; parts size in em
shape'round' | 'scoop' | 'bevel' | 'notch' | 'square' | 'squircle' | 'auto''auto' · ambient scopecorner geometry (CSS corner-shape; §14 degrade table)
radius'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopecorner size; auto = the concentric broadcast (§3)
density'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopespacing/leading scale over the kernel channels (§4)
color'primary' | 'secondary' | 'error' | 'warn' | 'success' | 'info' | 'auto' | number | string'auto' · ambient scopethe hue axis of the fixed oklch primary system (§5)
theme'light' | 'dark' | 'system' | 'auto''auto' · ambient scopelight/dark profile; system = the JS-mutable global (§6)
elevation'level-1' | 'level0' | 'level1' | 'level2' | 'level3' | 'level4' | 'level5' | 'auto' | number'auto' · ambient scopeofficial M3 levels over the surface ladder (§7)
motion'reduced' | 'subtle' | 'normal' | 'expressive' | 'auto' | number'auto' · ambient scopeintensity across the motion kernels (§8)
jixoai-ui ui.jixoai.com the jixoai design language

Theme

Brand hue

0°

Auto cycle · 24h