Как оформить React-иконки

Я пытаюсь понять, как стилизовать иконки, которые я импортирую, используя react-icons,

В частности, я хотел бы иметь возможность создать похожий на это:

То есть я хотел бы добавить цвет фона, отступы, границы и т. Д. Однако я не могу найти простой способ сделать это.

Я могу добавить опору размера и цвета, и это изменит фактический размер и цвет иконки. Но у меня нет простого способа изменить другие элементы.

Кто-нибудь знает, как я могу это сделать (или они могут порекомендовать другую библиотеку, которая может помочь мне в этом)?

13 ответов

Решение

Использование IconContext как упомянуто в Документах.

function BlueLargeIcon() {
  return (
    <IconContext.Provider
      value={{ color: 'blue', size: '50px' }}
    >
      <div>
        <FaBeer />
      </div>
    </IconContext.Provider>
  );
}

Кому это может быть полезно ...

Цвета некоторых значков изменить нельзя.
Например, я пытался изменить цвет { GrClose } значок, делая

      <GrClose
    className="icon"
    style={{
      position: 'absolute',
      top: '20px',
      right: '20px',
    }}
    size="50px"
    color="white"
    onClick={handleExit}
/>

Это просто не изменилось, когда я заменил свой значок на { AiOutlineClose } значок сработало!

Я думаю, что самый простой способ - просто передать опору прямо на иконку, к которой вы хотите применить стили. Исходный код в CodeSandbox. Я использовал tailwindcss классы здесь, но вы можете использовать свой собственный так же легко.

      import React from "react";
import "./styles.css";
import {
  FaFacebookF,
  FaTwitter,
  FaInstagram,
  FaPinterest
} from "react-icons/fa";

export default function App() {
  let circleClasses = "inline-block p-7 rounded-full w-20 mx-auto";
  let iconStyles = { color: "white", fontSize: "1.5em" };
  return (
    <div className="App grid grid-cols-2 sm:grid-cols-4 gap-2 w-3/4 mx-auto">
      <h1 className="col-span-full">Icon Demo</h1>
      <span style={{ background: "#3B5998" }} className={circleClasses}>
        <FaFacebookF style={iconStyles} />
      </span>
      <span style={{ background: "#1DA1F2" }} className={circleClasses}>
        <FaTwitter style={iconStyles} />
      </span>
      <span style={{ background: "black" }} className={circleClasses}>
        <FaInstagram style={iconStyles} />
      </span>
      <span style={{ background: "#BD081C" }} className={circleClasses}>
        <FaPinterest style={iconStyles} />
      </span>
    </div>
  );
}

Если вы хотите получить более подробную информацию о том, как это работает, мы можем погрузиться в исходный код для иконок реакции. Если вы посмотрите, в где IconContext определенreact -icons, вы увидите разрешенные свойства:

      export interface IconContext {
  color?: string;
  size?: string;
  className?: string;
  style?: React.CSSProperties;
  attr?: React.SVGAttributes<SVGElement>;
}

export const DefaultContext: IconContext = {
  color: undefined,
  size: undefined,
  className: undefined,
  style: undefined,
  attr: undefined,
};

export const IconContext: React.Context<IconContext> = React.createContext && React.createContext(DefaultContext);

Действительно, вы можете передавать цвет, размер, стиль, дополнительные атрибуты svg и даже строку className. Но это требует, чтобы вы обернули компонент Icon в контексте.

Когда вы устанавливаете response-icons, все значки добавляются в каталог node_modules в следующем формате:

      // THIS FILE IS AUTO GENERATED
