A fully customizable, accessible React multi-range slider component with keyboard support and mobile compatibility.
- ✅ Multiple Handles: Support for 2 or more handles
- ✅ Keyboard Navigation: Full keyboard support with arrow keys, home/end, page up/down
- ✅ Mobile Friendly: Touch events and responsive design
- ✅ Accessibility: ARIA labels, screen reader support, and keyboard navigation
- ✅ Fully Customizable: Colors, sizes, formatting, and behavior via props
- ✅ Marks Support: Visual indicators with custom labels
- ✅ Handle Constraints: Prevent crossing and set minimum distance between handles
- ✅ Event Callbacks:
onChange
andonChangeCommitted
events - ✅ TypeScript Ready: (types can be added easily)
npm i react-multi-slider-pro
# or
yarn add react-multi-slider-pro
import React, { useState } from 'react';
import { MultiSliderPro } from 'react-multi-slider-pro';
function App() {
const [values, setValues] = useState([20, 80]);
return (
<div>
<MultiSliderPro
values={values}
onChange={setValues}
min={0}
max={100}
showLabels
showValueLabels
/>
<p>Selected range: {values[0]} - {values[1]}</p>
</div>
);
}
Prop | Type | Default | Description |
---|---|---|---|
values |
number[] |
[20, 80] |
Array of handle values |
min |
number |
0 |
Minimum value |
max |
number |
100 |
Maximum value |
step |
number |
1 |
Step size for value changes |
disabled |
boolean |
false |
Disable the slider |
onChange |
(values: number[]) => void |
- | Called when values change |
onChangeCommitted |
(values: number[]) => void |
- | Called when user finishes changing values |
showLabels |
boolean |
false |
Show min/max labels and value chips |
showValueLabels |
boolean |
false |
Show value labels above handles |
formatLabel |
(value: number) => string |
- | Custom value formatting function |
trackColor |
string |
'bg-gray-300' |
Tailwind class for track color |
rangeColor |
string |
'bg-blue-500' |
Tailwind class for range color |
handleColor |
string |
'bg-blue-500' |
Tailwind class for handle color |
labelColor |
string |
'text-white' |
Tailwind class for label text color |
trackHeight |
string |
'h-1' |
Tailwind class for track height |
handleSize |
string |
'w-5 h-5' |
Tailwind class for handle size |
containerHeight |
string |
'h-10' |
Tailwind class for container height |
marks |
Mark[] |
[] |
Array of marks to display |
allowCross |
boolean |
false |
Allow handles to cross each other |
pushable |
number |
0 |
Minimum distance between handles |
className |
string |
'' |
Additional CSS classes |
style |
object |
{} |
Inline styles |
aria-label |
string |
'Multi-range slider' |
Accessibility label |
aria-labelledby |
string |
- | ID of element that labels the slider |
interface Mark {
value: number;
label?: string;
}
const [priceRange, setPriceRange] = useState([25, 75]);
<MultiSliderPro
values={priceRange}
onChange={setPriceRange}
min={0}
max={100}
showLabels
showValueLabels
formatLabel={(value) => `$${value}`}
aria-label="Price range selector"
/>
const [values, setValues] = useState([20, 50, 80]);
<MultiSliderPro
values={values}
onChange={setValues}
rangeColor="bg-red-500"
handleColor="bg-red-500"
trackHeight="h-2"
handleSize="w-6 h-6"
showValueLabels
/>
const marks = [
{ value: 0, label: 'Min' },
{ value: 25, label: '25%' },
{ value: 50, label: 'Mid' },
{ value: 75, label: '75%' },
{ value: 100, label: 'Max' }
];
<MultiSliderPro
values={[30, 70]}
marks={marks}
showLabels
step={5}
/>
// Controlled (recommended)
const [values, setValues] = useState([20, 80]);
<MultiSliderPro values={values} onChange={setValues} />
// With commit handler for API calls
<MultiSliderPro
values={values}
onChange={setValues} // Real-time updates
onChangeCommitted={(finalValues) => {
// Call API when user finishes dragging
updateFilters(finalValues);
}}
/>
Key | Action |
---|---|
← ↓ |
Move handle left/down by step |
→ ↑ |
Move handle right/up by step |
Shift + ←↓→↑ |
Move handle by large step (10% of range) |
Home |
Move handle to minimum value |
End |
Move handle to maximum value |
Page Down |
Move handle down by large step |
Page Up |
Move handle up by large step |
Tab |
Navigate between handles |
The component follows WAI-ARIA guidelines:
- Each handle has
role="slider"
- Proper
aria-valuemin
,aria-valuemax
, andaria-valuenow
attributes - Keyboard navigation support
- Screen reader announcements
- Focus management
<MultiSliderPro
aria-label="Temperature range"
aria-labelledby="temp-label"
values={[18, 24]}
/>
The component uses Tailwind CSS classes for styling. You can customize:
<MultiSliderPro
trackColor="bg-gray-200"
rangeColor="bg-purple-500"
handleColor="bg-purple-600"
/>
<MultiSliderPro
trackHeight="h-3"
handleSize="w-8 h-8"
containerHeight="h-12"
/>
<MultiSliderPro
className="my-custom-slider"
style={{ marginTop: '20px' }}
/>
<MultiSliderPro
allowCross={false} // Handles cannot pass each other
pushable={5} // Minimum 5-unit gap between handles
/>
<MultiSliderPro
allowCross={true} // Handles can cross each other
/>
- Chrome/Chromium 60+
- Firefox 55+
- Safari 12+
- Edge 79+
- Mobile browsers (iOS Safari, Chrome Mobile)
- React 16.8+ (hooks support)
- Tailwind CSS 2.0+
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
MIT License - feel free to use in your projects!
If you find this component helpful, please consider supporting its development:
Your sponsorship helps maintain and improve this component. Support the developer:
- GitHub Sponsors - One-time or monthly support
- ⭐ Star this repository on GitHub
- 🐛 Report bugs and issues
- 💡 Suggest new features and improvements
- 📢 Share this component with others
- 💻 Contribute code improvements
Your support makes a difference! Every contribution helps keep this project alive and continuously improved.
- Initial release
- Multiple handle support
- Keyboard navigation
- Mobile touch support
- Full accessibility
- Customizable styling
- Marks support