Slider
Pick a value or a range by dragging along a track. Built on Radix Slider: thumbs auto-render from the value array, with an optional live bubble and full keyboard support. SliderInput pairs a rail with a number.
Installation#
Usage#
import { Slider } from "@/components/ui/slider"
export function Example() {
return <Slider defaultValue={[60]} aria-label="Volume" />
}Anatomy#
import {
Slider,
SliderInput,
SliderInputValue,
SliderInputTrack,
SliderInputLabel,
} from "@/components/ui/slider"
<Slider />
<SliderInput>
<SliderInputValue />
<SliderInputTrack>
<SliderInputLabel />
<SliderInputValue />
</SliderInputTrack>
</SliderInput>Sizes#
Three sizes scale the track thickness and thumb diameter together: sm, md (default), and lg.
Variants#
The variant tints the range, thumb border, and tooltip as one. default uses the form-control primary; brand picks up the active accent; and the status fills carry domain meaning.
Range#
Pass two values and you get a two-thumb range, no extra component. Each thumb drags independently and carries its own value bubble.
Steps#
step snaps the thumb to discrete stops. Pair it with min/max and your own labels for a scaled control.
Vertical#
Set orientation="vertical" and give the root a height. The same recipe styles both axes via data-orientation.
Square#
shape="square" squares the rail and gives the thumb a fader-cap profile; corners stay concentric with the rail.
Equalizer#
Square + vertical turns the slider into a fader. A row of them reads as an equalizer; each is an independent control.
Disabled#
disabled dims the whole control and stops all interaction.
Controlled#
Drive the slider from state with value and onValueChange (both arrays), or leave it uncontrolled with defaultValue.
In a settings card#
The common shell: a labelled row with the live value trailing, the slider beneath.
Slider input#
SliderInput is the inspector slider: an editable number box beside a slim rail with a pill thumb, the pair you find in video, design and audio tools. The rail opens to the full control height while hovered, dragged or focused. It edits one number (not an array), and the row shares the 32/36/40 height scale with Input, so a column of them lines up with the rest of a panel.
- Click or drag anywhere on the track; arrows, Shift+arrows, Home and End work once it has focus.
- Drag sideways on the number box to scrub it. A plain click edits it with the number selected.
- While typing, arrows step (Shift steps Ă—10), Enter commits and Escape reverts. Out-of-range input clamps and snaps to
stepon commit. - Inside a
Fieldthe label focuses the box and names the thumb, no wiring needed. - Drag past either end and the rail stretches a few pixels, then eases back on release (not with reduced motion).
Slider input sizes#
size sets the height, the same scale as every form control: sm 32px, md 36px and lg 40px. Unsized, it follows density the way Input does. Typed text stays 14px at every size.
Slider input variants#
default keeps the fill and pill neutral, because an inspector is a wall of these and colour on every row would shout. brand tints them with the accent for the one setting that matters.
Only the parts you need#
With no children the root renders both halves. Compose SliderInputValue and SliderInputTrack yourself to add a suffix unit, or drop either one: the track alone is a compact fader, the box alone a scrubbable number.
Label inside the track#
Give SliderInputTrack children and the track becomes the field, the slider you find in generation panels. SliderInputLabel sits inside on the left and SliderInputValue turns into a read-only readout on the right, while the fill paints as a raised chip that ends at the pill. Drag anywhere on it.
- The text insets match Input's side padding, so a column of these lines up with the inputs and selects around it.
- The pill fades while it passes under the label or the readout, and
ticksfade out around the text. - Name the stops of a discrete scale with
formatValueon the root: the readout shows the name and the thumb announces it. - Both parts are optional. A label alone or a readout alone is still a field.
Label inside: sizes and variants#
The field layout keeps the same size and variant. Inside a field the pill stays a quiet grey next to the text, and brand tints the chip and the pill.
Ticks#
ticks on the track marks the stops: true for one at every step, or a number for one every that many units. The ends get no mark, since the rail's edges already show them. Inside the fill, marks only show while the track is hovered, dragged or focused. Past 64 marks none are drawn.
Decimal steps#
The box shows as many decimals as step has, and everything you type or scrub snaps to that grid. Drive it with value and onValueChange (plain numbers); onValueCommit fires once when a drag, scrub or edit ends.
Slider input disabled#
disabled (or a disabled Field) dims both halves together and stops every interaction.
API reference#
Slider
A Radix Slider with its track, range and one thumb per value, all rendered for you. Forwards all Radix Root props except asChild (orientation, step, minStepsBetweenThumbs, onValueCommit, inverted, name, disabled); every part on this page accepts className, merged last.
| Prop | Type | Default | Description |
|---|---|---|---|
| value | number[] | - | The controlled values, one per thumb. Pair with onValueChange. |
| defaultValue | number[] | - | The initial values when uncontrolled. Two values make a range. |
| onValueChange | (value: number[]) => void | - | Fires on every change while dragging or stepping. |
| min | number | 0 | The lowest value. |
| max | number | 100 | The highest value. |
| size | "sm" | "md" | "lg" | "md" | Track thickness and thumb size (a 16, 20 or 24px thumb). |
| variant | "default" | "brand" | "success" | "warning" | "destructive" | "default" | Tints the range, the thumb border and the tooltip together. The focus ring stays brand. |
| shape | "round" | "square" | "round" | square squares the rail and gives the thumb a fader-cap look. |
| tooltip | boolean | false | Shows a value bubble above each thumb on hover, focus and drag. |
| formatValue | (value: number) => React.ReactNode | - | Formats the tooltip value. Defaults to the raw number. |
| static | boolean | false | Kept for compatibility; controls no longer scale on press. |
| Data attribute | Description |
|---|---|
| data-orientation | horizontal or vertical, on the root, track, range and thumbs. A vertical slider needs a height (h-48 by default). |
| data-disabled | Present on the root, track, range and thumbs when disabled. |
SliderInput
The inspector slider root: holds one number and shares it with its parts. With no children it renders SliderInputValue then SliderInputTrack. Renders a <div role="group"> and forwards its native props except defaultValue and onChange.
| Prop | Type | Default | Description |
|---|---|---|---|
| value | number | - | The controlled value. |
| defaultValue | number | - | The initial value when uncontrolled. Defaults to min. |
| onValueChange | (value: number) => void | - | Fires on every change: each drag frame, parsed keystroke and scrub step. |
| onValueCommit | (value: number) => void | - | Fires once an interaction ends: drag release, blur, or Enter in the box. |
| min | number | 0 | The lowest value. |
| max | number | 100 | The highest value. |
| step | number | 1 | Snap increment for the track, the arrow keys and the scrub; also sets the displayed precision. |
| disabled | boolean | - | Disables both halves. Inherits a surrounding Field's disabled state. |
| size | "sm" | "md" | "lg" | - | Row height, shared with Input (32, 36 or 40px). Unsized, it follows density: sm under compact, md under comfortable. |
| variant | "default" | "brand" | "default" | brand tints the fill and the pill with the accent. |
| name | string | - | Form field name, submitted through Radix's hidden input on the track. |
| formatValue | (value: number) => string | - | Text for a value: shown by the value part and announced by the thumb. Name discrete stops here. |
| id | string | - | Goes to the number box so a <label htmlFor> focuses it. Inside a Field the generated id is used. |
| Data attribute | Description |
|---|---|
| data-disabled | Present when disabled. |
SliderInputValue
Beside the track, an editable, scrubbable number box; inside a track, a read-only readout. Forwards native <input> props except value, defaultValue, onChange, type and size; className goes on the input.
| Prop | Type | Default | Description |
|---|---|---|---|
| suffix | React.ReactNode | - | A muted unit painted after the number (%, px). Never part of the typed value. |
| formatValue | (value: number) => string | - | Formats the number while not editing. Defaults to the root's formatValue, then the step's precision. |
| boxClassName | string | - | Classes for the box around the input. |
SliderInputTrack
The rail and pill thumb, a Radix Slider Root. Value, bounds, step, disabled and name come from SliderInput; it forwards the remaining Radix Root props. Given children, it becomes the field (label inside, readout on the right).
| Prop | Type | Default | Description |
|---|---|---|---|
| ticks | boolean | number | - | Marks along the rail: true for one at every step, a number for one every that many units. Past 64 marks none are drawn. |
| Data attribute | Description |
|---|---|
| data-dragging | Present on the track while a pointer drags it. |
| data-orientation | Always horizontal. |
| data-disabled | Present when disabled. |
| data-covered | Present on the thumb while the pill passes under the label or the readout (it fades). |
| data-filled | Present on each tick at or below the value. |
| CSS variable | Description |
|---|---|
| --slider-input-fraction | The value's position from 0 to 1; drives the fill width. |
| --slider-input-thumb | Width of the thumb's box, set per size; the fill and ticks end under the pill's centre. |
| --slider-input-pull-l | The rubber-band stretch past the left end while dragging, in px. |
| --slider-input-pull-r | The rubber-band stretch past the right end while dragging, in px. |
| --slider-input-label-end | In the field layout, the label's right edge in px; ticks fade around it. |
| --slider-input-value-start | In the field layout, the readout's left edge in px; ticks fade around it. |
SliderInputLabel
The setting's name, painted inside the track on the left; it names the thumb for assistive tech unless the root has an aria-label. Only valid inside SliderInputTrack. Forwards all native <span> props.