Skip to main content

Slider

Please refer to MUI's official docs for more details on component's usage guide and API documentation.

Basic Slider

Use defaultValue prop for default slider value and disabled prop for disabled slider.

Basic Slider

Disabled Slider


// MUI Imports
import Slider from '@mui/material/Slider'
import Typography from '@mui/material/Typography'

const SliderBasic = () => {
return (
<div>
<Typography className='font-medium' color='text.primary'>
Basic Slider
</Typography>
<Slider defaultValue={30} aria-labelledby='continuous-slider' />
<Typography className='font-medium' color='text.primary'>
Disabled Slider
</Typography>
<Slider disabled defaultValue={30} aria-labelledby='disabled-slider' />
</div>
)
}

export default SliderBasic
Controlled and Uncontrolled

Manage value prop with the help of a state for controlled slider and use defaultValue prop for uncontrolled slider.

Controlled Slider

Uncontrolled Slider


// React Imports
import { useState } from 'react'

// MUI Imports
import Slider from '@mui/material/Slider'
import Typography from '@mui/material/Typography'

const SliderControlledUncontrolled = () => {
// States
const [value, setValue] = useState<number>(30)

return (
<div>
<Typography className='font-medium' color='text.primary'>
Controlled Slider
</Typography>
<Slider
value={value}
aria-labelledby='controlled-slider'
onChange={(event, newValue: number | number[]) => setValue(newValue as number)}
/>
<Typography className='font-medium' color='text.primary'>
Uncontrolled Slider
</Typography>
<Slider defaultValue={30} aria-labelledby='uncontrolled-slider' />
</div>
)
}

export default SliderControlledUncontrolled
Discrete Slider

You can generate a mark for each step with marks prop.


// MUI Imports
import Slider from '@mui/material/Slider'

const valuetext = (value: number) => {
return `${value}°C`
}

const SliderDiscrete = () => {
return (
<Slider
marks
min={10}
max={110}
step={10}
defaultValue={30}
valueLabelDisplay='auto'
getAriaValueText={valuetext}
aria-labelledby='discrete-slider'
/>
)
}

export default SliderDiscrete
Small Steps

You can change the default step increment with step prop.


// MUI Imports
import Slider from '@mui/material/Slider'

const valuetext = (value: number) => {
return `${value}°C`
}

const SliderSmallSteps = () => {
return (
<Slider
marks
step={5}
defaultValue={20}
valueLabelDisplay='auto'
getAriaValueText={valuetext}
aria-labelledby='small-steps-slider'
/>
)
}

export default SliderSmallSteps
Custom Marks

You can have custom marks by providing a rich array to the marks prop.


// MUI Imports
import Slider from '@mui/material/Slider'

const marks = [
{
value: 0,
label: '0°'
},
{
value: 20,
label: '20°'
},
{
value: 37,
label: '37°'
},
{
value: 100,
label: '100°'
}
]

const valuetext = (value: number) => {
return `${value}°C`
}

const SliderCustomMarks = () => {
return (
<Slider
step={10}
marks={marks}
defaultValue={20}
valueLabelDisplay='auto'
getAriaValueText={valuetext}
aria-labelledby='custom-marks-slider'
/>
)
}

export default SliderCustomMarks
Restricted Values

You can restrict the selectable values to those provided with the marks prop with step={null}.


// MUI Imports
import Slider from '@mui/material/Slider'

const marks = [
{
value: 0,
label: '0°'
},
{
value: 20,
label: '20°'
},
{
value: 37,
label: '37°'
},
{
value: 100,
label: '100°'
}
]

const valuetext = (value: number) => {
return `${value}°C`
}

const valueLabelFormat = (value: number) => {
return marks.findIndex(mark => mark.value === value) + 1
}

const SliderRestrictedValues = () => {
return (
<Slider
step={null}
marks={marks}
defaultValue={20}
valueLabelDisplay='auto'
getAriaValueText={valuetext}
valueLabelFormat={valueLabelFormat}
aria-labelledby='restricted-values-slider'
/>
)
}

export default SliderRestrictedValues
Label Always Visible

You can force the thumb label to be always visible with valueLabelDisplay='on'.


// MUI Imports
import Slider from '@mui/material/Slider'

