Slider
Pick a number or a range from a continuous track — horizontal or vertical, any number of thumbs, each with a 24px hit area.
- Status
- Since
0.1.0- Accessibility pattern
- APG slider
Last updated
Install
Configure registry credentials first using the Quickstart. Before copying this item or any transitive registry dependency, verify the signed manifest and save the exact bytes for Slider before installation. Retain the digest printed by this command.
pnpm exec vegastack-design verify sliderInstall with the pinned shadcn CLI. Bare shadcn does not verify VegaStack signature or integrity.
pnpm dlx shadcn@4.21.0 add @vegastack/sliderRun the exact offline --post-write command printed by the preflight, using its saved item path and independently retained --expected-integrity digest. Use the saved preflight for every transitive registry dependency too; stop on any mismatch before using the components.
Usage
import { Slider } from "@/components/ui/slider";
<Slider defaultValue={[33]} max={100} step={1} />;Anatomy
Examples
Range
Pass an array with two values for a range slider.
Multiple Thumbs
Pass an array with any number of values — the component renders one thumb per entry.
Vertical
Use orientation="vertical" and give the slider a height.
Controlled
Hold the value yourself with value and onValueChange.
Disabled
Use the disabled prop. The control keeps its pointer events (FRM-4), so a Tooltip can explain why
it is unavailable.
RTL
The track and the indicator are written with logical properties, so a right-to-left document fills from the other end.
Playground
Every Slider prop, auto-generated from the component's own types.
API Reference
Slider adds no props of its own — it accepts everything the underlying element or Base UI primitive accepts (className, ref, ARIA attributes, event handlers).
Accessibility
- Renders Base UI's Slider, which gives every thumb
role="slider"witharia-valuenow,aria-valueminandaria-valuemax; ←/→, Home, End and PageUp/PageDown all move it. - The thumb is 12px, so an
::afterpseudo-element extends its pointer target to 28×28 (A11Y-2), verified by a realelementFromPointprobe. - On
:focus-visiblethe global 2px outline inbase.cssapplies (FOC-1) — upstream'shover:ring-3 focus-visible:ring-3 active:ring-3glow is gone (FOC-6). - A slider has no visible text of its own — give it an
aria-label. That label reaches the hidden<input type="range">that actually holds the role, which is what a screen reader announces. ALabel htmlForpointed at the Slider'siddoes not name it: theidlands on the root<div>, and the input keeps a generated one.
| Contract | States tested |
|---|---|
| Behaviour | default, range, vertical, disabled, dragging |
| Accessibility | native-or-base-ui-semantics, browser-accessibility-test, keyboard-navigation, disabled |
| Visual | default, hover, focus, disabled |
Do / Don't
Deviations
Upstream's file plus packages/ui/upstream/patches/slider.patch. Every hunk:
- FOC-1, FOC-6 — the thumb's
ring-ring/50colour and its three glow triggers (hover:ring-3,focus-visible:ring-3,active:ring-3) are removed, along withfocus-visible:outline-hidden, which would have suppressed the global outline. - FRM-4 —
disabled:pointer-events-noneis dropped, so a disabled slider stays hoverable and a Tooltip can explain it. - A11Y-16 — the root's
aria-labelis forwarded to every thumb throughgetAriaLabel. Base UI keeps the real control in a visually hidden<input type="range">inside the thumb, and a label on the root lands on a<div>with no role, so upstream's file ships a namelessrole="slider"in every composition. A range slider gives both thumbs the group's name: upstream has no per-thumb label API. - DOC-2 —
cnis imported from@vegastack/design.