如何设置 MUI
Tooltip
文本的样式?悬停时的默认工具提示是黑色的,没有文字换行。是否可以更改背景、颜色等?这个选项甚至可用吗?
这个问题的另一个流行答案(André Junges)是针对 Material-UI 的 0.x 版本。下面我从 Material UI 的工具提示 - 自定义样式 中复制了我的答案,它针对 v3 和 v4 解决了这个问题。再往下,我添加了一个使用 v5 的示例版本。
下面是如何通过主题覆盖所有工具提示,或使用 withStyles 自定义单个工具提示的示例(两个不同的示例)。第二种方法也可用于创建自定义工具提示组件,您可以重复使用该组件而无需强制在全局范围内使用它。
import React from "react";
import ReactDOM from "react-dom";
import {
createMuiTheme,
MuiThemeProvider,
withStyles
} from "@material-ui/core/styles";
import Tooltip from "@material-ui/core/Tooltip";
const defaultTheme = createMuiTheme();
const theme = createMuiTheme({
overrides: {
MuiTooltip: {
tooltip: {
fontSize: "2em",
color: "yellow",
backgroundColor: "red"
}
}
}
});
const BlueOnGreenTooltip = withStyles({
tooltip: {
color: "lightblue",
backgroundColor: "green"
}
})(Tooltip);
const TextOnlyTooltip = withStyles({
tooltip: {
color: "black",
backgroundColor: "transparent"
}
})(Tooltip);
function App(props) {
return (
<MuiThemeProvider theme={defaultTheme}>
<div className="App">
<MuiThemeProvider theme={theme}>
<Tooltip title="This tooltip is customized via overrides in the theme">
<div style={{ marginBottom: "20px" }}>
Hover to see tooltip customized via theme
</div>
</Tooltip>
</MuiThemeProvider>
<BlueOnGreenTooltip title="This tooltip is customized via withStyles">
<div style={{ marginBottom: "20px" }}>
Hover to see blue-on-green tooltip customized via withStyles
</div>
</BlueOnGreenTooltip>
<TextOnlyTooltip title="This tooltip is customized via withStyles">
<div>Hover to see text-only tooltip customized via withStyles</div>
</TextOnlyTooltip>
</div>
</MuiThemeProvider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
这里是关于工具提示 CSS 类的文档,可用于控制工具提示行为的不同方面:https://material-ui.com/api/tooltip/#css
这里是关于覆盖主题中这些类的文档:https://material-ui.com/customization/components/#global-theme-override
这里是一个类似的例子,但更新后可以与 Material-UI 的 v5 一起使用(注意它在 5.0.3 和更高版本中工作,经过一些修复)。它包括通过主题定制、使用
styled
定制和使用sx
道具定制。所有这些自定义都针对“工具提示槽”,以便将 CSS 应用于控制工具提示视觉外观的元素。
import React from "react";
import ReactDOM from "react-dom";
import { createTheme, ThemeProvider, styled } from "@mui/material/styles";
import Tooltip from "@mui/material/Tooltip";
const defaultTheme = createTheme();
const theme = createTheme({
components: {
MuiTooltip: {
styleOverrides: {
tooltip: {
fontSize: "2em",
color: "yellow",
backgroundColor: "red"
}
}
}
}
});
const BlueOnGreenTooltip = styled(({ className, ...props }) => (
<Tooltip {...props} componentsProps={{ tooltip: { className: className } }} />
))(`
color: lightblue;
background-color: green;
font-size: 1.5em;
`);
const TextOnlyTooltip = styled(({ className, ...props }) => (
<Tooltip {...props} componentsProps={{ tooltip: { className: className } }} />
))(`
color: black;
background-color: transparent;
`);
function App(props) {
return (
<ThemeProvider theme={defaultTheme}>
<div className="App">
<ThemeProvider theme={theme}>
<Tooltip title="This tooltip is customized via overrides in the theme">
<div style={{ marginBottom: "20px" }}>
Hover to see tooltip customized via theme
</div>
</Tooltip>
</ThemeProvider>
<BlueOnGreenTooltip title="This tooltip is customized via styled">
<div style={{ marginBottom: "20px" }}>
Hover to see blue-on-green tooltip customized via styled
</div>
</BlueOnGreenTooltip>
<TextOnlyTooltip title="This tooltip is customized via styled">
<div style={{ marginBottom: "20px" }}>
Hover to see text-only tooltip customized via styled
</div>
</TextOnlyTooltip>
<Tooltip
title="This tooltip is customized via the sx prop"
componentsProps={{
tooltip: {
sx: {
color: "purple",
backgroundColor: "lightblue",
fontSize: "2em"
}
}
}}
>
<div>
Hover to see purple-on-blue tooltip customized via the sx prop
</div>
</Tooltip>
</div>
</ThemeProvider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
关于 v4 和 v5 之间主题结构变化的文档:https://mui.com/guides/migration-v4/#theme
Material-UI文档中的Tooltip自定义示例:https://mui.com/components/tooltips/#customization
MUI v5 更新
您可以通过覆盖工具提示槽中的样式来自定义
Tooltip
。在 v5 中有 3 种方法可以做到这一点。有关参考,请参阅Tooltip
的自定义部分。更多
sx
道具和createTheme
的例子可以在here和here中看到。
styled()
const ToBeStyledTooltip = ({ className, ...props }) => (
<Tooltip {...props} classes={{ tooltip: className }} />
);
const StyledTooltip = styled(ToBeStyledTooltip)(({ theme }) => ({
backgroundColor: '#f5f5f9',
color: 'rgba(0, 0, 0, 0.87)',
border: '1px solid #dadde9',
}));
sx
道具<Tooltip
title="Add"
arrow
componentsProps={{
tooltip: {
sx: {
bgcolor: 'common.black',
'& .MuiTooltip-arrow': {
color: 'common.black',
},
},
},
}}
>
<Button>SX</Button>
</Tooltip>
createTheme
+ ThemeProvider
const theme = createTheme({
components: {
MuiTooltip: {
styleOverrides: {
tooltip: {
backgroundColor: 'pink',
color: 'red',
border: '1px solid #dadde9',
},
},
},
},
});
这个答案已经过时了。 这个答案是在 2016 年为 Material-UI 的 0.x 版本编写的。请参阅这个答案,了解适用于版本 3 和 4 的方法。
好吧,您可以更改文本颜色和自定义 mui 主题的元素背景。
color
- 是文字颜色
rippleBackgroundColor
- 是工具提示 bbackground
示例:使用
IconButton
- 但你可以直接使用 Tooltip
..
import React from 'react';
import IconButton from 'material-ui/IconButton';
import MuiThemeProvider from 'material-ui/lib/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/lib/styles/getMuiTheme';
const muiTheme = getMuiTheme({
tooltip: {
color: '#f1f1f1',
rippleBackgroundColor: 'blue'
},
});
const Example = () => (
<div>
<MuiThemeProvider muiTheme={muiTheme}>
<IconButton iconClassName="muidocs-icon-custom-github" tooltip="test" />
</MuiThemeProvider>
</div>
);
您还可以为
style
传递一个 Tooltip
对象(在 IconButton
中是 tooltipStyles
)——但这些样式只会应用于根元素。
还不能更改标签样式以使其换行。
我也遇到了这个问题,希望任何想简单地改变工具提示颜色的人都能看到这个对我有用的解决方案:
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Tooltip from '@material-ui/core/Tooltip';
import Button from '@material-ui/core/Button';
import DeleteIcon from '@material-ui/icons/Delete';
const useStyles = makeStyles(theme => ({
customTooltip: {
// I used the rgba color for the standard "secondary" color
backgroundColor: 'rgba(220, 0, 78, 0.8)',
},
customArrow: {
color: 'rgba(220, 0, 78, 0.8)',
},
}));
export default TooltipExample = () => {
const classes = useStyles();
return (
<>
<Tooltip
classes={{
tooltip: classes.customTooltip,
arrow: classes.customArrow
}}
title="Delete"
arrow
>
<Button color="secondary"><DeleteIcon /></Button>
</Tooltip>
</>
);
};
基于 NearHuscarl 的答案 使用
sx
,对我来说最简单的方法是创建一个自定义组件以包含样式以及您想要在每个工具提示上重复的任何其他属性。
例如,组件可以在底部显示带有箭头和更大字体的工具提示:
const StyledTooltip = ({ title, children, ...props }) => (
<Tooltip
{...props}
title={title}
placement="bottom"
arrow
componentsProps={{
tooltip: {
sx: {
fontSize: '1.125rem',
},
},
}}
>
{children}
</Tooltip>
);
const Buttons = () => (
<div>
<StyledTooltip title="This is one">
<Button>One</Button>
</StyledTooltip>
<StyledTooltip title="This is two">
<Button>Two</Button>
</StyledTooltip>
</div>
);
我使用 HtmlTooltip 并为箭头工具提示样式添加
arrow: {color: '#f5f5f9',},
。
更多关于工具提示样式本身。
所以我使用
ValueLabelComponent
来控制标签,并在 MaterialUI 中放置一个 Tooltip
。
希望它能提供另一种编辑 MaterialUI 工具提示的方法 :)
const HtmlTooltip = withStyles((theme) => ({
tooltip: {
backgroundColor: 'var(--blue)',
color: 'white',
maxWidth: 220,
fontSize: theme.typography.pxToRem(12),
border: '1px solid #dadde9',
},
arrow: {
color: '#f5f5f9',
},
}))(Tooltip);
function ValueLabelComponent({ children, open, value }) {
return (
<HtmlTooltip arrow open={open} enterTouchDelay={0} placement="top" title={value}>
{children}
</HtmlTooltip>
);
}
...
...
return (
<div className={classes.root}>
<Slider
value={value}
onChange={handleChange}
onChangeCommitted={handleChangeCommitted}
scale={(x) => convertRangeValueToOriginalValue(x, minMaxObj)}
valueLabelDisplay="auto"
valueLabelFormat={(x) => '$' + x}
ValueLabelComponent={ValueLabelComponent}
aria-labelledby="range-slider"
/>
</div>
);
我用了
makeStyles()
然后结束了:
import React from 'react';
import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';
import Tooltip from '@mui/material/Tooltip';
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
import { makeStyles } from '@material-ui/core/styles';
const styles = makeStyles({
tooltip: {
backgroundColor: '#FFFFFF',
color: '#000000',
border: '.5px solid #999999',
fontSize: '.85rem',
fontWeight: '400'
}
});
const HeaderTooltip = ({ header, tooltip }) =>
<Grid container direction="row" alignItems="center" spacing={1}>
<Grid item>
<Typography variant='h5'>{header}</Typography>
</Grid>
<Grid item>
<Tooltip title={tooltip} classes={{ tooltip: styles().tooltip }}>
<InfoOutlinedIcon />
</Tooltip>
</Grid>
</Grid>
export default HeaderTooltip;
使用 styledComponent 和 MUI V5
import styled from 'styled-components';
....
....
<StyledTooltip title={tooltip}>
<IconTextStyle>
{icon}
<Label>{label}</Label>
</IconTextStyle>
</StyledTooltip>
const StyledTooltip = styled((props) => (
<Tooltip classes={{ popper: props.className }} {...props} />
))`
& .MuiTooltip-tooltip {
display: flex;
background-color: #191c28;
border-radius: 4px;
box-shadow: 0px 0px 24px #00000034;
}
`;
我通过以下方式创建了自定义工具提示
import React from 'react'
import Tooltip from '@material-ui/core/Tooltip'
import ErrorOutlineOutlinedIcon from '@material-ui/icons/ErrorOutlineOutlined'
import {
makeStyles,
createStyles,
withStyles,
} from '@material-ui/core/styles'
import Typography from '@material-ui/core/Typography'
import { Divider, Link, Paper } from '@material-ui/core'
const HtmlTooltip = withStyles(theme => ({
arrow: {
'&::before': {
color: 'white'
}
},
tooltip: {
backgroundColor: '#f5f5f9',
boxShadow: theme.shadows[8],
color: 'rgba(0, 0, 0, 0.87)',
fontSize: 14,
maxWidth: 800,
padding: 0,
},
tooltipPlacementTop: {
margin: '4px 0',
},
}))(Tooltip)
const imageStyles = { root: { color: 'deeppink', height: 20, marginBottom: 0, width: 20 } }
const Image = withStyles(imageStyles)(({ classes }) => (
<ErrorOutlineOutlinedIcon classes={classes} />
))
const useStyles = makeStyles(theme =>
createStyles({
content: {
border: `1px solid ${theme.palette.grey[300]}`,
margin: 0,
minWidth: 600,
padding: 0,
zIndex: 1,
},
contentInner: {
padding: theme.spacing(1)
},
header: {
backgroundColor: 'deeppink',
fontWeight: 'bold',
padding: theme.spacing(1),
}
})
)
export default function CustomTooltip(params) {
const classes = useStyles()
const labelDisplay = params.content
const textDispaly = params.text
return (
<>
{labelDisplay && labelDisplay.length > 20 ? (<HtmlTooltip arrow interactive title={
<Paper className={classes.content}>
<div className={classes.header}>
<Typography color='inherit' variant='body1' style={{color: 'white', fontSize: '20px'}}>
{params.title}
</Typography>
</div>
<Divider />
<div className={classes.contentInner}>
{textDispaly}
</div>
</Paper>}
placement='top'
>
<div style={{ alignItems: 'center', display: 'flex', fontSize: '12px', justifyContent: 'space-between' }}>
{labelDisplay}<Image/>
</div>
</HtmlTooltip>) : (labelDisplay)}
</>
)
}
我们可以通过以下方式自定义tooltip样式
import CheckCircleIcon from '@material-ui/icons/CheckCircle'
import ErrorIcon from '@material-ui/icons/Error'
import { withStyles } from '@material-ui/core/styles'
import Tooltip from '@material-ui/core/Tooltip'
// import getOr from 'lodash/fp/getOr'
import isEmpty from 'lodash/fp/isEmpty'
import classnames from 'classnames'
import PropTypes from 'prop-types'
import React from 'react'
import styles from './styles'
const Component = ({
classes,
value
}) => {
const LightTooltipSuccess = withStyles(theme => ({
tooltip: {
backgroundColor: '#16181a',
border: '2px solid limegreen',
borderRadius: '2px',
fontSize: 12,
width: '300px'
},
}))(Tooltip)
const LightTooltipFailure = withStyles(theme => ({
tooltip: {
backgroundColor: '#16181a',
border: '2px solid red',
borderRadius: '2px',
fontSize: 12,
width: '300px'
},
}))(Tooltip)
const RenderValidated = isValidated => {
return isEmpty(isValidated)
? <LightTooltipSuccess {...{
placement: 'top',
title: 'Success: Request row has been submitted'
}}>
<CheckCircleIcon className={classnames(classes.icon, classes.success)}/>
</LightTooltipSuccess>
: <LightTooltipFailure {...{
placement: 'top',
title: `Error: ${isValidated.join(', ')}` // Error: ${getOr([], isValidated).join(', ')}`
}}>
<ErrorIcon className={classes.icon} color='error'/>
</LightTooltipFailure>
}
return RenderValidated(value)
}
Component.displayName = 'ValidatedFramework'
Component.propTypes = {
classes: PropTypes.shape({
icon: PropTypes.string.isRequired,
success: PropTypes.string.isRequired
}),
value: PropTypes.arrayOf(PropTypes.string).isRequired
}
export default withStyles(styles)(Component)