Components

Slider

Lets users select a single value or a range from a continuous scale by dragging a thumb along a track. Supports any number of thumbs and both orientations.

Basic usage

Pass a single-element defaultValue array for an uncontrolled single-thumb slider. The thumb count comes from the value array — with neither value nor defaultValue you get two thumbs sitting at [min, max].

Range

Provide two values to render two thumbs that define a lower and upper bound — ideal for price or date ranges.

Steps & disabled

Use step to snap to coarser increments, and disabled to make the control read-only.

Vertical

Set orientation="vertical" for mixer-style controls. The root swaps to a column, stretches to the parent's height and keeps a min-h-44 floor, so give it a sized container.

Controlled

Hold the value in state and read it back next to the track. onValueChange fires on every movement, while onValueCommit fires only when a drag ends (and once per keyboard step) — use the second one for anything expensive such as a network request. minStepsBetweenThumbs stops the two handles from crossing.

Budget200700

Props

PropTypeDefaultDescription
defaultValuenumber[]Uncontrolled starting value — one number per thumb. With neither value nor defaultValue the slider renders two thumbs at [min, max].
valuenumber[]Controlled value. When set, you must update it via onValueChange.
onValueChange(value: number[]) => voidFires continuously as the thumb is dragged or moved with the keyboard.
onValueCommit(value: number[]) => voidFires at the end of an interaction — on pointer up after a drag, and on each keyboard step.
minnumber0Minimum allowed value.
maxnumber100Maximum allowed value.
stepnumber1Stepping interval the thumb snaps to.
minStepsBetweenThumbsnumber0Minimum number of steps two thumbs must keep between them in a range slider.
orientation'horizontal' | 'vertical''horizontal'Layout direction of the track. Vertical fills the parent height and floors at min-h-44.
invertedbooleanfalseFlips which end of the track the filled range grows from.
dir'ltr' | 'rtl'Reading direction for a horizontal track.
disabledbooleanfalsePrevents interaction and reduces opacity to 50%.
namestringName for the hidden inputs submitted with a native form.
formstringAssociates those hidden inputs with a form elsewhere in the document.
classNamestringAdditional Tailwind classes to merge onto the root.
...restRadix Slider.Root propsEverything else is forwarded to the Radix root.

Accessibility

  • Built on Radix UI Slider — each thumb is a focusable element with role="slider" and the correct aria-valuemin, aria-valuemax, and aria-valuenow.
  • Fully keyboard operable: Arrow keys move by one step, Page Up/Page Down by a larger amount, and Home/End jump to the bounds.
  • Each thumb shows a visible focus-visible ring using the brand gold ring token, plus a wider hover:ring-4 halo that makes the grab target obvious with a mouse.
  • aria-label and aria-labelledby passed to Slider land on the root span, which carries no ARIA role, so they are not announced. The role="slider" thumb is named by Radix instead — Minimum/Maximum for a two-thumb range, and nothing at all for a single thumb, because the package forwards no props down to the thumb. Put a visible Label beside the track so the purpose is at least in reading order, and do not rely on aria-label here.
  • The three parts use the same control tokens as Switch and Checkbox instead of the raw palette: track bg-slider-track, filled range bg-control-on, thumb bg-control-knob with a border-control-on outline. On the high-contrast palette that is 3.83–4.94:1 for the track and 6.51–12.67:1 for the range against the page — the earlier bg-muted track scored 1.07:1 and effectively disappeared in light mode.
  • Filled range against the empty track is only 1.70–2.57:1, and that is deliberate — thumb position is what carries the value, and both colours clear 3:1 against the page and against the thumb. No colour pair satisfies every constraint at once on a white page.