Slider

Capture user feedback from a range of values
Import

Usage

20%
50%
80%
Type
Color
Size
Radius
<Slider
marks={[
{ value: 20, label: '20%' },
{ value: 50, label: '50%' },
{ value: 80, label: '80%' },
]}
/>

Controlled

By default both Slider and RangeSlider are uncontrolled, add onChange and value props to make them controlled:

import { useState } from 'react';
import { Slider, RangeSlider } from '@mantine/core';
function Demo() {
const [value, setValue] = useState(40);
const [rangeValue, setRangeValue] = useState([20, 80]);
return (
<>
<Slider value={value} onChange={setValue} />
<RangeSlider value={rangeValue} onChange={setRangeValue} />
</>
);
}

Control label

To change label behavior and appearance set props:

  • label – formatter function, accepts value as an argument, set to null to disable label, defaults to f => f
  • labelAlwaysOn – if true – label will always be displayed, by default label is visible only when user is dragging
  • labelTransition, labelTransitionDuration, labelTransitionTimingFunction – label uses Transition component to animate presence, you can choose any premade transition or create your own
No label
Formatted label
Label always visible
40
Custom label transition
// Disable label
<Slider label={null} />
// Format label with function
<Slider label={(value) => `${value} °C`} />
// Always display label
<Slider labelAlwaysOn />
// Change label transition
<Slider
labelTransition="skew-down"
labelTransitionDuration={150}
labelTransitionTimingFunction="ease"
/>

Min, max and step

Decimal step
Step matched with marks
// Set min, max and step props to replace default values
<Slider
defaultValue={5}
min={-10}
max={10}
label={(value) => value.toFixed(1)}
step={0.1}
styles={{ markLabel: { display: 'none' } }}
/>
// Configure marks to match step
const MARKS = [
{ value: 0, label: 'xs' },
{ value: 25, label: 'sm' },
{ value: 50, label: 'md' },
{ value: 75, label: 'lg' },
{ value: 100, label: 'xl' },
];
<Slider
label={(val) => MARKS.find((mark) => mark.value === val).label}
defaultValue={50}
step={25}
radius={0}
marks={MARKS}
styles={{ markLabel: { display: 'none' } }}
/>

Marks

Add any amount of marks to slider by setting marks prop to an array of objects:

const marks = [
{ value: 20 }, // -> displays mark on slider track
{ value: 40, label: '40%' }, // -> adds mark label below slider track
];

Note that mark value is relative to slider value, not width:

20%
50%
80%
20%
50%
80%
const marks = [
{ value: 20, label: '20%' },
{ value: 50, label: '50%' },
{ value: 80, label: '80%' },
];
<Slider defaultValue={40} marks={[{ value: 10 }, { value: 40 }, { value: 95 }]} />
<Slider defaultValue={40} marks={marks} />
<RangeSlider defaultValue={[20, 80]} marks={marks} />

Styles API

You can change styles of any element in slider component with Styles API to match your design requirements:

20%
50%
80%
<Slider
defaultValue={40}
marks={marks}
labelTransition="fade"
size={2}
styles={{
track: {
backgroundColor:
theme.colorScheme === 'dark' ? theme.colors.dark[3] : theme.colors.blue[1],
},
mark: {
width: 6,
height: 6,
borderRadius: 6,
transform: 'translateX(-3px) translateY(-2px)',
borderColor: theme.colorScheme === 'dark' ? theme.colors.dark[3] : theme.colors.blue[1],
},
markFilled: {
borderColor: theme.colors.blue[6],
},
markLabel: { fontSize: theme.fontSizes.xs, marginBottom: 5, marginTop: 0 },
thumb: {
height: 16,
width: 16,
backgroundColor: theme.white,
borderWidth: 1,
boxShadow: theme.shadows.sm,
},
}}
/>

Accessibility and usability

Slider and RangeSlider components are accessible by default:

  • Slider thumbs are focusable
  • When user uses mouse to interact with slider, focus is moved on slider track, when user presses arrows focus is moved on thumb
  • Value can be changed with arrows with step increment/decrement

To label component for screen readers add labels to thumbs:

<Slider thumbLabel="Thumb aria-label" />
<RangeSlider thumbFromLabel="First thumb aria-label" thumbToLabel="Second thumb aria-label" />

TypeScript

Component props type

Import component props type:

import type { SliderProps, RangeSliderProps } from '@mantine/core';

Both SliderProps and RangeSliderProps extend React.ComponentPropsWithoutRef<'div'>, all other props are available under Component props tab.

SliderStylesNames type

SliderStylesNames type is a union with Slider and RangeSlider Styles API names:

import type { SliderStylesNames } from '@mantine/core';
const sliderClasses: Partial<Record<SliderStylesNames, 'string'>> = {
thumb: 'slider-thumb',
mark: 'slider-mark',
};
// Slider and RangeSlider have the same styles API
<Slider classNames={sliderClasses} />;
<RangeSlider classNames={sliderClasses} />;

See full styles descriptions list under Styles API tab.

Build fully functional accessible web applications faster than ever
Feedback
Your feedback is most valuable contribution to the project, please share how you use Mantine, what features are missing and what is done good
Leave feedback