当 material ui 滑块有多个拇指时,如何独立设置每个拇指的样式?
How to style each thumb independently when material ui slider have multiple thumbs?
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>
);
}
Material-UI passes a data-index
prop 到拇指,第一个拇指为 0
,第二个拇指为 1
。您可以利用此道具向拇指添加一个额外的 class,然后您可以在您的样式中使用它:
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>
);
}
下面是一个完整的工作示例。此示例使用 v5 和 styled
函数,但使用 withStyles
.
的 v4 也可以使用相同的方法
这会产生以下外观:
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>
);
}
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>
);
}
Material-UI passes a data-index
prop 到拇指,第一个拇指为 0
,第二个拇指为 1
。您可以利用此道具向拇指添加一个额外的 class,然后您可以在您的样式中使用它:
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>
);
}
下面是一个完整的工作示例。此示例使用 v5 和 styled
函数,但使用 withStyles
.
这会产生以下外观:
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>
);
}