Slider
A draggable range control for choosing a single value between a min and max, with full keyboard support.
Live demo
Slider picks one number across a range. It renders a rail with a fill showing the chosen portion and a role="slider" thumb carrying aria-valuemin/aria-valuemax/aria-valuenow, so pointer drag, click-to-position, and the full arrow/Page/Home/End keyboard set all move it.
Values snap to step and clamp to [min, max]. It is form-associated: give it a name and it contributes its current value to form data. Three sizes (sm, the default md, and lg) vary the thumb and rail thickness. It is the primitive the hue and alpha tracks of a color picker compose from.
When to use
How this component composes with the rest of the set.
Props
13 props, straight from the manifest.
| Prop | Type | Default | Bindings | Description |
|---|---|---|---|---|
Appearance
Sizes
sm
Compact: thin rail, small thumb.
md
Default.
lg
Large: thicker rail, bigger thumb for touch.
States
hover
Pointer over the thumb. Overlay paints the hover tint.
active
Thumb pressed or dragging. Overlay paints the press tint.
focus-visible
Keyboard focus on the thumb: a token-colored ring, plus a transparent outline that becomes real in forced-colors mode.
disabled
Non-interactive: muted fill and thumb, thumb removed from the tab order.
Anatomy
The named parts that make up the component, with their selectors.
slider
The column wrapper carrying the size and disabled classes and stacking the optional label above the rail.
rail
The interactive track the thumb travels along; its ::before paints the unfilled groove.
fill
The accent-colored portion of the rail from the minimum to the current value.
thumb
The draggable role="slider" knob positioned at the current value.
header
The row above the rail that lays out the label and value readout on opposite ends when either is shown.
label
The optional visible label that names the slider and is referenced as its accessible name.
value
The optional inline readout of the current value, shown when show-value is set and formatted by the format property.
overlay
The pseudo-element on the thumb that paints hover and active state tints.
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-3
--accent-4
--bg-0
--black
--blue
--border-normal
--border-thick
--border-thin
--brown
--cyan
--danger
--duration-fast
--ease-standard
--elevation-1
--fg-0
--fg-1
--fg-disabled
--field-bg
--field-border
--font-sans
--gray
--green
--info
--leading-tight
--line-2
--neutral
--neutral-bg
--orange
--pink
--purple
--radius-full
--radius-sm
--red
--ring
--space-1
--space-2
--space-4
--space-5
--space-6
--state-disabled
--state-hover
--state-press
--success
--text-body
--text-sm
--warn
--white
--yellow
Accessibility
Code
Ranges, sizes, and form association
A labeled slider, a stepped range, the compact size, a form-bound slider, and a disabled one.
<xoji-slider label="Volume" value="60"></xoji-slider>
<xoji-slider label="Brightness" min="0" max="100" step="5" value="40"></xoji-slider>
<xoji-slider size="sm" label="Compact" value="25"></xoji-slider>
<xoji-slider label="Opacity" name="opacity" value="80"></xoji-slider>
<xoji-slider label="Volume" value="60" show-value></xoji-slider>
<xoji-slider id="pct" label="Opacity" value="80" show-value></xoji-slider>
<script>
document.getElementById("pct").format = (v) => v + "%";
</script>
<xoji-slider label="Volume" value="60" hide-label></xoji-slider>
<xoji-slider label="Locked" value="50" disabled></xoji-slider>
<script lang="ts">
import { Slider } from "@xoji/svelte";
let volume = $state(60);
</script>
<Slider label="Volume" bind:value={volume} />
<Slider label="Brightness" min={0} max={100} step={5} value={40} />
<Slider size="sm" label="Compact" value={25} />
<Slider label="Opacity" name="opacity" value={80} />
<Slider label="Volume" value={60} showValue />
<Slider label="Opacity" value={80} showValue format={(v) => `${v}%`} />
<Slider label="Volume" value={60} hideLabel />
<Slider label="Locked" value={50} disabled />
---
import { Slider } from "@xoji/astro";
---
<Slider label="Volume" value={60} />
<Slider label="Brightness" min={0} max={100} step={5} value={40} />
<Slider size="sm" label="Compact" value={25} />
<Slider label="Opacity" name="opacity" value={80} />
<Slider label="Volume" value={60} showValue />
<Slider label="Volume" value={60} hideLabel />
<Slider label="Locked" value={50} disabled />