Skip to content

Slider

Picks a number or a range by dragging a thumb along a track.

Library
What’s this?

Installation

pnpm dlx shadcn@latest add @wisty/slider

The CLI installs the Radix or Base UI file to match your project.

If your project doesn't have Wisty UI's theme yet, add it once with npx shadcn@latest add @wisty/cosmos. Until then, components keep shadcn's default look. Installation has the details.

When to use

Use it

  • To pick a number from a range where the feel matters more than the exact value, like a discount, a volume or a probability.
  • To pick a range with two thumbs, like a price filter, as the Range example shows.
  • When the range is small enough to move through with the arrow keys.

Don't use it

  • When people need an exact number, or the range is very large. Use Input with type="number", or put one next to the slider.
  • When the choice is one of a few named options. Use Radio Group or Toggle Group.
  • To show progress, not to choose. Use Progress.

Usage

Pass the value as an array, one number per thumb, and name the slider with aria-labelledby pointing at a visible label.

import { useId } from "react"

import { Label } from "@/components/ui/label"
import { Slider } from "@/components/ui/slider"

export function Probability() {
  const id = useId()

  return (
    <div className="grid gap-1">
      <Label id={`${id}-label`}>Probability</Label>
      <Slider aria-labelledby={`${id}-label`} defaultValue={[60]} />
    </div>
  )
}

When you control it, let onValueChange take a number as well as an array: setValue(Array.isArray(next) ? next : [next]). In Base UI projects, moving a single thumb by pointer passes a bare number, though the types say array, and kept as a number the slider draws a second thumb. For expensive work, act when the drag ends instead: onValueCommit in Radix projects, onValueCommitted in Base UI projects.

Examples

Range

Two thumbs pick a range, one for each number in `defaultValue`.

Disabled

A slider set with `disabled`: it can't take focus or move.

Vertical

A slider that runs bottom to top, set with `orientation="vertical"`.

API reference

Slider

PropTypeDefault
minnumber0
maxnumber100

Also takes every Radix Slider.Root (opens in a new tab) prop.

SLDS mapping

SLDS styles a native range input, slds-slider__range in slds-slider. The track, the fill and each thumb match that input's track and thumb, and orientation="vertical" is slds-slider_vertical. The value text after the slider is slds-slider__value, which the slider doesn't render; add it yourself, as the Discount example does.

Known gaps:

  • SLDS's track has no fill. Here the range fills in the thumb's color.
  • SLDS's slider is one native input, so it has no range slider.
  • SLDS's range text in the label ("0 - 100", slds-slider-label__range) isn't part of Slider. Add it to the label if you want it.

Keyboard interactions

Keys Action
Right or Up arrow Increases the value by one step.
Left or Down arrow Decreases the value by one step.
Shift + arrow, Page Up or Page Down Changes the value by ten steps.
Home, End Moves to the minimum or the maximum.

Accessibility

  • Each thumb takes its name from the root's aria-labelledby. An aria-label on the root reaches no thumb, so use a visible label.
  • Each thumb announces its value, so make the value text next to the slider aria-hidden.
  • A disabled slider can't take focus. Say why in nearby text if it matters.

Responsive behavior

  • A horizontal slider fills its container's width. A vertical one fills its container's height, so give that container a height, as the Vertical example does.

Rules

  • Don't restyle the track, thumb or fill colors. They come from the theme.