Slider ported
Pick a value or a range on a track that follows your finger.
Pick a value or a range on a track that follows your finger.
Loading demo…
Guidance
When to use
- Approximate values like volume, opacity, or a price range.
- Ranges with two thumbs, labelled marks, and a formatted readout.
When not to use
- Use number-field when the exact number matters.
- Use progress to show a value people cannot change.
pnpm dlx shadcn-svelte@latest add @arcui/sliderUsage
<script lang="ts">
import { Slider } from '$lib/components/slider';
let volume = $state(40);
</script>
<Slider label="Volume" bind:value={volume} />Variants & Examples
Single value
Bind a number. Omit value and pass defaultValue for uncontrolled use.
<Slider label="Volume" bind:value={volume} />Range
Bind a [low, high] tuple to get two thumbs. minStepsBetweenThumbs keeps them apart.
<Slider label="Budget" bind:value={range} step={5} minStepsBetweenThumbs={2} thumbLabels={['Minimum price', 'Maximum price']} />Marks
A bare number draws a tick. A mark with a label prints under the track, and clicking it moves the nearest thumb there.
<Slider label="Size" step={25} defaultValue={50} marks={[{ value: 0, label: 'S' }, 50, { value: 100, label: 'L' }]} />Start and end snippets
Place content beside the track, such as an icon.
<Slider label="Volume" bind:value={volume}>
{#snippet start()}<VolumeIcon />{/snippet}
</Slider>API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
value | T extends number | [number, number] | – | Bindable. A number for one thumb, a tuple for a range. Leave unset for uncontrolled use. |
defaultValue | T | – | Initial value when uncontrolled. Its shape (number or tuple) decides single or range. |
marks | (number | { value: number; label?: string })[] | – | Ticks on the track. A labelled mark also prints under the track and is clickable. |
label | string | – | (Required) Visible label; names the thumbs unless thumbLabels is set. |
onValueChange | (value: T) => void | – | Called on every step while dragging or pressing keys. |
onValueCommit | (value: T) => void | – | Called once when a drag is released or a key changes the value. |
min | number | '0' | Lower bound. |
max | number | '100' | Upper bound. |
step | number | '1' | Increment. |
largeStep | number | 'a tenth of the range' | Distance for PageUp, PageDown, and Shift with an arrow. |
minStepsBetweenThumbs | number | '0' | Closest two range thumbs may sit, in steps. |
format | (value: number) => string | – | Formats the readout, bubble, and spoken value. |
showValue | boolean | 'true' | Show the readout beside the label. |
thumbLabels | [string, string] | – | Accessible names for the two range thumbs. |
start | Snippet | – | Content before the track, such as an icon. |
end | Snippet | – | Content after the track. |
name | string | – | Submits the value with a form, one hidden input per thumb. |
disabled | boolean | – | Disables dragging and keys. |
className | string | – | Added to the root. |
Keyboard Interactions
| Key | Action |
|---|---|
ArrowRight / ArrowUp | Increases by step. |
ArrowLeft / ArrowDown | Decreases by step. |
Shift + Arrow / PageUp / PageDown | Moves by largeStep. |
Home / End | Moves to the lowest or highest allowed value for that thumb. |
Accessibility
- Each thumb is role="slider" with aria-valuemin, aria-valuemax, aria-valuenow, aria-valuetext from format, and aria-orientation.
- Thumbs are named by label, or by thumbLabels for ranges.
- The readout, bubble, and marks are aria-hidden because the thumbs carry the value.
Motion
Phase 1 (current): the thumb, fill, and readout jump straight to the stepped value; the bubble appears and disappears without animation. Phase 2 (React behaviour): - Released drags carry a little momentum before snapping; the bubble springs up over an active thumb and digits roll in the readout. At a limit the thumb strains toward the key press and springs back. - Reduced motion removes momentum, the strain, and digit rolling, and turns off CSS transitions.
Notes for AI
- Use for approximate values and ranges like volume, price filters, or opacity. Use number-field when the exact number matters.
- Controlled or uncontrolled; pass a tuple for a range. Put heavy work such as fetching in onValueCommit, not onValueChange.
- Pass name to submit through hidden inputs. Exported as a named export: import { Slider } from '$lib/components/slider'.
Source of truth: registry/components/slider/slider.tsx