본문 바로가기
웹개발/리액트

ReactComponent를 통해 svg 를 컴포넌트처럼 사용하기

by 현댕5697 2021. 7. 24.
반응형

ReactComponent를 통해 svg 파일을 컴포넌트처럼 사용하면 fill 속성을 변경하여 svg 에셋의 색을 설정할 수 있다!

svg 파일 코드를 뜯어보면 다음과 같다

<svg width="100%" height="100%" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.9946 8.77393L17.9928 8.71843C17.9824 8.39083 17.7275 8.12324 17.4003 8.09707C15.5146 7.9459 14.0575 6.40491 14.0101 4.51196C14.002 4.17894 13.7407 3.90684 13.4082 3.88518C11.6068 3.76831 10.1651 2.38075 9.97964 0.586162C9.9467 0.267586 9.68453 0.0216596 9.3646 0.00902482C9.24367 0.00406117 9.12229 0 9 0C4.03725 0 0 4.03725 0 9C0 13.9627 4.03725 18 9 18C13.9627 18 18 13.9627 18 9C17.9995 8.92419 17.9973 8.84883 17.9946 8.77393ZM10.0338 8.97383C10.0338 9.54916 9.56766 10.0153 8.99233 10.0153C8.417 10.0153 7.95087 9.54916 7.95087 8.97383C7.95087 8.3985 8.417 7.93236 8.99233 7.93236C9.56766 7.93236 10.0338 8.3985 10.0338 8.97383ZM7.71396 5.15272C7.71396 5.72805 7.24783 6.19418 6.6725 6.19418C6.09717 6.19418 5.63104 5.72805 5.63104 5.15272C5.63104 4.57739 6.09717 4.11126 6.6725 4.11126C7.24783 4.11081 7.71396 4.57739 7.71396 5.15272ZM4.55437 8.57538C5.12971 8.57538 5.59584 9.04151 5.59584 9.61685C5.59584 10.1922 5.12971 10.6583 4.55437 10.6583C3.97904 10.6583 3.51291 10.1922 3.51291 9.61685C3.51291 9.04197 3.97904 8.57538 4.55437 8.57538ZM7.71396 13.4799C7.71396 12.9046 8.1801 12.4385 8.75543 12.4385C9.33076 12.4385 9.79689 12.9046 9.79689 13.4799C9.79689 14.0553 9.33076 14.5214 8.75543 14.5214C8.1801 14.5214 7.71396 14.0553 7.71396 13.4799ZM13.049 9.86413C13.6243 9.86413 14.0904 10.3303 14.0904 10.9056C14.0904 11.4809 13.6243 11.9471 13.049 11.9471C12.4737 11.9471 12.0075 11.4809 12.0075 10.9056C12.0075 10.3303 12.4737 9.86413 13.049 9.86413Z" fill="white"/>
</svg>

혹은

<svg width="100%" height="100%" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="10.9091" width="3" height="24" rx="1.5" fill="white"/>
<rect x="24" y="10.9091" width="3" height="24" rx="1.5" transform="rotate(90 24 10.9091)" fill="white"/>
</svg>

이런 형식이다.

첫번째 svg의 경우 색상을 바꾸는 방법은 다음과 같다.

import styled from "styled-components";
import { PlusIcon } from "@assets/icons/common";

const IconBox = () => {
  return (
        <Container class="icon_container">
          <PlusIcon className="plus_icon" />
        </Container>
  );
};

const Container = styled.div`
  width: 20px;
  height: 20px
  .plus_icon{
    width: 10px;
    height: 10px;
    path {
    	fill: #ffffff;
    }
  }
`;

이렇게 svg 컴포넌트에 className 속성을 지정한 후 css를 가지고 svg의 width, height, fill css 속성을 변경할 수 있다.

그런데 이렇게 svg를 컴포넌트처럼 사용할 경우 width, height 값을 변경하면 에셋이 깨진다는 문제가 있었다...

예를 들어 svg 기본 크기가 width = 24px, height = 24px 인데 width = 18px, height = 18px로 변경하고 싶은 경우 정상적으로 svg가 렌더링되지 않았다.

깨지는 svg...

 

❓ SVG 정리


svg를 이해하기 위해서는 viewport viewbox 개념을 이해해야 한다.

viewport

 svg가 보이는 영역이다. css를 통해 svg의 width, height를 변경할 경우 viewport의 너비, 높이가 변경된다.

viewbox

좌표와 가로, 세로의 비율을 결정하는 svg의 특성이다.

viewport < viewbox 인 경우 svg는 영역에 비해 축소되어 보이게 된다. 

viewport > viewbox 인 경우 svg는 영역에 비해 확대되어 보이게 된다.

 

만약  svg 기본 속성값이 width = 24px, height = 24px 라면 viewbox = 0 0 24 24 이라고 하자.

이때 css 속성을 변경하여 width = 18px, height = 18px로 설정하게 된다면 viewbox의 크기가 18px*18px로 변경되는 반면,  svg 아이콘의 절대적인 크기는 24px*24px로 그대로이기 때문에 아이콘이 잘리게 되는 것이다.

 

🎉 해결방법

내가 원하는 것은 img 태그를 사용하는 것처럼 비율 그대로 width, height만 줄어드는 것이었다. 

이를 위해서는 viewbox 값이 변경되어야 했는데, css를 통해서는 값을 변경할 수 없었다.

그래서 svg 파일을 열어 width=100%, height=100%로 속성값을 변경해주었다.

그랬더니 viewport 값에 상관없이 svg 컴포넌트에 width, height를 지정해준 값에 대해 일정한 비율로 맞춰지게 되었다!! 해결완료~~

 

21.08.05 추가


찾아보니까 svgr 웹팩을 설정할 때 viewbox 관련 설정을 옵션으로 넣어줄 수 있었다.

- next.js에 적용하기

// next.config.js
module.exports = {
  reactStrictMode: true,
  webpack(config, { dev, webpack }) {
    config.module.rules.push({
      test: /\.svg$/,
      use: [
      	{
        	loader: "@svgr/webpack",
            options: {
            	svgoConfig: { plugins: { removeViewBox: false } },
            }
        }
      ],
    });

    return config;
  },
};

- storybook에 적용하기

// .storybook/main.js
module.exports = {
  webpackFinal: async (config) => {
    config.module.rules.unshift({
      test: /\.svg$/,
      use: [
        {
          loader: "@svgr/webpack",
          options: {
            svgoConfig: { plugins: { removeViewBox: false } },
          },
        },
      ],
    });

    return config;
  },
};

이러면 svg 파일을 직접 수정하지 않고도 비율을 유지하면서 width, height 값을 조절할 수 있다.

반응형

댓글