【问题标题】:Is there a way I can overwrite the colour the Material UI Icons npm package provides in React?有没有办法可以覆盖材料 UI 图标 npm 包在 React 中提供的颜色?
【发布时间】:2018-11-24 19:39:58
【问题描述】:

我是 React 新手,正在使用 npm 包 Material UI 图标 (https://www.npmjs.com/package/@material-ui/icons) 并在 React 组件中显示图标:

导入:

import KeyboardArrowRightIcon from 'material-ui/svg-icons/hardware/keyboard-arrow-right';

和渲染:

readMoreLink={<a href={someUrl} >Read more <KeyboardArrowRightIcon /></a>}

但是,由于KeyboardArrowRightIcon 是 npm 包提供的 SVG,它带有自己的填充颜色:

例如:&lt;svg viewBox="0 0 24 24" style="display: inline-block; color: rgba(0, 0, 0, 0.54);...

我知道我可以通过在元素中添加样式属性来覆盖此颜色,例如:

<KeyboardArrowRightIcon style={{ fill: '#0072ea' }} />

但是有没有办法让它成为一个 SCSS 变量 (style={{ fill: $link-color }})?

我担心如果样式表中的链接颜色发生变化,以后有人将不得不寻找所有这些硬编码实例。

【问题讨论】:

    标签: reactjs sass


    【解决方案1】:

    更改图标颜色

    <HomeIcon />
    <HomeIcon color="primary" />
    <HomeIcon color="secondary" />
    <HomeIcon color="action" />
    <HomeIcon color="disabled" />
    <HomeIcon style={{ color: green[500] }} />
    <HomeIcon style={{ color: 'red' }} />
    

    更改图标大小

    <HomeIcon fontSize="small" />
    <HomeIcon />
    <HomeIcon fontSize="large" />
    <HomeIcon style={{ fontSize: 40 }} />
    

    MDI 使用 Icon 组件

    <Icon>add_circle</Icon>
    <Icon color="primary">add_circle</Icon>
    <Icon color="secondary">add_circle</Icon>
    <Icon style={{ color: green[500] }}>add_circle</Icon>
    <Icon fontSize="small">add_circle</Icon>
    <Icon style={{ fontSize: 30 }}>add_circle</Icon>
    

    对于字体

    <Icon className="fa fa-plus-circle" />
    <Icon className="fa fa-plus-circle" color="primary" />
    <Icon className="fa fa-plus-circle" color="secondary" />
    <Icon className="fa fa-plus-circle" style={{ color: green[500] }} />
    <Icon className="fa fa-plus-circle" fontSize="small" />
    <Icon className="fa fa-plus-circle" style={{ fontSize: 30 }} />
    

    Resouces to learn more abo it, Icons

    【讨论】:

      【解决方案2】:

      只需添加样式fill: "green"

      例如:&lt;Star style={{fill: "green"}}/&gt;

      【讨论】:

      • 在过去纯 CSS 的日子里,内联样式不受欢迎。我仍然相信将样式锤击到单个组件是bad practice
      • 我同意内联样式不好。但是这个答案仍然没有回答原来的问题。假设将来 KeyboardArrowRightIcon 将填充颜色更改为“红色”,那么您的硬编码“绿色”值将如何反映新的“红色”颜色?
      【解决方案3】:

      在 Material-UI 中指定/覆盖图标颜色的最简单方法是使用自定义 CSS class name

      假设您想要显示绿色复选框而不是红色三角形,具体取决于某个过程的结果。

      您在代码中的某处创建一个函数,例如:

      function iconStyles() {
        return {
          successIcon: {
            color: 'green',
          },
          errorIcon: {
            color: 'red',
          },
        }
      }
      

      然后将makeStyles 应用于该函数,并运行结果。

      import { makeStyles } from '@material-ui/core/styles';
      ...
      
      const classes = makeStyles(iconStyles)();
      

      在您的渲染函数中,您现在可以使用对象classes

        const chosenIcon = outcome
          ? <CheckCircleIcon className={classes.successIcon} />
          : <ReportProblemIcon className={classes.errorIcon} />;
      

      我在这个答案中首先提到的功能实际上接受一个主题作为输入,并允许您修改/丰富该主题:这确保您的自定义类不被视为异常,而是作为更全面的视觉解决方案中的集成(例如,主题中的图标颜色最好被视为encodings)。

      Material-UI 非常丰富,我鼓励您探索其他现有的customisation mechanisms

      【讨论】:

        【解决方案4】:

        我发现最简单的方法是使用以下方法。

        import { styled } from '@material-ui/styles';
        import { Visibility } from '@material-ui/icons';
        
        const MyVisibility = styled(Visibility)({
            color: 'white',
        });
        

        【讨论】:

          【解决方案5】:

          如下所示覆盖材质 UI 图标颜色

          在js中

                  const [activeStar, setActiveStar] = useState(false);
          
                  <IconButton onClick={() => setActiveStar(!activeStar)}>
                    {activeStar ? (
                      <StarOutlined className="starBorderOutlined" />
                    ) : (
                      <StarBorderOutlined />
                    )}
                  </IconButton>
          

          在 CSS 中

                .starBorderOutlined {
                  color: #f4b400 !important;
                 }
          

          【讨论】:

            【解决方案6】:

            您可以通过使用createMuiTheme() 创建custom theme 来为所有图标设置默认颜色:

            createMuiTheme({
              props: {
                MuiSvgIcon: {
                  htmlColor: '#aa0011',
                }
              }
            })
            

            这将为&lt;KeyboardArrowRightIcon/&gt; 等每个图标设置htmlColor 属性的默认值。这是您可以设置的list of other props

            【讨论】:

              【解决方案7】:

              这就是我的工作

              我使用 MUI v4.5.1。使用 color 属性 API 和 value 继承并添加一个 div 或 span 包装器并在那里添加你的颜色。

              来自 API 文档

              color 默认值:inherit。组件的颜色。它支持对这个组件有意义的主题颜色。

              添加星形图标

              import React from 'react';
              import Star from '@material-ui/icons/StarRounded';
              import './styles.css';
              
              export function FavStar() {
                return (
                  <div className="star-container">
                    <Star size="2em" fontSize="inherit" />
                  </div>
                );
              }
              

              在 style.css 中

              .star-container {
                color: red;
                font-size: 30px;
              }
              

              【讨论】:

                【解决方案8】:

                你可以这样做:&lt;PlusOne htmlColor="#ffaaee" /&gt;

                【讨论】:

                  【解决方案9】:

                  很惊讶,还没有人提出过网站范围的解决方案。

                  您可以在此处覆盖为“颜色”选项分配的颜色https://material-ui.com/api/icon/#props

                  通过向您的主题添加覆盖(如果您还没有定义自定义主题,则必须定义)https://material-ui.com/customization/theming/#createmuitheme-options-args-theme

                  定义主题后,就很简单了

                  const theme = createMuiTheme({
                    "overrides": {
                      MuiSvgIcon: {
                        colorPrimary: {
                          color: ["#625b5b", "!important"],
                        },
                        colorSecondary: {
                          color: ["#d5d7d8", "!important"],
                        },
                      },
                      ...
                  });
                  

                  【讨论】:

                  • 这种方法唯一的问题是您必须将颜色属性声明为“主要”才能使其工作,而不是覆盖默认颜色。您可以使用这种方法覆盖根颜色,但此时父母不会影响孩子。需要记住的一点。
                  【解决方案10】:

                  覆盖两个色调(TwoTone)图标的唯一正确解决方案是传递它的 htmColor 属性:

                  React.createElement(Icon, {htmlColor: "#00688b"})
                  

                  【讨论】:

                    【解决方案11】:

                    您可以使用SvgIcon,来自documentation

                    SvgIcon 组件将 SVG path 元素作为其子元素,并且 将其转换为显示路径的 React 组件,并允许 要设置样式并响应鼠标事件的图标。 SVG 元素应该 缩放为 24x24px 视口。

                    你必须使用devTools来提取KeyboardArrowRightIcon图标的路径:

                    然后将其与您的自定义颜色一起使用,如下所示:

                    <SvgIcon
                      component={svgProps => {
                        return (
                          <svg {...svgProps}>
                            {React.cloneElement(svgProps.children[0], {
                              fill: myColorVariable
                            })}
                          </svg>
                        );
                      }}
                    >
                       <path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"></path>
                    </SvgIcon>
                    

                    【讨论】:

                      【解决方案12】:

                      我遇到了同样的问题,我的解决方法是:

                      import React from 'react';
                      import pure from 'recompose/pure';
                      import {SvgIcon} from '@material-ui/core';
                      
                      let smile = (props) => (
                       <SvgIcon {...props}
                        component={props => {
                          return (
                            <svg {...props}>
                              {React.cloneElement(props.children[0], {
                                fill: "#4caf50"
                              })}
                            </svg>
                          );
                        }}
                      >
                         <path d="M256,32C132.281,32,32,132.281,32,256s100.281,224,224,224s224-100.281,224-224S379.719,32,256,32z M256,448
                                  c-105.875,0-192-86.125-192-192S150.125,64,256,64s192,86.125,192,192S361.875,448,256,448z M160,192c0-26.5,14.313-48,32-48
                                  s32,21.5,32,48c0,26.531-14.313,48-32,48S160,218.531,160,192z M288,192c0-26.5,14.313-48,32-48s32,21.5,32,48
                                  c0,26.531-14.313,48-32,48S288,218.531,288,192z M384,288c-16.594,56.875-68.75,96-128,96c-59.266,0-111.406-39.125-128-96"></path>
                      </SvgIcon>
                      );
                      smile = pure(smile);
                      smile.displayName = 'smile';
                      smile.muiName = 'SvgIcon';
                      
                      export default smile;
                      

                      【讨论】:

                        【解决方案13】:

                        Solution that works the best for myself:
                        
                        const EditableIcon = ({ icon, color, sx }: PropsWithChildren<EditableIconProps>) => {
                          const c = useIconStyles()
                          return React.cloneElement(icon, {
                            ...(color && { color }),
                            ...(sx && { sx }),
                            classes: {
                              colorPrimary: c.colorPrimary,
                              colorSecondary: c.colorSecondary,
                              colorAction: c.colorAction
                            }
                          })
                        }

                        如果设置了颜色,您的类将覆盖默认值。

                        【讨论】:

                          【解决方案14】:

                          只需在图标组件上添加样式

                          <KeyboardArrowRightIcon style={{color:"red"}} />
                          

                          但是你可以使用如下的条件样式

                              import React from "react";
                          import { makeStyles } from "@material-ui/core/styles";
                          import Icon from "@material-ui/core/Icon";
                          
                          const useStyles = makeStyles((theme) => ({
                            root: {
                              "& > span": {
                                margin: theme.spacing(2)
                              }
                            }
                          }));
                          
                          export default function Icons() {
                            //let we want chnage the icon color of
                            // somecontition varaiable is not empty
                            const somecontition = "some";
                            //here is some different style objects
                            const style = {  // old style object
                              color: "red"
                            };
                            const new_style = { //new style  object
                              color: "blue"
                            };
                            const classes = useStyles();
                          
                            return (
                              <div className={classes.root}>
                                {/* if somecondition var is not empty the use new_style other wise it will use old style*/}
                                <Icon style={somecontition ? style : new_style}>add_circle</Icon>
                              </div>
                            );
                          }
                          

                          【讨论】:

                            【解决方案15】:

                            您可以让您的风格充满活力。这是一个答案: stackoverflow answer

                            你应该小心你覆盖了什么

                            问候

                            【讨论】:

                              猜你喜欢
                              • 2020-02-17
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2016-11-24
                              • 2020-05-16
                              • 1970-01-01
                              • 1970-01-01
                              相关资源
                              最近更新 更多