const marks = [
{
value: 0,
label: '0°'
},
{
value: 20,
label: '20°'
},
{
value: 37,
label: '37°'
},
{
value: 100,
label: '100°'
}
]

const valuetext = (value: number) => {
return `${value}°C`
}

const SliderLabelAlwaysVisible = () => {
return (
<Slider
step={10}
marks={marks}
defaultValue={80}
valueLabelDisplay='on'
getAriaValueText={valuetext}
aria-labelledby='label-always-visible-slider'
/>
)
}

export default SliderLabelAlwaysVisible
Range Slider

The slider can be used to set the start and end of a range by supplying an array of values to the value or defaultValue prop.


// MUI Imports
import Slider from '@mui/material/Slider'

const SliderRange = () => {
return <Slider defaultValue={[20, 37]} valueLabelDisplay='auto' aria-labelledby='range-slider' />
}

export default SliderRange
Colors

Use color prop for different colored slider.

Secondary Slider

Error Slider

Warning Slider

Info Slider

Success Slider


// MUI Imports
import Slider from '@mui/material/Slider'
import Typography from '@mui/material/Typography'

const SliderColors = () => {
return (
<div>
<Typography className='font-medium' color='text.primary'>
Secondary Slider
</Typography>
<Slider defaultValue={30} color='secondary' aria-labelledby='secondary-slider' />
<Typography className='font-medium' color='text.primary'>
Error Slider
</Typography>
<Slider defaultValue={30} color='error' aria-labelledby='error-slider' />
<Typography className='font-medium' color='text.primary'>
Warning Slider
</Typography>
<Slider defaultValue={30} color='warning' aria-labelledby='warning-slider' />
<Typography className='font-medium' color='text.primary'>
Info Slider
</Typography>
<Slider defaultValue={30} color='info' aria-labelledby='info-slider' />
<Typography className='font-medium' color='text.primary'>
Success Slider
</Typography>
<Slider defaultValue={30} color='success' aria-labelledby='success-slider' />
</div>
)
}

export default SliderColors
Vertical Sliders

Use orientation='vertical' prop for vertical slider.


// MUI Imports
import Slider from '@mui/material/Slider'

const marks = [
{
value: 0,
label: '0°'
},
{
value: 20,
label: '20°'
},
{
value: 37,
label: '37°'
},
{
value: 100,
label: '100°'
}
]

const valuetext = (value: number) => {
return `${value}°C`
}

const SliderVertical = () => {
return (
<div className='bs-[310px]'>
<Slider
orientation='vertical'
getAriaValueText={valuetext}
defaultValue={30}
aria-labelledby='vertical-slider'
className='mie-8'
/>
<Slider
disabled
defaultValue={30}
orientation='vertical'
getAriaValueText={valuetext}
aria-labelledby='vertical-disabled-slider'
className='mie-8'
/>
<Slider
marks={marks}
orientation='vertical'
defaultValue={[20, 37]}
getAriaValueText={valuetext}
aria-labelledby='vertical-marks-slider'
className='mie-0'
/>
</div>
)
}

export default SliderVertical
Customized Slider

Use styled hook to customize your slider.


// MUI Imports
import { styled } from '@mui/material/styles'
import MuiSlider from '@mui/material/Slider'
import type { SliderProps } from '@mui/material/Slider'

const marks = [
{
value: 0
},
{
value: 20
},
{
value: 37
},
{
value: 100
}
]

// Styled Slider component
const Slider = styled(MuiSlider)<SliderProps>(({ theme }) => ({
height: 2,
padding: '15px 0',
color: theme.palette.primary.main,
'& .MuiSlider-rail': {
opacity: 0.5,
backgroundColor: '#bfbfbf'
},
'& .MuiSlider-track': {
border: 'none'
},
'& .MuiSlider-mark': {
width: 1,
height: 8,
backgroundColor: '#bfbfbf',
'&.MuiSlider-markActive': {
opacity: 1,
backgroundColor: 'currentColor'
}
},
'& .MuiSlider-thumb': {
width: 28,
height: 28,
border: 'none',
backgroundColor: theme.palette.common.white,
boxShadow: '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.13),0 0 0 1px rgba(0,0,0,0.02)',
'&:focus, &:hover, &.Mui-active, &.Mui-focusVisible': {
boxShadow: '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02) !important',

// Reset on touch devices, it doesn't add specificity
'@media (hover: none)': {
boxShadow: '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.13),0 0 0 1px rgba(0,0,0,0.02)'
}
}
},
'& .MuiSlider-valueLabel': {
top: 0,
fontSize: 12,
fontWeight: 'normal',
backgroundColor: 'unset',
color: theme.palette.text.primary,
'&:before': {
display: 'none'
},
'& *': {
background: 'transparent',
color: theme.palette.mode === 'dark' ? theme.palette.common.white : theme.palette.common.black
}
}
}))

