Stable in React
Slider
An easily stylable range input.
Install#
One package per framework. Slider's parts come from it; the anatomy tab at the top shows how they nest.
bun add @▢▢▢▢/react7 parts. The example uses 7 of them; the data does not say which are required.
Slider.RootGroups all parts of the slider.Slider.LabelAn accessible label that is automatically associated with the slider thumbs.Slider.ValueDisplays the current value of the slider as text.Slider.ControlThe clickable, interactive part of the slider.Slider.TrackContains the slider indicator and represents the entire range of the slider.Slider.IndicatorVisualizes the current value of the slider.Slider.ThumbThe draggable part of the slider at the tip of the indicator.
Examples#
Common ways to put it to work. Each one runs live.
Two thumbs set a range; thumbCollisionBehavior decides what happens when they meet.
SliderRangeSlider.tsxStyling and accessibility#
The parts ship no styles. Style their states with these attributes; the CSS tab at the top has a sheet. The same CSS works in all five frameworks.
[data-dragging]Present while the user is dragging. On Root, Value, Control, Track, Indicator, Thumb.[data-orientation]Indicates the orientation of the slider. On Root, Value, Control, Track, Indicator, Thumb.[data-disabled]Present when the slider is disabled. On Root, Value, Control, Track, Indicator, Thumb.[data-valid]Present when the slider is in a valid state (when wrapped in Field.Root). On Root, Value, Control, Track, Indicator, Thumb.[data-invalid]Present when the slider is in an invalid state (when wrapped in Field.Root). On Root, Value, Control, Track, Indicator, Thumb.[data-touched]Present when the slider has been touched (when wrapped in Field.Root). On Root, Value, Control, Track, Indicator, Thumb.[data-dirty]Present when the slider's value has changed (when wrapped in Field.Root). On Root, Value, Control, Track, Indicator, Thumb.[data-focused]Present when the slider is focused (when wrapped in Field.Root). On Root, Value, Control, Track, Indicator, Thumb.[data-index]Indicates the index of the thumb in range sliders. On Thumb.
Keyboard
- ArrowRightArrowUpIncreases the value by
step(ArrowLeftin right-to-left) On Thumb. - ArrowLeftArrowDownDecreases the value by
step(ArrowRightin right-to-left) On Thumb. - ShiftArrowUpShiftArrowRightIncreases the value by
largeStep, stopping atmaxOn Thumb. - ShiftArrowDownShiftArrowLeftDecreases the value by
largeStep, stopping atminOn Thumb. - PageUpIncreases the value by
largeStepOn Thumb. - PageDownDecreases the value by
largeStepOn Thumb. - HomeSets the value to
minOn Thumb. - EndSets the value to
maxOn Thumb.
Set for you
a nestedeach thumb is read as a slider with its valueThumb<input type="range">witharia-valuenow,aria-orientationthe value is read as written, such as "40 °C"Thumbaria-valuetextfromgetAriaValueTextorformateach thumb has a name, also in a range sliderThumbaria-labelledbyto Label, or the name fromgetAriaLabelthe thumbs are read as one controlRootrole="group",aria-labelledbyto Labelrenders anthe value text is tied to the slider without being announced on every changeValue<output>
API reference#
28 props across 7 parts, in React syntax, and className, style, render once for every part. Open a row to try it.
Slider · all partsclassNameCSS class applied to the element, or a function that
returns a class based on the component's state.string | ((state: State) => string | undefined)styleStyle applied to the element, or a function that
returns a style object based on the component's state.React.CSSProperties | ((state: State) => React.CSSProperties | undefined)renderAllows you to replace the component's HTML element
with a different tag, or compose it with another component.React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, State>Use it in React#
What differs from the React API. Switch the framework at the top of the page.
@▢▢▢▢/react is the React 19 package. Its parts, props, data attributes and error messages are upstream Base UI's, and upstream's own tests run against it.
- Parts
Each component is its own entry point and exports one namespace named after it.
import { Switch } from '@base-ui-next/react/switch' export function Example() { return ( <Switch.Root> <Switch.Thumb /> </Switch.Root> ) }A part renders the element its API reference names, such as a
<span>forSwitch.Root. - Props and events
Props and callbacks have upstream's names and signatures:
onCheckedChange(checked, details),onOpenChange(open, details),onValueChange(value, details).detailscarriesreason,event,cancel()andallowPropagation(). Native handlers are React's (onClick,onKeyDown), andevent.preventBaseUIHandler()stops a part's own handler. - Styling
classNametakes a string or a function(state) => string;styletakes an object or a function(state) => object. The state'sdata-*attributes are on the element for CSS. renderrendertakes an element (render={<a href="/docs" />}) or a function(props, state) => elementthat spreadspropson what it returns.- Refs
refreaches the part's element. Imperative handles are ref props, as upstream:inputRef, andactionsRef({ validate }on Field and Form,{ unmount, close }on Dialog). - Binding
A part is controlled when its value prop (
checked,open,value) is set, and uncontrolled with thedefaultform (defaultChecked,defaultOpen,defaultValue). React has no two-way binding: pair the value with its change callback. - From @base-ui/reactChange the import from
@base-ui/react/<component>to@▢▢▢▢/react/<component>. - From @base-ui/reactNothing else changes: props, parts, data attributes and errors are the same.