[myBudget] React icon component
이전 프로젝트에서 SASS로 작업 할때는 아이콘 폰트를 만들어 활용했다.
리액트 프로젝트에서는 아이콘을 어떻게 사용하나 찾아보니 다양한 방법들이 있었다.
FontAwesome
웹에서 아이콘이 필요할때 사용하는 라이브러리 (일부 유료)react-icons
리액트 프로젝트에서 빠르게 아이콘을 사용하고 싶을때 활용
하지만 나는 만들어놓은 아이콘 셋이 있기 때문에 svg 활용하는 방법을 찾아봤다.
크기나 색상등을 편하게 수정해서 사용할 수 있도록
svg파일을 컴포넌트화시켜서 활용하는 방법이 제일 좋을 것 같았다.
SVG 파일 추가 및 수정
피그마에서 아이콘 svg파일을 받아 src/assets/svg
경로에 저장했다.
그리고 svg파일 내의 width, height 는 current
로, path 태그 내 fill 값은 currentColor
로 수정했다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<svg
width="current"
height="current"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g id="menu">
<path
id="Union"
fill-rule="evenodd"
clip-rule="evenodd"
d="M2 6C2 5.44772 2.44772 5 3 5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H3C2.44772 7 2 6.55228 2 6ZM2 12C2 11.4477 2.44772 11 3 11H21C21.5523 11 22 11.4477 22 12C22 12.5523 21.5523 13 21 13H3C2.44772 13 2 12.5523 2 12ZM3 17C2.44772 17 2 17.4477 2 18C2 18.5523 2.44772 19 3 19H21C21.5523 19 22 18.5523 22 18C22 17.4477 21.5523 17 21 17H3Z"
fill="currentColor"
/>
</g>
</svg>
export ReactComponenet
저장한 svg파일을 바로 활용할 곳에서 import해 사용할수도 있지만
여러개의 아이콘을 한번에 export 하기위해 src/assets/svg
경로에 index.ts
파일을 만든다.
1
2
3
4
export { ReactComponent as menu } from "./menu.svg";
export { ReactComponent as close } from "./close.svg";
export { ReactComponent as edit } from "./edit.svg";
// ...
svg 타입 정의
export 하고나면 svg 타입을 지정하라는 타입스크립트 에러가 생긴다.
Cannot find module './menu.svg' or its corresponding type declarations.ts(2307)
같은 경로에 svg.d.ts
파일을 생성해 아래 코드를 추가하고
1
2
3
4
5
6
7
declare module '*.svg' {
import React = require('react');
export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
const src: string;
export default src;
}
타입스크립트 컴파일러가 인식할 수 있게 tsconfig.json
의 include에 만든 파일 경로를 추가한다.
1
2
3
{
"include": ["src", "src/components", "src/assets/avg/svg.d.ts"]
}
Icon 컴포넌트 생성
svg의 사이즈나 속성을 쉽게 변경하기 위해 Icon 컴포넌트를 만든다.
src/component
경로에 Icon.tsx
파일 생성 후 각 속성의 타입과 기본값을 정의했다.
svg파일에서 사이즈와 컬러값을 current로 수정해두었기 때문에
props 처럼 원하는 값을 넘겨줄 수 있다.
어떤 종류의 아이콘을 사용할지는 키값으로 받아와 필수 prop으로 사용하도록 만든다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import React, { ReactElement } from 'react';
import * as icons from '../assets/svg';
export type IconType = keyof typeof icons;
export const iconTypes: IconType[] = Object.keys(icons) as IconType[];
export interface IconProps {
type: IconType;
color?: string;
size?: string | number;
}
const NORMAL_SIZE = '24px';
const NORMAL_COLOR = '#3D434B';
function Icon({ type, color, size }: IconProps): ReactElement {
const SVGIcon = icons[type];
const fillColor = color || NORMAL_COLOR;
const widthPx =
(size &&
(typeof size === 'number'
? `${size}px`
: `${size.replace('px', '')}px`)) ||
NORMAL_SIZE;
return (
<SVGIcon
style=
/>
);
}
export default Icon;
사용할 컴포넌트에서 아이콘 import
아이콘을 사용할 컴포넌트에서 아래와 같이 import해 다른 컴포넌트와 동일한 방식으로 사용할 수 있다.
1
2
3
4
5
6
7
8
9
import Icon from "./Icon";
function App() {
return (
<div>
<Icon type="menu" />
</div>
);
}
icon 속성이 필수임을 에러로 표시해주고 타입도 추천해준다
컬러와 사이즈는 기본값을 지정해두었기 때문에, 필요한 경우에만 수정하면 된다.
Leave a comment