var GenIcon = require('../lib').GenIcon
module.exports.Fa500Px = function Fa500Px (props) {
  return GenIcon({"tag":"svg","attr":{"viewBox":"0 0 448 512"},"child":[{"tag":"path","attr":{"d":"M103.3 344.3c-6.5-14.2-6.9-18.3 7.4-23.1 25.6-8 8 9.2 43.2 49.2h.3v-93.9c1.2-50.2 44-92.2 97.7-92.2 53.9 0 97.7 43.5 97.7 96.8 0 63.4-60.8 113.2-128.5 93.3-10.5-4.2-2.1-31.7 8.5-28.6 53 0 89.4-10.1 89.4-64.4 0-61-77.1-89.6-116.9-44.6-23.5 26.4-17.6 42.1-17.6 157.6 50.7 31 118.3 22 160.4-20.1 24.8-24.8 38.5-58 38.5-93 0-35.2-13.8-68.2-38.8-93.3-24.8-24.8-57.8-38.5-93.3-38.5s-68.8 13.8-93.5 38.5c-.3.3-16 16.5-21.2 23.9l-.5.6c-3.3 4.7-6.3 9.1-20.1 6.1-6.9-1.7-14.3-5.8-14.3-11.8V20c0-5 3.9-10.5 10.5-10.5h241.3c8.3 0 8.3 11.6 8.3 15.1 0 3.9 0 15.1-8.3 15.1H130.3v132.9h.3c104.2-109.8 282.8-36 282.8 108.9 0 178.1-244.8 220.3-310.1 62.8zm63.3-260.8c-.5 4.2 4.6 24.5 14.6 20.6C306 56.6 384 144.5 390.6 144.5c4.8 0 22.8-15.3 14.3-22.8-93.2-89-234.5-57-238.3-38.2zM393 414.7C283 524.6 94 475.5 61 310.5c0-12.2-30.4-7.4-28.9 3.3 24 173.4 246 256.9 381.6 121.3 6.9-7.8-12.6-28.4-20.7-20.4zM213.6 306.6c0 4 4.3 7.3 5.5 8.5 3 3 6.1 4.4 8.5 4.4 3.8 0 2.6.2 22.3-19.5 19.6 19.3 19.1 19.5 22.3 19.5 5.4 0 18.5-10.4 10.7-18.2L265.6 284l18.2-18.2c6.3-6.8-10.1-21.8-16.2-15.7L249.7 268c-18.6-18.8-18.4-19.5-21.5-19.5-5 0-18 11.7-12.4 17.3L234 284c-18.1 17.9-20.4 19.2-20.4 22.6z"}}]})(props);
};

Если мы посмотрим на исходный код, мы сможем получить немного больше контекста о том, как это работает.

      import * as React from 'react';

import { IconContext, DefaultContext } from './iconContext';

export interface IconTree {
  tag: string;
  attr: {[key: string]: string};
  child: IconTree[];
}


function Tree2Element(tree: IconTree[]): React.ReactElement<{}>[] {
  return tree && tree.map((node, i) => React.createElement(node.tag, {key: i, ...node.attr}, Tree2Element(node.child)));
}
export function GenIcon(data: IconTree) {
  return (props: IconBaseProps) => (
    <IconBase attr={{...data.attr}} {...props}>
      {Tree2Element(data.child)}
    </IconBase>
  );
}

export interface IconBaseProps extends React.SVGAttributes<SVGElement> {
  children?: React.ReactNode;
  size?: string | number;
  color?: string;
  title?: string;
}

export type IconType = (props: IconBaseProps) => JSX.Element;
export function IconBase(props:IconBaseProps & { attr?: {} }): JSX.Element {
  const elem = (conf: IconContext) => {
    const {attr, size, title, ...svgProps} = props;
    const computedSize = size || conf.size || "1em";
    let className;
    if (conf.className) className = conf.className;
    if (props.className) className = (className ? className + ' ' : '') + props.className;

    return (
      <svg
        stroke="currentColor"
        fill="currentColor"
        strokeWidth="0"
        {...conf.attr}
        {...attr}
        {...svgProps}
        className={className}
        style={{ color: props.color || conf.color, ...conf.style, ...props.style}}
        height={computedSize}
        width={computedSize}
        xmlns="http://www.w3.org/2000/svg"
      >
      {title && <title>{title}</title>}
      {props.children}
    </svg>
    )
  };

  return IconContext !== undefined
    ? <IconContext.Consumer>{(conf: IconContext) => elem(conf)}</IconContext.Consumer>
    : elem(DefaultContext);
}

Итак, это функция, которая принимает объект с интерфейсом IconTree, который включает tag, attr а также childхарактеристики. Мы можем увидеть это в действии в сгенерированном выше коде. GenIconвозвращает саму функцию. Эта функция принимает реквизиты в качестве аргумента, реализующего интерфейс. В IconBaseProps интерфейс расширяется React.SVGAttributes который включает в себя className а также style. Затем они передаются здесь как свойства компонента:

      export function GenIcon(data: IconTree) {
  return (props: IconBaseProps) => (
    <IconBase attr={{...data.attr}} {...props}>
      {Tree2Element(data.child)}
    </IconBase>
  );
}

Чтобы понять, как на самом деле работает функция, давайте посмотрим на ее оператор return:

          return IconContext !== undefined
    ? <IconContext.Consumer>{(conf: IconContext) => elem(conf)}</IconContext.Consumer>
    : elem(DefaultContext);

