【问题标题】:How to style MUI Tooltip?如何设置 MUI 工具提示的样式?
【发布时间】:2016-08-14 02:05:31
【问题描述】:

如何设置 MUI Tooltip 文本的样式?悬停时的默认工具提示显示为黑色,没有文字换行。是否可以更改背景,颜色等?这个选项甚至可用吗?

【问题讨论】:

    标签: reactjs tooltip material-ui formsy-material-ui


    【解决方案1】:

    关于这个问题的另一个流行答案(André Junges)是针对 Material-UI 的 0.x 版本。下面我从Material UI's Tooltip - Customization Style 复制了我的答案,它针对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.3some fixes 之后的更高版本)。它包括通过主题进行自定义、使用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 文档中的工具提示自定义示例:https://mui.com/components/tooltips/#customization

    【讨论】:

    • 我只是好奇,为什么我们需要以这种方式创建样式组件? styled(({ className, ...props }) => ( ) 为什么 styled(Tooltip) 在这种情况下不起作用?
    • @Javatar styled(Tooltip) 将导致通过className 属性应用样式,但Tooltip 将它收到的大多数属性(包括className)传递给它包装的子元素(可能是因为用Tooltip 包裹的组件可以接收道具的方式与没有被Tooltip 包裹的方式大致相同),所以styled(Tooltip) 实际上会设置被包裹元素的样式而不是工具提示。
    【解决方案2】:

    这个答案已经过时了。这个答案是在 2016 年为 Material-UI 的 0.x 版本编写的。请参阅this answer 了解适用于版本 3 和 4 的方法。

    嗯,你可以改变文本颜色和自定义mui主题的元素背景。

    color - 是文本颜色

    rippleBackgroundColor - 是工具提示的背景

    示例:使用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>
    );
    

    您还可以为Tooltip 传递一个style 对象(在IconButton 中是tooltipStyles) - 但这些样式只会应用于根元素。

    目前尚无法更改标签样式以使其包含多行。

    【讨论】:

      【解决方案3】:

      我也遇到了这个问题,希望任何想要简单地更改工具提示颜色的人都能看到这个对我有用的解决方案:

      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>
          </>
        );
      };
      

      【讨论】:

      • 似乎有一个我偶然发现的“边缘”案例。如果 的子组件是函数式组件,那么 React 会抛出一条警告消息,指出无法将 refs 传递给函数式组件。所以如果我有类似 StyleMenu/> 的东西。它可以工作,但反应会引发警告消息,指示应该使用 ForwardRef?我该如何处理?
      • 这效果更好,因为传递一个跨度只对跨度覆盖的区域进行着色,因此工具提示的外围区域仍然具有默认颜色,此方法更改工具提示背景
      【解决方案4】:

      如果你想改变 Tooltip 的 text color , font-size ... 有一个简单的方法。

      例如,您可以在 Martial Ui Tooltip 的标题内插入标签:

      <Tooltip title={<span>YourText</span>}>
         <Button>Grow</Button>
      </Tooltip>
      

      然后你可以随心所欲地设计你的标签。

      检查下面的例子:

      【讨论】:

      • 迄今为止最简单的答案。在我的情况下,我也可以使用 styled-components 设置 的样式。
      • @LucasAndrade 是的,我很高兴它对你有帮助,祝你好运
      【解决方案5】:

      MUI v5 更新

      您可以通过覆盖工具提示槽中的样式来自定义Tooltip。在 v5 中有 3 种方法可以做到这一点。有关参考,请参阅 Tooltipcustomization 部分。更多sx prop 和createTheme 的例子可见herehere

      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',
              },
            },
          },
        },
      });
      

      【讨论】:

      • 如何在另一个组件上使用它,比如简单的 div 或 Typography ?
      • @sshmaxime 与我在回答中对Button 所做的相同。有什么问题吗?
      【解决方案6】:

      使用 HtmlTooltip 的另一种解决方案

      我使用 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>
        );
      

      【讨论】:

        【解决方案7】:

        我使用了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;
        

        【讨论】:

          【解决方案8】:

          MUI v5 自定义组件

          NearHuscarl's answer 的基础上使用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>
          );
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-10-19
            • 1970-01-01
            • 1970-01-01
            • 2011-07-15
            • 2019-01-18
            • 2021-07-19
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多