const SliderCustomized = () => (
<Slider marks={marks} defaultValue={60} valueLabelDisplay='on' aria-labelledby='customized-slider' />
)

export default SliderCustomized
Removed Track

The track can be turned off with track={false} prop.


// MUI Imports
import Slider from '@mui/material/Slider'

const marks = [
{
value: 0,
label: '0°'
},
{
value: 20,
label: '20°'
},
{
value: 37,
label: '37°'
},
{
value: 100,
label: '100°'
}
]

const valuetext = (value: number) => {
return `${value}°C`
}

const SliderRemovedTrack = () => {
return (
<Slider
track={false}
marks={marks}
defaultValue={30}
getAriaValueText={valuetext}
aria-labelledby='removed-track-slider'
/>
)
}

export default SliderRemovedTrack
Sizes

Use size prop for different sizes of slider.

Small

Medium


// MUI Imports
import Slider from '@mui/material/Slider'
import Typography from '@mui/material/Typography'

const SliderSizes = () => {
return (
<div>
<Typography className='font-medium' color='text.primary'>
Small
</Typography>
<Slider size='small' defaultValue={30} aria-labelledby='small-slider' />
<Typography className='font-medium' color='text.primary'>
Medium
</Typography>
<Slider defaultValue={30} aria-labelledby='medium-slider' />
</div>
)
}

export default SliderSizes
Minimum Distance

You can enforce a minimum distance between values in the onChange event handler.


// React Imports
import { useState } from 'react'

// MUI Imports
import Slider from '@mui/material/Slider'

const minDistance = 10

const SliderMinimumDistance = () => {
// States
const [value1, setValue1] = useState<number[]>([20, 37])
const [value2, setValue2] = useState<number[]>([20, 37])

const handleChange1 = (event: Event, newValue: number | number[], activeThumb: number) => {
if (!Array.isArray(newValue)) {
return
}

if (activeThumb === 0) {
setValue1([Math.min(newValue[0], value1[1] - minDistance), value1[1]])
} else {
setValue1([value1[0], Math.max(newValue[1], value1[0] + minDistance)])
}
}

const handleChange2 = (event: Event, newValue: number | number[], activeThumb: number) => {
if (!Array.isArray(newValue)) {
return
}

if (newValue[1] - newValue[0] < minDistance) {
if (activeThumb === 0) {
const clamped = Math.min(newValue[0], 100 - minDistance)

setValue2([clamped, clamped + minDistance])
} else {
const clamped = Math.max(newValue[1], minDistance)

setValue2([clamped - minDistance, clamped])
}
} else {
setValue2(newValue as number[])
}
}

return (
<div>
<Slider
disableSwap
value={value1}
onChange={handleChange1}
valueLabelDisplay='auto'
getAriaLabel={() => 'Minimum distance'}
/>
<Slider
disableSwap
value={value2}
onChange={handleChange2}
valueLabelDisplay='auto'
getAriaLabel={() => 'Minimum distance shift'}
/>
</div>
)
}

export default SliderMinimumDistance
Inverted Track

The track can be inverted with track='inverted' prop.


// MUI Imports
import Slider from '@mui/material/Slider'

const marks = [
{
value: 0,
label: '0°'
},
{
value: 20,
label: '20°'
},
{
value: 37,
label: '37°'
},
{
value: 100,
label: '100°'
}
]

const valuetext = (value: number) => {
return `${value}°C`
}

const SliderInvertedTrack = () => {
return (
<Slider
marks={marks}
track='inverted'
defaultValue={30}
getAriaValueText={valuetext}
aria-labelledby='inverted-track-slider'
/>
)
}

export default SliderInvertedTrack