videorc/ui

Slider

A slider on Base UI with a chrome-fill range and chrome-bead thumbs. Its name and spoken value go on the thumbs, where a screen reader reads them.

Installation

$ pnpm dlx shadcn@latest add @videorc/slider

Usage

import { Slider } from "@/components/ui/slider";
<Slider aria-label="Microphone gain" defaultValue={60} />

One thumb takes a number; a range takes an array, and onValueChange hands back the same shape.

Examples

Value readout

Show the value beside the label, and pass the same words as aria-valuetext so a screen reader says "+6.0 dB", not "6".

Raise it until your voice peaks just under the red.

Range

Pass two values for two thumbs. minStepsBetweenValues keeps them apart, and format turns each thumb's spoken value into a unit.

Theming

Token or attributeMeaning
chrome-fillThe range
bg-foreground/15The 4 px track
chrome-beadEvery thumb
ring-knob-ringThe thumb's hairline rim; a 4 px ring on hover and focus
data-orientationhorizontal or vertical
data-disabledDims to 50%
data-slotslider, slider-track, slider-range, slider-thumb

Keyboard

KeyAction
← → ↑ ↓Moves the focused thumb one step
Shift with an arrowMoves it one largeStep
Page Up Page DownMoves it one largeStep
Home EndMoves it to the minimum or maximum
TabMoves to the next thumb, then the next control

Accessibility

Each thumb holds a native range input with role="slider", and that is what a screen reader reads. So aria-label, aria-labelledby, aria-describedby and aria-valuetext go to every thumb, never the root. Inside a Field, a slider that names nothing takes the FieldLabel through aria-labelledby (a label element can't point at a thumb) and the Field's descriptions. Outside a Field, always name it.

API reference

Every Base UI Slider root prop, plus:

Prop

Type