Segmented Control
A single-select toggle bar: pick one of a few options from a connected button group.
Live demo
Segmented Control picks one option from a small, fixed set rendered as a connected button bar. It's the compact alternative to a radio group when the choices are few and worth showing at once.
It is a role="radiogroup" of role="radio" buttons with roving tabindex: the selected segment is the tab stop, arrow keys move and select with wraparound, and Home/End jump to the ends. Options are declared as a comma-separated options string, either bare labels (the label is the value) or label:value pairs. It's form-associated; give it a name and the chosen value submits. Three sizes: sm, md, lg.
When to use
How this component composes with the rest of the set.
Props
8 props, straight from the manifest.
| Prop | Type | Default | Bindings | Description |
|---|---|---|---|---|
Appearance
Sizes
sm
Compact.
md
Default.
lg
Large.
States
selected
The chosen segment: filled with the accent and its readable foreground. When the theme's --selection-cue resolves to marker (a high-contrast or redundant-cues algorithm), the selected segment gains a non-color check glyph so selection never rests on color alone.
hover
Pointer over an unselected segment; an overlay paints the hover tint.
focus-visible
Keyboard focus on a segment: a token ring plus a transparent outline that becomes real in forced-colors mode.
disabled
The whole group disabled: muted, non-interactive.
Anatomy
The named parts that make up the component, with their selectors.
field
The wrapper stacking the optional label over the toggle bar.
segmented
The role="radiogroup" track holding the options.
option
Each role="radio" segment; the selected one fills with the accent.
label
The optional visible label, referenced as the group's accessible name.
Tokens & coverage
What the component consumes, checked live against what the algorithm produces.
Live coverage check against the xoji-default register
(derive(xojiDefault, { anchors }) →
coverComponent(manifest, register)). Every token this component
consumes must be a key the algorithm produces.
--accent
--accent-2
--accent-2-fg
--accent-3
--accent-3-fg
--accent-4
--accent-4-fg
--accent-fg
--bg-1
--black
--black-fg
--blue
--blue-fg
--border-normal
--border-thick
--border-thin
--brown
--brown-fg
--cyan
--cyan-fg
--danger
--danger-fg
--duration-fast
--ease-standard
--fg-0
--fg-1
--fg-disabled
--font-sans
--gray
--gray-fg
--green
--green-fg
--info
--info-fg
--line-2
--neutral
--neutral-fg
--orange
--orange-fg
--pink
--pink-fg
--purple
--purple-fg
--radius-md
--radius-sm
--red
--red-fg
--ring
--selection-cue
--space-1
--space-2
--space-3
--space-4
--state-disabled
--state-hover
--state-press
--success
--success-fg
--text-body
--text-sm
--warn
--warn-fg
--weight-medium
--white
--white-fg
--yellow
--yellow-fg
Accessibility
Code
Labels, value pairs, and sizes
A view switch, an alignment control using label:value pairs, the compact size, and a disabled group.
<xoji-segmented label="View" options="Day,Week,Month" value="Week"></xoji-segmented>
<xoji-segmented label="Align" options="Left:start,Center:center,Right:end" value="center"></xoji-segmented>
<xoji-segmented size="sm" label="Theme" options="Light,Dark,Auto" value="Auto"></xoji-segmented>
<xoji-segmented label="Locked" options="One,Two,Three" value="Two" disabled></xoji-segmented>
<script lang="ts">
import { Segmented } from "@xoji/svelte";
let view = $state("Week");
</script>
<Segmented label="View" options="Day,Week,Month" bind:value={view} />
<Segmented label="Align" options="Left:start,Center:center,Right:end" value="center" />
<Segmented size="sm" label="Theme" options="Light,Dark,Auto" value="Auto" />
<Segmented label="Locked" options="One,Two,Three" value="Two" disabled />
---
import { Segmented } from "@xoji/astro";
---
<Segmented label="View" options="Day,Week,Month" value="Week" />
<Segmented label="Align" options="Left:start,Center:center,Right:end" value="center" />
<Segmented size="sm" label="Theme" options="Light,Dark,Auto" value="Auto" />
<Segmented label="Locked" options="One,Two,Three" value="Two" disabled />