Reputation: 5123
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles, makeStyles } from '@material-ui/core/styles';
import Slider from '@material-ui/core/Slider';
import Typography from '@material-ui/core/Typography';
import Tooltip from '@material-ui/core/Tooltip';
const useStyles = makeStyles((theme) => ({
root: {
width: 300 + theme.spacing(3) * 2,
},
margin: {
height: theme.spacing(3),
},
}));
const AirbnbSlider = withStyles({
root: {
color: '#3a8589',
height: 3,
padding: '13px 0',
},
thumb: {
height: 27,
width: 27,
backgroundColor: '#fff',
border: '1px solid currentColor',
marginTop: -12,
marginLeft: -13,
boxShadow: '#ebebeb 0 2px 2px',
'&:focus, &:hover, &$active': {
boxShadow: '#ccc 0 2px 3px 1px',
},
'& .bar': {
// display: inline-block !important;
height: 9,
width: 1,
backgroundColor: 'currentColor',
marginLeft: 1,
marginRight: 1,
},
},
active: {},
track: {
height: 3,
},
rail: {
color: '#d8d8d8',
opacity: 1,
height: 3,
},
})(Slider);
function AirbnbThumbComponent(props) {
return (
<span {...props}>
<span className="bar" />
<span className="bar" />
<span className="bar" />
</span>
);
}
export default function CustomizedSlider() {
const classes = useStyles();
return (
<div className={classes.root}>
<Typography gutterBottom>Airbnb</Typography>
<AirbnbSlider
ThumbComponent={AirbnbThumbComponent}
getAriaLabel={(index) => (index === 0 ? 'Minimum price' : 'Maximum price')}
defaultValue={[20, 40]}
/>
</div>
);
}
Upvotes: 3
Views: 2038
Reputation: 81006
Material-UI passes a data-index
prop to the thumb which will be 0
for the first thumb and 1
for the second. You can leverage this prop to add an additional class to the thumb which you can then use in your styles:
function AirbnbThumbComponent(props) {
const { children, className, ...other } = props;
const extraClassName =
other["data-index"] === 0 ? "first-thumb" : "second-thumb";
return (
<SliderThumb {...other} className={clsx(className, extraClassName)}>
{children}
<span className="airbnb-bar" />
<span className="airbnb-bar" />
<span className="airbnb-bar" />
</SliderThumb>
);
}
Below is a full working example. This example uses v5 and the styled
function, but the same approach is doable with v4 using withStyles
.
This produces the following look:
import * as React from "react";
import PropTypes from "prop-types";
import Slider, { SliderThumb } from "@material-ui/core/Slider";
import { styled } from "@material-ui/core/styles";
import Typography from "@material-ui/core/Typography";
import Box from "@material-ui/core/Box";
import clsx from "clsx";
const AirbnbSlider = styled(Slider)(({ theme }) => ({
color: "#3a8589",
height: 3,
padding: "13px 0",
"& .MuiSlider-thumb": {
height: 27,
width: 27,
backgroundColor: "#fff",
border: "1px solid currentColor",
"&.second-thumb": {
border: "2px dashed purple"
},
"&:hover": {
boxShadow: "0 0 0 8px rgba(58, 133, 137, 0.16)"
},
"& .airbnb-bar": {
height: 9,
width: 1,
marginLeft: 1,
marginRight: 1
},
"&.first-thumb .airbnb-bar": {
backgroundColor: "red"
},
"&.second-thumb .airbnb-bar": {
backgroundColor: "currentColor"
}
},
"& .MuiSlider-track": {
height: 3
},
"& .MuiSlider-rail": {
color: theme.palette.mode === "dark" ? "#bfbfbf" : "#d8d8d8",
opacity: theme.palette.mode === "dark" ? undefined : 1,
height: 3
}
}));
function AirbnbThumbComponent(props) {
const { children, className, ...other } = props;
const extraClassName =
other["data-index"] === 0 ? "first-thumb" : "second-thumb";
return (
<SliderThumb {...other} className={clsx(className, extraClassName)}>
{children}
<span className="airbnb-bar" />
<span className="airbnb-bar" />
<span className="airbnb-bar" />
</SliderThumb>
);
}
AirbnbThumbComponent.propTypes = {
children: PropTypes.node
};
export default function CustomizedSlider() {
return (
<Box sx={{ width: 320 }}>
<Typography gutterBottom>Airbnb</Typography>
<AirbnbSlider
components={{ Thumb: AirbnbThumbComponent }}
getAriaLabel={(index) =>
index === 0 ? "Minimum price" : "Maximum price"
}
defaultValue={[20, 40]}
/>
</Box>
);
}
Upvotes: 3