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

registry:ui · Data Entry

radio — the icon-ladder ring, scaled dot

Pure-CSS radio: appearance-none + 16px circle, :checked border primary + inner 8px dot (scale 0→1 transition), error wiring identical to checkbox.

pure CSS · zero icon deps :checked dot pop native arrow-key walking labelSide left / right label[for] + aria wiring

radio

appearance-none circle with a scaled dot — the native input keeps form participation, keyboard toggling, and same-name arrow-key walking; the glyph is pure CSS.

edge requires the nightly channel

radio-usage.svelte svelte
<Radio
  label="node"
  name="runtime"
  bind:group={picked}
/>
<Radio label="bun" name="runtime" bind:group={picked} />
<Radio label="deno" name="runtime" bind:group={picked} />
<!-- picked = 'bun' -->

radio

The selector, redrawn in pure CSS

A control where the paint deserved its own drawing code: the component strips appearance off the native input and draws its glyph with a pseudo-element — a scaled dot. Zero icon fonts, zero SVG, zero dependencies; the native input underneath keeps form participation, keyboard toggling, and :checked state.

:checked turns the border primary and pops the dot (14px at the default rung — the 16/18/20/24 ladder) from scale(0) to scale(1) (150ms ease-out). Same-name radios keep native arrow-key walking — tab into the group and use the arrows.

Radio usage
<!-- same-name radios keep native arrow-key walking -->
<Radio label="node" name="runtime" checked />
<Radio label="bun" name="runtime" />
<Radio label="deno" name="runtime" />

<!-- labelSide="left" flips the label to the inline-start -->
<Radio label="pro" name="plan" labelSide="left" />

types

Radio variants

Same-name radios form one native choice set; use label placement and disabled state as needed.

radio · variants

radio-types-demo.svelte svelte
<script lang="ts">
  import Radio from '@ui/radio.svelte';
</script>

<div class="grid gap-4 sm:grid-cols-3">
  <div class="border border-border p-4"><Radio label="selected" name="types-radio" checked /></div>
  <div class="border border-border p-4"><Radio label="label left" name="types-radio-left" labelSide="left" /></div>
  <div class="border border-border p-4"><Radio label="disabled" name="types-radio-disabled" disabled /></div>
</div>

usage

Usage

Give every option the same name and bind the selected value when the parent needs it.

Radio usage
<!-- same-name radios keep native arrow-key walking -->
<Radio label="node" name="runtime" checked />
<Radio label="bun" name="runtime" />
<Radio label="deno" name="runtime" />

<!-- labelSide="left" flips the label to the inline-start -->
<Radio label="pro" name="plan" labelSide="left" />

a11y

Accessibility

Native radio grouping supplies arrow-key walking and form semantics; the component adds explicit validation wiring.

Keyboard

KeyAction
Arrow keysMove selection within same-name radio group
SpaceSelect the focused radio

ARIA

AttributeValueDescription
aria-invalidtrueSet when error is present
aria-describedby{id}-errorReferences the validation message

theming

Density and tokens

The ring, dot, and label all consume the shared density scale.

xs
sm
default
lg
TokenDefaultSource
--jx-hit28 / 32 / 40 / 48pxdensity
--jx-icon16 / 18 / 20 / 24pxdensity
--jx-gap8 / 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 family CONSUMES size and color: the native element never receives them (the §1 native collision rule).

radio · universal props

radio-universal.svelte svelte
<Radio label="px number" size={14} density="small" value="a" group={g} />
<Radio label="named steps" size="large" radius="medium" value="b" group={g} />

api

API

Props extend native HTML input attributes; these additions define the radio-specific contract.

Properties

PropertyTypeDefaultDescription
label string—Same-row label rendered with label[for].
group bindstring | number—Bindable selected value for the radio channel.
labelSide 'left' | 'right''right'Places the label before or after the control.
error string—Adds invalid state and an associated message.

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