简体   繁体   English

如何将样式应用于一组 SVG 元素

[英]How to apply style to an array of SVG elements

I have an array of .svg icons, where each icon has some properties which I need to override:我有一组.svg图标,其中每个图标都有一些我需要覆盖的属性:

<svg width="24" height="24" viewBox="0 0 24 24"> ... </svg>
import styled from 'styled-components';

import Github from 'assets/github.svg';
import Facebook from 'assets/facebook.svg';
import Twitter from 'assets/twitter.svg';
...

const icons = [
  <Github />,
  <Facebook />,
  <Twitter />,
  ...
];

I would like to apply the same styling for each icon without duplicating code and using CSS-in-JS .我想为每个图标应用相同的样式,而无需重复代码和使用CSS-in-JS

My solution so far has some issues:到目前为止,我的解决方案有一些问题:

// Works but,
// I want to use CSS-in-JS like styled-components
// for easier maintenance
const iconStyle = {
  width: 50,
  height: 50
};

const SocialBar = () => (
  <IconBar as={FlexBox}>
    {icons.map((icon, key) => (
      <div key={key}>{React.cloneElement(icon, iconStyle)}</div>
    ))}
  </IconBar>
);
// Works but,
// there are too many icons
const SocialBar = () => (
  <IconBar as={FlexBox}>
    <Github style={iconStyle} />
    <Facebook style={iconStyle} />
    ...
  </IconBar>
);

And styling svg component like this won't work:像这样的样式svg组件将不起作用:

// Won't override the width="24" height="24" properties
const StyledIcon = styled(Github)`
  width: 50;
  height: 50;
`;

You can wrap the SVG with an element (like an i ) and style any svg children inside of it with some CSS defined within a styled-component (you can also target g and path as well).您可以用一个元素(如i )包裹 SVG 并使用在样式组件中定义的一些 CSS 为其中的任何svg子项设置样式(您也可以以gpath为目标)。 Unfortunately, SVGs are pretty tricky to work with, so you may need to manually copy/paste the SVG xml into a JS file (if you're using the CRA , you can import a ReactComponent from an SVG ).不幸的是,SVG 使用起来非常棘手,因此您可能需要手动将 SVG xml 复制/粘贴到 JS 文件中(如果您使用的是CRA ,则可以从 SVG导入ReactComponent )。

Working example (copy/pasted SVG into JS file -- 1st example is the default, 2nd example passes in props, 3rd example passes in multiple props):工作示例(将 SVG 复制/粘贴到 JS 文件中——第一个示例是默认值,第二个示例传入 props,第三个示例传入多个 props):

编辑样式化 SVG 组件


Icon/Icon.js (this component accepts a styled component generated className and any children placed inside of it)图标/ Icon.js(此组件接受生成的风格的部件className和任何children放在它里面)

import React from "react";
import PropTypes from "prop-types";

const Icon = ({ className, children }) => (
  <i className={className}>{children}</i>
);

Icon.propTypes = {
  className: PropTypes.string.isRequired,
  children: PropTypes.node.isRequired
};

export default Icon;

Icon/index.js (this will style the Icon component above; and, subsequently it will style the children ) Icon/index.js (这将为上面的Icon组件设置样式;随后它将为children组件设置样式)

import styled from "styled-components";
import Icon from "./Icon";

const StyledIcon = styled(Icon)`
  margin: 0 20px;
  svg {
    fill: ${({ fill }) => fill || "#03a9f3"};
    height: ${({ dimension }) => dimension || "50px"};
    width: ${({ dimension }) => dimension || "50px"};
  }
`;

export default StyledIcon;

This is one way of doing it.这是一种方法。

//Github.js
import React from "react";
export default function Github({height, width}) {
    return (
        <svg width={width} height={height} viewBox="0 0 24 24"> ...  </svg>
    );
}

Then where you want to use it.然后你想在哪里使用它。

<Github height={24} width={24} />

I'm not entirely sure what your request is, relative to the code samples you already have.相对于您已有的代码示例,我不完全确定您的要求是什么。 Are you trying to avoid using React.cloneElement ?你想避免使用React.cloneElement吗? Make the array of icons as functions, instead of a jsx element.将图标数组作为函数,而不是 jsx 元素。 map over it to the jsx version and apply the styles to each mapmap到 jsx 版本并将样式应用于每个

const icons = [
  Github,
  Facebook,
  Twitter,
]

buildIcons() {
  const style = {
    //..
  }
  return icons.map((icon, idx) => (
    <icon style={style} key={idx}/>
  ))

}

Using index as the key works, but if you can find a different property that is unique to each icon, it'd be better.使用索引作为键是可行的,但如果您能找到每个图标独有的不同属性,那就更好了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM