Slider
Picks a number, or a range with two thumbs, by dragging along a track.
import { Slider } from '@aksornproject/aksara-ui'Single value
A number in value or defaultValue gives one thumb. Pass exactly one of the two. min, max and step default to 0, 100 and 1. The slider fills its container, so set a width on the parent or with className.
<div className="w-full max-w-spacing-320">
<Slider label="Volume" defaultValue={50} />
</div>Range
A pair, [start, end], gives two thumbs. There is no mode prop, because the shape of the value picks it. onValueChange fires on every drag move and key press, and onValueCommitted fires once when the drag ends. A range handler receives a SliderRange. minStepsBetweenValues keeps the thumbs apart.
<div className="w-full max-w-spacing-320">
<Slider
label="Price"
value={price}
onValueChange={setPrice}
max={1000}
step={50}
formatValue={(value) => `฿${value}`}
thumbLabels={['minimum', 'maximum']}
valueDisplay="text"
/>
</div>Value display
valueDisplay picks where the value shows. tooltip, the default, shows a bubble above a thumb while it is hovered, dragged or keyboard focused. text shows the value beside the track and reserves the width of the value at min and max, so the track never resizes under the pointer. none hides it. formatValue writes the bubble, the text and what screen readers announce.
<div className="flex w-full max-w-spacing-320 flex-col gap-spacing-24">
<Slider label="Tooltip" defaultValue={30} valueDisplay="tooltip" />
<Slider
label="Text"
defaultValue={60}
valueDisplay="text"
formatValue={(value) => `${value}%`}
/>
<Slider label="None" defaultValue={80} valueDisplay="none" />
</div>Marks
marks draws ticks on the track. A number draws a tick, and { value, label } also draws a label under it. Marks outside min and max are dropped. Marks do not snap the value. step does.
<div className="w-full max-w-spacing-320">
<Slider
label="Grade level"
defaultValue={[2, 4]}
min={1}
max={6}
marks={GRADES}
formatValue={(value) => `P${value}`}
/>
</div>Vertical
orientation="vertical" gives a fixed 160px control. Mark labels sit to the right of their ticks.
<Slider
aria-label="Zoom"
defaultValue={40}
orientation="vertical"
valueDisplay="text"
formatValue={(value) => `${value}%`}
/>Field
required draws a star after label, and optional draws "(Optional)" or a string you pass. Both are visual only, and a slider takes one or the other. info puts a help icon after the label that opens a tooltip. description sits under the label. status and message render the shared field message under the slider. While disabled, disabledMessage takes the place of message to say why.
<div className="flex w-full max-w-spacing-320 flex-col gap-spacing-24">
<Slider
label="Quiz time"
required
info="Students see a countdown with this many minutes."
description="How long students have to finish."
value={minutes}
onValueChange={setMinutes}
min={10}
max={90}
step={5}
formatValue={(value) => `${value} min`}
status={minutes > 60 ? 'warning' : undefined}
message={
minutes > 60 ? 'Long quizzes tire younger students.' : undefined
}
/>
<Slider
label="Passing score"
optional
defaultValue={50}
disabled
disabledMessage="Turn on grading to set a passing score."
/>
</div>Accessibility
- Each thumb is a native
<input type="range">. Arrow keys step. Page Up, Page Down and Shift+Arrow step bylargeStep. Home and End jump to the bounds. - A slider needs exactly one name, a visible
labeloraria-labeloraria-labelledby. TypeScript rejects none and both. - A range thumb takes the slider name plus "start" or "end", so a screen reader hears "Price start".
thumbLabelsreplaces the suffixes. - Each thumb announces
formatValueas itsaria-valuetext. The bubble and the value text are hidden from screen readers, so nothing is read twice. description,messageanddisabledMessageare linked to every thumb witharia-describedby, after any ids you pass.status="error"cannot setaria-invalidon the thumb. The error message reaches screen readers througharia-describedby.- In macOS Safari without Full Keyboard Access, Tab skips the slider, as it skips every native range input.
API
Slider
V is the value type, number or SliderRange. name submits each thumb's value through a hidden input. The rest of the native div props go to the root.
Prop
Type