Components

Slider

A React slider with a Liquid Glass track, single values, ranges, and vertical orientation.

Slider renders the control, track, indicator, and glass thumb internally. children is intentionally not supported; style merges into the outermost root.

Basic example

The slider below is the real component. Its label and value are rendered outside the slider; dragging, clicking the track, or using the arrow keys updates the value.

Volume40

Accessible name

Slider does not render a visible label. Point aria-labelledby at a visible label, or pass aria-label; both are forwarded from the root to every thumb, and aria-describedby is forwarded as well. For range sliders, use getAriaLabel to name each thumb.

aria-invalid and aria-errormessage are applied to the underlying input[type="range"], so validation state supplied by a form library reaches the focusable control. A plain aria-label is shared by every thumb in a range slider; pass getAriaLabel when each thumb needs a distinct name.

Range values

Passing an array renders one thumb per value. format follows Intl.NumberFormatOptions and is applied to the thumb's accessible value text.

Price range

Vertical

orientation="vertical" switches the track, indicator, and thumb to a vertical layout:

Level

Disabled

The disabled state uses the native disabled attribute, stopping both dragging and keyboard interaction:

Disabled slider

Form usage

Slider forwards name and submits the current value through a hidden input[type="range"]:

Volume

The current value is submitted through a hidden range input.

Not submitted yet

Constraints

min, max, and step define the scale. For range sliders, minStepsBetweenValues keeps the thumbs apart, while thumbAlignment and thumbCollisionBehavior control how they meet the edges and each other.

Budget

Step 10 with five steps between values keeps a minimum gap of 50.

Swap range

Thumbs align to the control edges and swap places when they meet.

Accessibility

Each thumb is a slider with aria-valuemin, aria-valuemax, aria-valuenow, and a name from aria-label, aria-labelledby, or getAriaLabel.

Arrow keys change the value by step, and Page Up and Page Down use largeStep. Home and End move a single-value slider to its bounds; on a range slider they move the focused thumb to the adjacent thumb boundary, while the outer thumbs still reach the bounds. Range sliders need a distinct name for every thumb. aria-invalid and aria-errormessage reach the underlying range input. See the accessibility guide for naming examples.

API reference

PropTypeDefaultDescription
valuenumber | readonly number[]—Controlled value; an array renders one thumb per value.
defaultValuenumber | readonly number[]—Uncontrolled initial value.
onValueChange(value, details) => void—Called when the value changes.
onValueCommitted(value, details) => void—Called when a value change is committed.
namestring—Field name used when submitting a form.
formstring—Identifies the form that owns the slider inputs.
minnumber0Minimum value.
maxnumber100Maximum value.
stepnumber1Step for dragging and arrow keys.
largeStepnumber10Step for Page Up / Page Down and Shift + arrow keys.
minStepsBetweenValuesnumber0Minimum steps between range thumb values.
orientation"horizontal" | "vertical""horizontal"Layout and keyboard orientation.
formatIntl.NumberFormatOptions—Value format used by the accessible value text.
localeIntl.LocalesArgument—Locale used for number formatting.
getAriaLabel(index: number) => string—Accessible name for the thumb at the given index. Use it for range sliders.
getAriaValueText(formattedValue, value, index) => string—Custom accessible value text for each thumb.
aria-labelstring—Accessible name shared by every thumb.
aria-labelledbystring—ID reference for an external accessible name.
aria-describedbystring—ID reference for supporting text announced with each thumb.
aria-invalidboolean | "grammar" | "spelling" | "true" | "false"—Marks the underlying range input as invalid.
aria-errormessagestring—ID of the error message associated with the underlying range input.
disabledbooleanfalseDisables the slider.
thumbAlignment"center" | "edge" | "edge-client-only""center"How thumbs align with the control edges.
thumbCollisionBehavior"push" | "swap" | "none""push"How range thumbs behave when they collide.
renderReactElement | ((props, state) => ReactElement)—Replaces the root element.
refRef<HTMLDivElement>—Ref forwarded to the root element.
classNamestring—Tailwind classes merged into the outermost root.
styleCSSProperties—Inline styles merged into the same element as className.
ui{ root?: ClassValue; control?: ClassValue; track?: ClassValue; indicator?: ClassValue; thumb?: ClassValue }—Tailwind classes for internal slots, keyed by data-slot.
AttributeDescription
data-draggingPresent while a thumb is being dragged.
data-orientationIndicates the orientation (horizontal or vertical).
data-disabledPresent when the slider is disabled.
data-indexIndicates the thumb index on range sliders.
data-validPresent when the slider is valid and wrapped in Field.
data-invalidPresent when the slider is invalid and wrapped in Field.
data-touchedPresent after the slider is touched while wrapped in Field.
data-dirtyPresent after the slider value changes while wrapped in Field.
data-slotMarks internal parts (root, control, track, indicator, thumb) for styling.
data-focusedPresent when the slider is focused while wrapped in Field.

Theming

The component uses the shared glass material. Tune shared --ui-glass-* tokens on a parent, use className for layout, and use ui for internal slots keyed by data-slot. Component-specific values live in src/theme/slider.ts. See the theming guide for token layers and presets.

  • Input — For an exact numeric value typed by the user.
  • Progress — For read-only task completion.
  • Switch — For an immediate binary setting.