skip to Main Content

So, I’m using nextjs + svgr + tailwind in my app.

I’m dynamically changing size and color of my svgs, but I also want to add "flex-shrink-0 fill-current" globally to all my icons.

I want to render my icon with:

<AlertIcon className="text-red size-5" /> 

and to be sure it would also have "flex-shrink-0 fill-current" applied to it.

2

Answers


  1. Chosen as BEST ANSWER

    Yup, I simply added Icon component and put all logic there

    src/components/Icon.tsx

    import { twMerge } from "tailwind-merge";
    
    import * as icons from "@/icons";
    
    export type IconType = keyof typeof icons;
    
    type Props = {
      icon: IconType;
      className?: string;
    };
    
    export default function Icon(props: Props) {
      const { className, icon } = props;
    
      const IconComponent = icons[icon];
    
      return (
        <IconComponent
          className={twMerge("flex-shrink-0 fill-current", className)}
        />
      );
    }
    
    Icon.displayName = "Icon";
    

    src/icons/index.ts

    export { default as add } from "./add.svg";
    export { default as alert } from "./alert.svg";
    export { default as arrowLeft } from "./arrowLeft.svg";
    

    Icon render

    ....
    <Icon icon="add" className="size-6 text-blue" />
    ...
    

  2. You could try adding a wrapper component around the icons and pass the size and color down as explicit props, along with whichever icon you wish to render.

    Then in your SVG file, remove any fill or stroke attributes so Tailwind can modify those with classes. See Tailwind SVGs

    interface IconWrapperProps {
      color: string;
      size: string;
      children: any;
    }
    
    const IconWrapper: React.FC<IconWrapperProps> = ({color, size, children}) {
      return (
        <div className={`${color} ${size} flex-shrink-0`} >
          {children}
        </div>
      )
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search