이전에 디자이너, 기획자가 없이 혼자서 개발을 진행하다 보니 일관성이 떨어지는 문제가 있었다. 그래서 이번에는 그런 문제를 해결하기 위해 theme.tsx 파일을 만들어서 애플리케이션 전체에 걸쳐 사용될 공통 디자인을 먼저 설정하기로 했다.
theme.tsx 파일에는 컬러, 반응형 디자인에 필요한 장치별 크기, 폰트 등 전반적인 디자인 요소를 미리 지정해줬다. 폰트는 프로젝트가 진행되면서 추가해도 괜찮기 때문에 일단은 빈 상태로 뒀다.
/styles/theme.tsx
import { DefaultTheme } from 'styled-components';
const colors = {
mainColor: '#ffd55c',
mainColorDk: '#fbc62e',
mainColorLg: '#ffdd7b',
black: '#000000',
white: '#FFFFFF',
whitesmoke: '#F5F5F5',
} as const;
const deviceSizes = {
mobile: '390px',
tablet: '768px',
desktop: '1536px',
};
const devices = {
mobile: `screen and (min-width: ${deviceSizes.mobile})`,
tablet: `screen and (min-width: ${deviceSizes.tablet})`,
desktop: `screen and (min-width: ${deviceSizes.desktop})`,
} as const;
const fonts = {};
export type ColorsType = typeof colors;
export type DevisesType = typeof devices;
export const theme: DefaultTheme = {
colors,
devices,
};
타입을 명시하고 사용할 때 어떤 값이 있는지 알 수 있도록 theme.tsx 파일에서 각 객체의 타입을 생성했다.
그리고 DefaultTheme에는 방금 만든 theme 객체의 타입이 없기 때문에 인터페이스를 확장해야한다.
/styles/styled.d.ts
import 'styled-components';
import { ThemeType } from './theme';
import { ColorsType, DevisesType } from './theme';
declare module 'styled-components' {
export interface DefaultTheme {
colors: ColorsTypes;
devices: DevicesTypes;
}
}
사용할 때는 아래와 같이 작성하면 props.theme. 까지만 입력해도 자동으로 colors, devices 등이 나와서 어떤 값이 있는지 확인할 수 있고, 따라서 오타를 방지할 수 있다.
const Button = styled.button`
background-color: ${(props) => props.theme.colors.mainColor};
`