이번 프로젝트에서 ThemeProvider
를 처음 알게되어 기록을 남긴다.
먼저 ThemeProvider란
말그대로 테마 스타일을 Provider로 설정해두고 각각의 컴포넌트에서 받아 사용하며, 전역에서 스타일을 관리할 수 있도록 해준다.
이번 프로젝트처럼 컴포넌트 수가 많을 때 공통적으로 관리하여 협업에 도움이 되고 재사용이 가능하여 효율적으로 사용할 수 있겠다고 생각했다.
순서
먼저 최상단 페이지인 _app.tsx
에 provider로 뿌려줄 공통 theme파일을 작성한다.
그 다음 각각의 컴포넌트에서 export한 theme파일을 import해온다.
필요한 속성 값에 theme props로 넘겨주어 설정한다.
base/Text 컴포넌트 어려웠던 부분
Text컴포넌트에서 Text는 동적으로 타입을 변환해 주어야하는데
const Tag = block ? "div" : paragraph ? "p" : "span";
emotion/styled
를 사용하여 스타일을 정의하면 태그로 사용해야하는데
const StyledText = styled.div<Props>``
const StyledText = styled.p<Props>``
const StyledText = styled.span<Props>``
위와 같이 styled 뒤에 태그 종류를 미리 설정해두면 정적타입이 되는 문제를 겪었다.
해결방법은
const Tag = block ? "div" : paragraph ? "p" : "span";
const StyledText = styled(Tag)<Props>``
결과
const Tag = block ? "div" : paragraph ? "p" : "span";
const StyledText = styled(Tag)<Props>`
font-size: ${({ theme }) =>
typeof size === "string" ? theme.fontSizes[size] :
`${size}px`};
// size?: number | "xs" | "sm" | "base" | "md" | "lg" | "xl";
color: ${({ theme }) => theme.colors.gray900};
//color가 없는 경우 gray900 이고,
color: ${color && color};
// css는 우선순위가 아래로 가기때문에 color가 있는 경우 color 보여줌
font-weight: ${strong && "bold"};
text-decoration: ${underline && "underline"};
`;
return (
<StyledText style={{ ...rest.style }} {...rest}>
{children}
</StyledText>
);
base/Icon 컴포넌트
const IconWrapper = styled.i<Pick<Props, "size" | "rotate">>`
display: inline-block;
${({ size, theme }) => css`
width: ${typeof size === "string" ? theme.iconSize[size] : size};
height: ${typeof size === "string" ? theme.iconSize[size] : size};
`}
Pick
를 사용하면 특정 타입(Props)에서 속성을 선택하여 타입을 정의할 수 있다.