Home > Net >  How to create custom reusable icon component in React.js
How to create custom reusable icon component in React.js

Time:06-20

I want to create component named <MyIcon name='iconName'/> which takes name of Icon as property.

I have few svg icons on my assets which i want to use to display on my component.

The idea behind it is to create union type for MyIcon component.

What i've tried:

Icon Component:

type MyIconProps = {
name: 'arrowIcon' | 'avatarIcon' | 'dashboardIcon'
}

const MyIcon = ({ name }: MyIconProps) => {
  return <img src={name} />;
};

export default MyIcon;

Icons with imports:

import arrowExpand from 'src/assets/images/arrow_expand.svg';
import avatar from 'src/assets/images/avatar.svg';
export const icons = [
  {
    name: 'arrowIcon',
    path: arrowExpand,
  },
  {
    name: 'avatarIcon',
    path: avatar,
  },
];

Could you tell me how i can apply those imported icons on my component?

CodePudding user response:

So in this case we have create Icons.js file in react where we can store icon svg path and icon name to use it another component

Icons.js

const Icons = ({ name, className }) => {

  switch (name) {
    case "menu":
      return <svg width="1.5em" height="1.5em" viewBox="0 0 25 16" className={className} fill="currentColor" xmlns="http://www.w3.org/2000/svg">
        <path fillRule="evenodd" clipRule="evenodd" d="M1.69698 2.66667C0.963647 2.66667 0.363647 2.06667 0.363647 1.33333C0.363647 0.6 0.963647 0 1.69698 0H23.0303C23.7636 0 24.3636 0.6 24.3636 1.33333C24.3636 2.06667 23.7636 2.66667 23.0303 2.66667H1.69698ZM1.69698 9.33321H15.0303C15.7636 9.33321 16.3636 8.73321 16.3636 7.99988C16.3636 7.26655 15.7636 6.66655 15.0303 6.66655H1.69698C0.963647 6.66655 0.363647 7.26655 0.363647 7.99988C0.363647 8.73321 0.963647 9.33321 1.69698 9.33321ZM1.69698 16.0001H23.0303C23.7636 16.0001 24.3636 15.4001 24.3636 14.6668C24.3636 13.9335 23.7636 13.3335 23.0303 13.3335H1.69698C0.963647 13.3335 0.363647 13.9335 0.363647 14.6668C0.363647 15.4001 0.963647 16.0001 1.69698 16.0001Z" />
      </svg>
  }
};

export default Icons;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

After that you can use this icon in another file using Import like

import Icons from './Icons';
  return (
    <div>
      <Icons name="menu"/>
    </div>
  )

this will work

CodePudding user response:

Import the svg file like this:

import { ReactComponent as NameOfYourSvg } from "./assets/images/arrowIcon.svg";

Apply object destructuring to access the name and the rest props from MyIcon props:

const { name, ...rest } = props;

Then create Icons object that holds all SVG components inside MyIcon component and pass the props into it

const Icons: Record<IconProps["name"], any> = {
    iconName: <IconTag {...rest} />,
    ...
};

And render the icon by name:

  return Icons[name];

And the complete code of your Icon component will be like this:

import { ReactComponent as ArrowIcon } from "./assets/images/arrowIcon.svg";
import { ReactComponent as AvatarIcon } from "./assets/images/avatarIcon.svg";
import { ReactComponent as DashboardIcon } from "./assets/images/dashboardIcon.svg";

type MyIconProps = {
  name: "arrowIcon" | "avatarIcon" | "dashboardIcon";
};

const MyIcon = (props: MyIconProps) => {
  const { name, ...svgProps } = props;

  const Icons: Record<IconProps["name"], any> = {
    avatarIcon: <AvatarIcon {...svgProps} />,
    arrowIcon: <ArrowIcon {...svgProps} />,
    dashboardIcon: <DashboardIcon {...svgProps} />,
  };

  return Icons[name];
};

export default MyIcon;

And you can use your icon like this:

  <Icon name="arrowIcon" />
  • Related