Slider
Single thumb
The thumbs stay inside the slider at both ends of the track, and the track keeps a readable length. When the row cannot hold both the track and the value, the value moves under the track.
Range (two thumbs)
Sizes
Formatted values
Use formatValue for units or readable timestamps. It formats the visible value
and each thumb's spoken value, including when showValue is false. Range values
are formatted individually.
<Slider
aria-label="Pressure band"
defaultValue={[12, 47]}
formatValue={(value) => `${value} kPa`}
showValue
/>
Disabled
Inside a Field
Inside a Field the slider and its thumbs are named by the Field's label; a range's thumbs add "(lower)" and "(upper)". A Field error marks the slider invalid and draws its thumbs in the error color; the track is not reddened, so the scale does not read as a danger zone.
Inclusive bounds.
Vertical
A vertical slider takes the height its container gives it, and at least 128px.
Props
Pass a number for one thumb or a tuple for a range. Values clamp to bounds; ranges
order lower to upper. Non-finite values use min. Invalid min, max, or step
falls back to 0, min + 100, or 1, respectively. The display follows controlled
and uncontrolled changes.
| PROP | TYPE | DEFAULT | REQUIRED |
|---|---|---|---|
valueSingle thumb when number; pass [number, number] tuple for range mode. | number | array | — | no |
defaultValuePass [number, number] tuple for range mode. | number | array | — | no |
onValueChange(value: number | [number, number]) => void. Called as the value changes; a tuple in range mode. | function | — | no |
minFinite lower bound. Non-finite values fall back to 0. | number | 0 | no |
maxFinite upper bound greater than min. Invalid values fall back to min + 100. | number | 100 | no |
stepFinite positive increment. Invalid values fall back to 1. | number | 1 | no |
disabled | boolean | false | no |
orientation | enumhorizontal | vertical | "horizontal" | no |
size | enumsm | md | lg | "md" | no |
showValueRender the current value(s) in mono next to the track; the readout moves under the track when the row cannot hold both. | boolean | false | no |
formatValue(value: number) => string. Formats displayed values and each thumb's aria-valuetext. Applies separately to both values in range mode, including when showValue is false. | function | — | no |
name | string | — | no |
Accessibility
- Each thumb has a
sliderrole; range names include “(lower)” / “(upper)”, from anaria-label, anaria-labelledbyor a Field's label, and never the values. - Arrows change by
step; Home/End selects min/max; PageUp/PageDown uses larger increments. - Inherits
id,aria-describedby, and the invalid state from Field; its ownaria-labelledby,aria-describedby, andaria-invalidwin. Other attributes (data-*,style,title) reach the slider's root. - Each thumb has a 24px target.
formatValuesupplies each thumb'saria-valuetext; numeric values remain the default.- The unfilled track is drawn in the control outline color (3:1 or more), so the ends of the scale show.
- In forced-colors (high contrast) mode the track keeps a visible edge, the filled range is drawn in the system highlight color, and keyboard focus draws a 2px outline in the system text color around the thumb.
Manifest entry
<Slider aria-label="Acceptable temperature" defaultValue={[18, 24]} min={-20} max={50} showValue />View agent manifest
{
"description": "Single-thumb or range slider. Pass value: number for single, [number, number] for range. Track in the control outline color; active range in accent; square thumbs that stay inside the slider at both ends. Inside a Field it is named by the label (range thumbs add lower and upper) and a Field error marks it invalid, drawing its thumbs in the error color.",
"props": {
"value": {
"type": "union",
"types": [
"number",
"array"
],
"description": "Single thumb when number; pass [number, number] tuple for range mode."
},
"defaultValue": {
"type": "union",
"types": [
"number",
"array"
],
"description": "Pass [number, number] tuple for range mode."
},
"onValueChange": {
"type": "function",
"description": "(value: number | [number, number]) => void. Called as the value changes; a tuple in range mode."
},
"min": {
"type": "number",
"default": 0,
"description": "Finite lower bound. Non-finite values fall back to 0."
},
"max": {
"type": "number",
"default": 100,
"description": "Finite upper bound greater than min. Invalid values fall back to min + 100."
},
"step": {
"type": "number",
"default": 1,
"description": "Finite positive increment. Invalid values fall back to 1."
},
"disabled": {
"type": "boolean",
"default": false
},
"orientation": {
"type": "enum",
"values": [
"horizontal",
"vertical"
],
"default": "horizontal"
},
"size": {
"type": "enum",
"values": [
"sm",
"md",
"lg"
],
"default": "md"
},
"showValue": {
"type": "boolean",
"default": false,
"description": "Render the current value(s) in mono next to the track; the readout moves under the track when the row cannot hold both."
},
"formatValue": {
"type": "function",
"description": "(value: number) => string. Formats displayed values and each thumb's aria-valuetext. Applies separately to both values in range mode, including when showValue is false."
},
"name": {
"type": "string"
}
},
"composable_with": [
"Field"
],
"never_inside": [
"Button",
"Badge"
],
"example": "<Slider aria-label=\"Acceptable temperature\" defaultValue={[18, 24]} min={-20} max={50} showValue />"
}