Slider
An input where the user selects a value from within a given range.
Installation
Install the following dependencies:
Set up the token layer and the StyleX compiler, if you have not already. See
Installation, and paste states.ts and
state-styles.ts from the same page. The slider imports both. The examples
caption the slider with Field.
Paste field-state.ts from the same installation page.
Copy and paste the following code into your project.
Update the import paths to match your project setup.
Usage
Slider renders the control, the track, the filled range and the thumbs
itself. It fills its container, so set the width on the slider or its parent.
value and defaultValue take a number for one thumb or an array for one
thumb per entry.
Inside Field, use FieldLabel for automatic association. For a bare slider, pass aria-labelledby. Base UI copies it to the
<input> inside every thumb, and a screen reader announces that input. A
label's htmlFor cannot reach an input the slider renders itself.
Range
Use an array with two values for a range slider.
Multiple thumbs
Use an array with more than two values for a thumb per value. Thumbs push each
other when they meet; set thumbCollisionBehavior to "swap" or "none" to
change that.
Vertical
Use orientation="vertical" for a vertical slider. It takes the height of its
parent, with a minimum of 10rem when the parent has no height.
Controlled
Pass value and onValueChange to control the slider. onValueCommitted
fires once when a drag or a key press ends. Use it for work that costs more
than a state update.
Disabled
Set disabled on Field to disable its control and dim its label, or on a bare control directly.
Invalid
Set invalid on Field or aria-invalid on a bare slider.
API reference
Pass render to replace a part's element or compose it with another component.
Slider wraps the Base UI Slider.Root and accepts its props. See the
Base UI reference. It also
takes xstyle, style and className and applies them to the root.
Slider
| Prop | Type | Default |
|---|---|---|
value | number | readonly number[] | — |
defaultValue | number | readonly number[] | min |
onValueChange | (value, eventDetails) => void | — |
onValueCommitted | (value, eventDetails) => void | — |
min | number | 0 |
max | number | 100 |
step | number | 1 |
largeStep | number | 10 |
minStepsBetweenValues | number | 0 |
orientation | "horizontal" | "vertical" | "horizontal" |
disabled | boolean | false |
name | string | — |
thumbCollisionBehavior | "push" | "swap" | "none" | "push" |
thumbAlignment | "center" | "edge" | "edge-client-only" | "edge" |
format | Intl.NumberFormatOptions | — |
locale | Intl.LocalesArgument | — |
xstyle | StyleXStyles | — |
style | CSSProperties | — |
className | string | — |
The root is a <div role="group">. Each thumb wraps an <input type="range">,
so the arrow keys, Home, End, Page Up and Page Down move it, Shift with an
arrow moves by largeStep, and a name submits every value with a form.
format and locale format the aria-valuetext a screen reader reads out.
sliderStyles
The style maps behind the component. Spread them onto any element.
| Key | What it is |
|---|---|
root | The full-width root |
rootVertical | The full-height root |
control | The gesture surface: flex row, no touch scrolling |
controlVertical | The column, with its 10rem floor |
disabled | The dimmed, non-interactive state |
track | The groove: height, fill, inset shadow, clipping |
trackVertical | The groove turned on its side |
range | The primary fill |
thumb | The raised circle: edge, lit face, lift, hover ring |
thumbRing | The ring while focused from the keyboard or dragged |
disabled is the shared states.disabled from theme/states.ts. thumbRing
is the shared ring with no pseudo-class on it, with the thumb's lift kept under
the halo. A thumb needs a ring without a pseudo-class because focus goes to the
<input> nested inside it. The hover halo stays on thumb, since the thumb
itself receives the hover.
Data attributes
| Attribute | On | Effect |
|---|---|---|
data-slot="slider" | the root | Targets the slider from a parent |
data-slot="slider-control" | the control | Targets the gesture surface |
data-slot="slider-track", data-slot="slider-range" | the groove | Targets the track and its fill |
data-slot="slider-thumb" | a thumb | Targets the circle |
data-orientation, data-disabled, data-dragging | every part | Base UI writes them |
data-index | a thumb | Base UI writes the thumb's position in value |
data-focus-visible | a thumb | Set while the ring shows for keyboard focus |