Preview
Design guidance
Each thumb has an accessible name and supports Arrow, Home, End, Page Up, and Page Down. Set name for form submission. Use disabled for unavailable controls and aria-invalid="true" with an owning Field when the current value needs correction. A range keeps its handles ordered through Base UI collision behavior.
This component wraps Base UI slider for its behavior.
Installation
Basic usage
Use the exported component in the composition shown above. Keep labels, data, and callbacks in the consuming application.
Structures
Examples
Tall marked single
The 40px rail shows a solid selected range, a focused/hoverable handle, and 0/50/100 ruler values.
Tall marked range
Two handles control a bounded range and cannot cross.
Brightness pads
Use canonical icon buttons for coarse decrement and increment actions beside the slider. The pads disable at 0% and 100%.
Ruler
Use Slider.Ruler, Slider.Mark, and Slider.RulerValue when a scale needs visible ticks and values.
Boundaries and form values
Exercise the component with saved values and its meaningful boundary states.
API reference
| Prop | Type | Default | Description |
|---|---|---|---|
defaultValue | Value | undefined | The uncontrolled value of the slider when it's initially rendered. To render a controlled slider, use the `value` prop instead. | |
disabled | boolean | undefined | Whether the slider should ignore user interaction. | |
format | Intl.NumberFormatOptions | undefined | Options to format the value. | |
locale | Intl.LocalesArgument | The locale used by `Intl.NumberFormat` when formatting the value. Defaults to the user's runtime locale. | |
max | number | undefined | The maximum allowed value of the slider. Should not be equal to min. | |
min | number | undefined | The minimum allowed value of the slider. Should not be equal to max. | |
minStepsBetweenValues | number | undefined | The minimum steps between values in a range slider. | |
name | string | undefined | Identifies the field when a form is submitted. | |
form | string | undefined | Identifies the form that owns the slider inputs. Useful when the slider is rendered outside the form. | |
orientation | BaseUI.Orientation | undefined | The component orientation. | |
step | number | undefined | The granularity with which the slider can step through values. (A "discrete" slider.) The `min` prop serves as the origin for the valid values. We recommend (max - min) to be evenly divisible by the step. | |
largeStep | number | undefined | The granularity with which the slider can step through values when using Page Up/Page Down or Shift + Arrow Up/Arrow Down. | |
thumbAlignment | "center" | "edge" | "edge-client-only" | undefined | How the thumb(s) are aligned relative to `Slider.Control` when the value is at `min` or `max`: - `center`: The center of the thumb is aligned with the control edge - `edge`: The thumb is inset within the control such that its edge is aligned with the control edge - `edge-client-only`: Same as `edge` but renders after React hydration on the client, reducing bundle size in return | |
thumbCollisionBehavior | "push" | "none" | "swap" | undefined | Controls how thumbs behave when they collide during pointer interactions. - `'push'` (default): Thumbs push each other without restoring their previous positions when dragged back. - `'swap'`: Thumbs swap places when dragged past each other. - `'none'`: Thumbs cannot move past each other; excess movement is ignored. | |
value | Value | undefined | The value of the slider. For range sliders, provide an array with one value per thumb. | |
onValueChange | ((value: Value extends number ? number : Value, eventDetails: BaseSlider.Root.ChangeEventDetails) => void) | undefined | Callback function that is fired when the slider's value changed. Receives the new value as the first argument; the originating event is available as `eventDetails.event`. The value is also reflected on `eventDetails.event.target.value` for form integration. The `eventDetails.reason` indicates what triggered the change: - `'input-change'` when the hidden range input emits a change event (for example, via form integration) - `'track-press'` when the control track is pressed - `'drag'` while dragging a thumb - `'keyboard'` for keyboard input - `'none'` when the change is triggered without a specific interaction | |
onValueCommitted | ((value: Value extends number ? number : Value, eventDetails: BaseSlider.Root.CommitEventDetails) => void) | undefined | Callback function that is fired when a value change is committed. Does not fire if the value did not change, or if the change was canceled. **Warning**: This is a generic event, not a change event. The `eventDetails.reason` indicates what triggered the commit: - `'drag'` while dragging a thumb - `'track-press'` when the control track is pressed - `'keyboard'` for keyboard input - `'input-change'` when the hidden range input emits a change event (for example, via form integration) - `'none'` when the commit occurs without a specific interaction | |
ref | React.Ref<HTMLDivElement> | undefined | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). | |
className | string | ((state: BaseUI.SliderRootState) => string | undefined) | undefined | CSS class applied to the element, or a function that returns a class based on the component's state. | |
render | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | BaseUI.ComponentRenderFn<BaseUI.HTMLProps, BaseUI.SliderRootState> | undefined | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. | |
style | React.CSSProperties | ((state: BaseUI.SliderRootState) => React.CSSProperties | undefined) | undefined | Style applied to the element, or a function that returns a style object based on the component's state. |