Здесь мы видим, что в любом случае вызывается вызываемая функция (определенная внутри тела). Итак, будет использовать, если он определен, заключая возвращаемый элемент в IconContext.Consumerи звонит с помощью. Но если IconContext не определен в этой области, будет использоваться DefaultContext вместо.

Чтобы понять, как это работает, нам нужно взглянуть на elem функция, определенная внутри IconBase. Вот снова полный исходник:

        const elem = (conf: IconContext) => {
    const {attr, size, title, ...svgProps} = props;
    const computedSize = size || conf.size || "1em";
    let className;
    if (conf.className) className = conf.className;
    if (props.className) className = (className ? className + ' ' : '') + props.className;

    return (
      <svg
        stroke="currentColor"
        fill="currentColor"
        strokeWidth="0"
        {...conf.attr}
        {...attr}
        {...svgProps}
        className={className}
        style={{ color: props.color || conf.color, ...conf.style, ...props.style}}
        height={computedSize}
        width={computedSize}
        xmlns="http://www.w3.org/2000/svg"
      >
      {title && <title>{title}</title>}
      {props.children}
    </svg>
    )
  };

Итак, если вы посмотрите на код, относящийся к className, вы увидите, что мы действительно можем добавить className в Context и / или props напрямую ( <FaFacebook className="bg-blue" />), и они будут фактически объединены и применены к возвращаемым

          let className;
    if (conf.className) className = conf.className;
    if (props.className) className = (className ? className + ' ' : '') + props.className;

Кроме того, стили, определенные в контексте или в свойствах, будут объединены и применены к svg.

       style={{ color: props.color || conf.color, ...conf.style, ...props.style}}

Здесь следует отметить, что все стили и классы применяются непосредственно к возвращаемому svgэлемент. Итак, в вашем случае вам, вероятно, понадобится элемент обертывания, чтобы создать радиус границы и цвет фона, а затем применить соответствующие стили для цвета и размера непосредственно к svg.

Просто добавьте свойство "цвет" к

Как это:

      <Icon color="blue" />

Вы можете сделать это, просто добавив свойство цвета к значку, то же самое касается других свойств, таких как размер.

<BiXCircle size={40} color="red" />
import {IconContext} from "react-icons";

class App extends component {

return (

<div>
<IconContext.Provider value={{ className="myReact-icons"}}>
       <FaBeer />
  </IconContext.Provider>
</div>
);  
}

css example below

.myreact-icons { color: red;
                 height: 40px;
               }

Есть более простой способ изменить цвет значка реакции. Вы можете выбрать все внутри значка svg с помощью .icon > * используйте CSS fill чтобы заполнить путь svg.

```
.icon > * {
    fill: #B3B3B3;
}

.icon > *:hover {
    fill: #747474;
}
```

      <HiOutlineInformationCircle
size= {40}
color="#777C92"
className = "m-1 cursor-pointer hover: stroke-[#E5765D]"
/>

Изменения цвета значков люверсов не применяются. Вы можете попробовать с другими, передав класс и нацелив его с помощью css, или непосредственно внутри <IconExample color={'blue'} />

Вы можете экспортировать их как объект(ы) с другими свойствами и сопоставлять их.

      import { FaInstagram, FaTwitter } from 'react-icons/fa';

export const socialIcons = [
    {
        icon: <FaInstagram
            style={{ height: '30px', width: '30px' }}
        />,
        title: 'Instagram',
        link: '',
        color: '#C13584',
        isOpen: false,
        id: 'instagram',
    },
    {
        icon: <FaTwitter
        style={{ height: '30px', width: '30px' }}/>,
        title: 'Twitter',
        link: '',
        color: '#00acee',
        isOpen: false,
        id: 'twitter',
    },
];

      import { socialIcons } from '../';

// ...
        <div>
            {socialIcons.map((social) => (
                <div>
                    <a href={social.link}>
                        <button style={{ color: social.color }}
                        id={social.id}>
                            {social.icon}
                        </button>
                    </a>
                </div>
            ))}
        </div>
      It is so easy just capsule your **icon** in **span tag**

            <div className="social-icons">
              <span>
                <FaGithub/>
              </span>
            </div>

then style it using **CSS**

.social-icons span{
    margin: 10px;
    font-size: 20px;          
    color: var(--grey);        
}
         
.social-icons span:hover{
    color:black
}
      function blackReactIcons () {
     return(
             <div>
                 <FaTwitter fill='#000' />
                 <FaLinkedinIn fill='#000' />
                 <FaGithub fill='#000' />
             </div>

        );
}                

В ваших стилях.scss или css

Другие вопросы по тегам