Slider
A labelled range input that shows its value as text, with optional labelled marks.
4px
SliderExample.tsx
import { Slider } from "@/components/Slider";
export function SliderExample() {
return (
<Slider
label="Corner radius"
min={0}
max={24}
defaultValue={4}
formatValue={(value) => `${String(value)}px`}
/>
);
}Examples
Marks
4px
Hint
100%
How much larger headings are than body text.
Controlled
1px
Stored value: 1
Hidden label
100
Disabled
8px
Props
Native range props (value, defaultValue, min, max, step, onChange, name, disabled, ref and the rest) go to the <input>; value and defaultValue are numbers, and min, max and step default to 0, 100 and 1. className and style go to the wrapper.
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | The visible label and the slider's accessible name. Required by the type. |
hideLabel | boolean | false | Hides the label visually; it still names the slider. The value text stays visible. Only where something else on screen says what it sets. |
hint | ReactNode | — | Help text under the label, read as the slider's description. |
formatValue | (value: number) => string | String | Turns the value into the text shown beside the label and announced as the value. |
marks | readonly { value: number; label: string }[] | — | Labelled stops under the track. On a mark, the announced value leads with its label: "Default, 4px". |
onValueChange | (value: number) => void | — | Called with the new value as a number, alongside the native onChange. |
Component tokens
| Token | Copy | Description | Aliases | Light | Dark | Preview |
|---|---|---|---|---|---|---|
--component-slider-track | The unfilled track: the control's boundary. | color.border.strong | #6d7e90from color.gray.500 | #818b9efrom color.slate.400 | ||
--component-slider-track-height | Track thickness. | space.stack.xs | 0.25remfrom space.1 | 0.25remfrom space.1 | ||
--component-slider-fill | The track from the minimum to the thumb. | color.action.background | #b37500from color.gold.600 | #f5e3c2from color.champagne.100 | ||
--component-slider-thumb | The thumb: what the visitor drags. | color.action.background | #b37500from color.gold.600 | #f5e3c2from color.champagne.100 | ||
--component-slider-thumb-border | A ring around the thumb that separates it from the fill. | color.surface.raised | #fffffffrom color.gray.0 | #18202efrom color.slate.900 | ||
--component-slider-thumb-size | Thumb diameter and the control's height: at least 24px (WCAG 2.5.8). | size.icon.lg | 1.5remfrom size.6 | 1.5remfrom size.6 | ||
--component-slider-radius | Rounds the track and the thumb. | radius.pill | 9999pxfrom radius.full | 9999pxfrom radius.full | ||
--component-slider-gap | Space between the label row, hint, track and marks. | space.stack.xs | 0.25remfrom space.1 | 0.25remfrom space.1 | ||
--component-slider-value-text | The current value beside the label. | color.text.muted | #455464from color.gray.700 | #e6ecf3from color.slate.100 | ||
--component-slider-mark-text | Mark labels under the track. | color.text.subtle | #5d6876from color.gray.600 | #d3dce6from color.slate.200 |
Accessibility
- A native <input type="range"> with a visible <label> tied to it, so it's announced as a slider with its name, and every browser's own keyboard support works. A label is required by the type.
- The value is shown as text beside the label, so it isn't conveyed by the thumb's position alone. The same text is the slider's aria-valuetext, so it's announced with its unit. The text isn't an <output>, whose status role would announce every step a second time.
- Marks are a visual aid, hidden from screen readers; on a mark, the announced value leads with the mark's label instead.
- The thumb is 24px across (WCAG 2.5.8) and takes the focus ring. It's checked to 3:1 against the surfaces, as is the track, in both themes. In forced colors the track and thumb take system colors.
- Disabled sliders use native disabled: they can't be focused or changed.
| Key | Action |
|---|---|
| Arrow Right / Arrow Up | Increases the value by one step. |
| Arrow Left / Arrow Down | Decreases the value by one step. |
| Page Up / Page Down | Changes the value by a larger step, as the browser sets it. |
| Home / End | Sets the minimum or the maximum. |