An input where the user selects a value from within a given range.
Can be controlled or uncontrolled.
Supports multiple thumbs.
Supports a minimum value between thumbs.
Supports touch or click on track to update value.
Supports Right to Left direction.
Full keyboard navigation.
Install the component from your command line.
npm install @radix-ui/react-slider
Import all parts and piece them together.
import * as Slider from '@radix-ui/react-slider';
export default () => (
<Slider.Root>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb />
</Slider.Root>
);
Contains all the parts of a slider. It will render an input
for each thumb when used within a form
to ensure events propagate correctly.
The track that contains the Slider.Range
.
The range part. Must live inside Slider.Track
.
A draggable thumb. You can render multiple thumbs.
Use the orientation
prop to create a vertical slider.
// index.jsx
import * as Slider from '@radix-ui/react-slider';
import './styles.css';
export default () => (
<Slider.Root
className="SliderRoot"
defaultValue={[50]}
orientation="vertical"
>
<Slider.Track className="SliderTrack">
<Slider.Range className="SliderRange" />
</Slider.Track>
<Slider.Thumb className="SliderThumb" />
</Slider.Root>
);
/* styles.css */
.SliderRoot {
position: relative;
display: flex;
align-items: center;
}
.SliderRoot[data-orientation='vertical'] {
flex-direction: column;
width: 20px;
height: 100px;
}
.SliderTrack {
position: relative;
flex-grow: 1;
background-color: grey;
}
.SliderTrack[data-orientation='vertical'] {
width: 3px;
}
.SliderRange {
position: absolute;
background-color: black;
}
.SliderRange[data-orientation='vertical'] {
width: 100%;
}
.SliderThumb {
display: block;
width: 20px;
height: 20px;
background-color: black;
}
Add multiple thumbs and values to create a range slider.
import * as Slider from '@radix-ui/react-slider';
export default () => (
<Slider.Root defaultValue={[25, 75]}>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb />
<Slider.Thumb />
</Slider.Root>
);
Use the step
prop to increase the stepping interval.
import * as Slider from '@radix-ui/react-slider';
export default () => (
<Slider.Root defaultValue={[50]} step={10}>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb />
</Slider.Root>
);
Use minStepsBetweenThumbs
to avoid thumbs with equal values.
import * as Slider from '@radix-ui/react-slider';
export default () => (
<Slider.Root defaultValue={[25, 75]} step={10} minStepsBetweenThumbs={1}>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb />
<Slider.Thumb />
</Slider.Root>
);
Adheres to the Slider WAI-ARIA design pattern.
Create your own API by abstracting the primitive parts into your own component.
This example abstracts all of the Slider
parts so it can be used as a self closing element.
import { Slider } from './your-slider';
export default () => <Slider defaultValue={[25]} />;
// your-slider.jsx
import * as SliderPrimitive from '@radix-ui/react-slider';
export const Slider = React.forwardRef((props, forwardedRef) => {
const value = props.value || props.defaultValue;
return (
<SliderPrimitive.Slider {...props} ref={forwardedRef}>
<SliderPrimitive.Track>
<SliderPrimitive.Range />
</SliderPrimitive.Track>
{value.map((_, i) => (
<SliderThumb key={i} />
))}
</SliderPrimitive.Slider>
);
});
Because of a limitation we faced during implementation, the following example won't work as expected and the onMouseDown
and onMouseUp
event handlers won't be fired:
<Slider.Root
onMouseDown={() => console.log('onMouseDown')}
onMouseUp={() => console.log('onMouseUp')}
>
…
</Slider.Root>
We recommend using pointer events instead (eg. onPointerDown
, onPointerUp
). Regardless of the above limitation, these events are better suited for cross-platform/device handling as they are fired for all pointer input types (mouse, touch, pen, etc.).