Slider
A range input with single or dual thumbs, tooltips, colors, sizes, and vertical orientation.
aria-* props now land on each thumb instead of the wrapper around it, so an aria-label names the control. class, style and data-* stay on the wrapper. A selector or test query that reached the control through the wrapper needs the change below./* Before 2.9.0: the attribute sat on the wrapper */
[aria-label="Volume"] [role="slider"] {
outline-offset: 4px;
}
/* From 2.9.0: it is on the control. In a test,
getByRole('slider', { name: 'Volume' }) now finds it */
[role="slider"][aria-label="Volume"] {
outline-offset: 4px;
}Playground
Experiment with different props in real-time.
Basic Usage
Single thumb slider.
<script lang="ts">
import { Slider } from 'sv5ui';
let value = $state(50);
</script>
<Slider bind:value />Range
Pass an array for dual-thumb range selection.
<script lang="ts">
import { Slider } from 'sv5ui';
let range = $state([25, 75]);
</script>
<Slider bind:value={range} />Min, Max & Step
Customize range and step increment.
<Slider min={0} max={1000} step={50} value={500} />
<Slider min={-50} max={50} step={10} value={0} />Sizes
5 track/thumb sizes.
xs
sm
md
lg
xl
<Slider size="xs" value={50} />
<Slider size="sm" value={50} />
<Slider size="md" value={50} />
<Slider size="lg" value={50} />
<Slider size="xl" value={50} />Colors
Semantic color schemes.
primary
success
warning
error
<Slider color="primary" value={60} />
<Slider color="success" value={60} />
<Slider color="warning" value={60} />
<Slider color="error" value={60} />Tooltip
Show value tooltip above thumbs.
<Slider tooltip value={50} />
<Slider tooltip value={[20, 80]} />Vertical
Vertical orientation.
<div class="flex gap-8 h-48">
<Slider orientation="vertical" value={60} />
<Slider orientation="vertical" value={[30, 70]} tooltip />
</div>Disabled
<Slider disabled value={40} />Controlled
Two-way binding with bind:value.
Value: 50
<script lang="ts">
import { Slider } from 'sv5ui';
let value = $state(50);
</script>
<Slider bind:value tooltip />
<p>Value: {value}</p>Accessibility
A slider renders no text, so it always needs a name: pass aria-label, or wrap it in a FormField. It lands on each thumb, where assistive technology looks for it, along with the other naming and describing attributes: aria-label, aria-labelledby, aria-describedby, aria-invalid, aria-required, aria-errormessage and aria-details. class, style, data-* and aria-hidden stay on the wrapper.
<!-- A slider has no label of its own: name it -->
<Slider aria-label="Volume" value={40} />
<!-- Two thumbs: both receive the same name -->
<Slider aria-label="Price range" value={[20, 60]} />With two thumbs, both receive the same attributes, so a range slider announces the same name for each end. onfocus and onblur are attached to the thumbs too. Inside a FormField the field label names each thumb and the description is announced.
UI Slots
Use the ui prop to override classes on internal elements.
| Slot | Description |
|---|---|
root | Root wrapper |
base | Base container |
track | Track element |
range | Range fill |
thumb | Thumb elements |
tooltip | Tooltip elements |
Props
| Prop | Type | Default |
|---|---|---|
value | number | number[] | 0 |
min | number | 0 |
max | number | 100 |
step | number | 1 |
orientation | 'horizontal' | 'vertical' | 'horizontal' |
color | ColorType | 'primary' |
size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' |
tooltip | boolean | false |
disabled | boolean | false |
autoSort | boolean | true |
onValueChange | (value) => void | - |
onValueCommit | (value) => void | - |
name | string | - |
ref | HTMLElement | null | null |
class | string | - |
ui | Record<Slot, Class> | - |