Slider
Pick a value or a range by dragging thumbs along a track, with full keyboard support.
Single value
value is two-way. A press on the track moves the thumb there; arrows, Page keys, Home and End step it.
Code
<Slider value={state.volume} label="Volume"
onValueChange={(v, d) => log(d.reason)}
onValueCommit={(v, d) => commitLog(d.reason)} />
<p>{state.volume[0]}</p>Usage
import { Slider, SliderValue } from "@elements/ui/slider";
<Slider value={form.volume} label="Volume" />
<Slider value={filters.price} max={500} step={10} minStepsBetweenThumbs={2} name="price" />
<Slider value={eq.bass} orientation="vertical" label="Bass" />Examples
Range
Two values make a range. minStepsBetweenThumbs keeps them apart; format sets the spoken value.
Code
<Slider value={state.price} min={0} max={500} step={10}
minStepsBetweenThumbs={5} label="Price"
format={{ style: "currency", currency: "USD", maximumFractionDigits: 0 }} />Multiple thumbs
Any number of values. The range spans the outer thumbs.
Code
<Slider value={state.multi} /> <!-- [10, 40, 70] -->Thumb collisions
When a dragged thumb meets another it pushes it, swaps past it, or stops. The keyboard always stops.
Code
<Slider value={state.push} thumbCollisionBehavior="push" />
<Slider value={state.swap} thumbCollisionBehavior="swap" />
<Slider value={state.none} thumbCollisionBehavior="none" />Vertical
orientation=vertical fills the container's height. ArrowUp increases.
Code
<Slider value={state.bass} orientation="vertical" label="Bass" />
<Slider value={state.treble} orientation="vertical" label="Treble" />Fine steps
step 0.01 with a 0.1 large step, spoken as a percent.
Code
<Slider value={state.opacity} min={0} max={1} step={0.01} largeStep={0.1}
format={{ style: "percent" }} label="Opacity" />Disabled and invalid
A disabled slider leaves the tab order. disabledThumbs pins single thumbs. invalid marks the thumb aria-invalid and draws it in the danger color.
Code
<Slider value={[40]} disabled label="Locked" />
<Slider value={state.pinned} disabledThumbs={[0]} label="Window" />
<Slider value={state.level} invalid label="Level" />Thumb alignment
center puts the thumb's middle at the track's end; edge keeps the whole thumb inside.
Code
<Slider value={state.center} label="Center" />
<Slider value={state.edge} thumbAlignment="edge" label="Edge" />Direction
Under rtl the slider runs right to left and ArrowLeft increases. inverted runs from max to min.
Code
<Slider value={state.rtl} dir="rtl" label="Right to left" />
<Slider value={state.inverted} inverted label="Inverted" />In a form
name submits each value (name[] for a range). Reset restores the first values.
Code
<form onsubmit={(e) => submit(e)}>
<Slider value={state.price} name="price" />
<Slider value={state.volume} name="volume" />
<Button type="reset">Reset</Button>
<Button type="submit" variant="primary">Submit</Button>
</form>In a field
The field's label names the thumb.
Applies to every display.
Code
<Field label="Brightness" description="Applies to every display.">
<Slider value={state.brightness} />
</Field>Refusing a change
onValueChange gets details.cancel(): this one stops at 80.
Code
<Slider value={state.capped} label="Capped at 80"
onValueChange={(v, d) => v[0] > 80 && d.cancel()}
onValueCommit={() => state.cappedCommits++} />Spoken values
getAriaValueText and getAriaLabel set what a screen reader says. format and locale set the spoken number: here a German percent.
Code
<Slider value={state.temperature} min={10} max={30} step={0.5}
getAriaValueText={(f, v) => `${v} degrees`}
getAriaLabel={() => "Thermostat"} />
<Slider value={state.share} max={1} step={0.01} format={{ style: "percent" }} locale="de-DE" label="Anteil" />Marks
marks draws a tick inside the track at each value and markLabels prints them underneath. Pair them with step so the thumb snaps to each mark. SliderValue prints the value in an output.
Code
<SliderValue value={state.marked} htmlFor="loudness" />
<Slider value={state.marked} step={25} marks={[0, 25, 50, 75, 100]} markLabels
label="Loudness" attrs={{ id: "loudness" }} />