TASIOMIND.DEV — OPERATIONAL▸▸▸FULL STACK DEVELOPER @ GWQ SERVICEPLUS AG▸▸▸FOUNDER — K8SGPT.AI▸▸▸OPEN SOURCE: ACTIVE▸▸▸DISTRIBUTED SYSTEMS / KUBERNETES / AI▸▸▸RUST + GO + PYTHON▸▸▸FIELD TESTED / STATUS — NOMINAL▸▸▸LOCATION: EUROPE/BERLIN▸▸▸TASIOMIND.DEV — OPERATIONAL▸▸▸FULL STACK DEVELOPER @ GWQ SERVICEPLUS AG▸▸▸FOUNDER — K8SGPT.AI▸▸▸OPEN SOURCE: ACTIVE▸▸▸DISTRIBUTED SYSTEMS / KUBERNETES / AI▸▸▸RUST + GO + PYTHON▸▸▸FIELD TESTED / STATUS — NOMINAL▸▸▸LOCATION: EUROPE/BERLIN▸▸▸

SVG Icon System in React

June 27, 2019

SVG as Image

code
import React from "react";
import logo from "./logo.svg"; // Tell Webpack this JS file uses this svg

console.log(logo); // /logo.84287d09.svg

function Header() {
  // Import result is the URL of your image
  return <img src={logo} alt="Logo" />;
}

export default Header;

SVG as a React component

You can import an SVG as a React Component. This has been supported since Create React App 2.0 (react-scripts@2.0.0 and react@16.3.0)

code
import { ReactComponent as MyIcon } from "./icon.svg";
export { MyIcon };
code
import { ReactComponent as Logo } from "./logo.svg";
const App = () => (
  <div>
    {/* Logo is an actual React component */}
    <Logo className="App-logo" alt="logo" />
  </div>
);

Don't forget the curly braces in the import! The ReactComponent import name is special and tells Create React App that you want a React component that renders an SVG, rather than its filename.

A ReactComponent SVG will show as inline <svg> when rendered. You can now use all the CSS magic.

code
.App-logo g {
  fill: red;
}

.App-logo path {
  stroke: palegoldenrod;
  stroke-width: 10px;
  fill: none;
  stroke-dasharray: 35px 15px;
  animation: orbit 1s infinite linear;
}

@keyframes orbit {
  to {
    sroke-dashoffset: 50px;
  }
}

SVG with Props

To be continued.. Will probably have to leave the .svg files and add the paths in a .jsx file so we could use props

Case for converting SVGs into React components

  • Theming. You can change the color of all icons when you change the theme. But i'd argue you can do that with CSS as well
code
// wrapping SVGs in theme-able components
import styled from "styled-components";
import theme from "styled-theming";

export const backgroundColor = theme("mode", {
  light: "#fafafa",
  dark: "#0e0f11",
});
const LogoWrapper = styled.div`
  svg {
    fill: ${backgroundColor};
  }
`;