6. Global Style
keyword
Reset CSS
box-sizing
속성word-break
속성Theme
ThemeProvider
Reset CSS
styled-reset 편하다.
import { Reset } from "styled-reset";
export default function App() {
return (
<>
<Reset />
<GlobalStyle />
<Greeting />
</>
);
}
간편하게 reset과 global style을 잡아줄 수 있다.
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
html {
font-size: 62.5%;
}
body {
font-size: 1.6rem;
}
:lang(ko) {
h1, h2, h3 {
word-break: keep-all;
}
}
`;
export default GlobalStyle;
Theme
디자인 시스템의 근간을 마련하는데 활용. 잘 정의하면 다크 모드 등에 대응하기 쉬움. 눈에 보이는 단편적인 정보를 넘어서, “의미”에 집중할 수 있게 됨.
일단 기본 Theme부터 정의.
const defaultTheme = {
colors: {
background: "#FFF",
text: "#000",
primary: "#F00",
secondary: "#00F",
},
};
export default defaultTheme;
// App.tsx
import { ThemeProvider } from "styled-components";
import { Reset } from "styled-reset";
import defaultTheme from "./styles/defaultTheme";
import GlobalStyle from "./styles/GlobalStyle";
export default function App() {
return (
<ThemeProvider theme={defaultTheme}>
<Reset />
<GlobalStyle />
<Greeting />
</ThemeProvider>
);
}
props.theme을 활용
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
body {
background: ${(props) => props.theme.colors.background};
color: ${(props) => props.theme.colors.text};
}
a {
color: ${(props) => props.theme.colors.text};
}
button,
input,
select,
textarea {
background: ${(props) => props.theme.colors.background};
color: ${(props) => props.theme.colors.text};
}
`;
export default GlobalStyle;
타입 문제를 해결하기 위해 styled.d.ts 파일 작성.
import 'styled-components';
declare module 'styled-components' {
export interface DefaultTheme extends Theme {
colors: {
background: string;
text: string;
primary: string;
secondary: string;
}
}
}
타입을 정의하고 defaultTheme을 맞추는 게 불편하니, 반대로 defaultTheme에서 타입을 추출하자.
import defaultTheme from "./defaultTheme";
type Theme = typeof defaultTheme;
export default Theme;
타입 파일 변경
import 'styled-components';
import Theme from './Theme';
declare module 'styled-components' {
export interface DefaultTheme extends Theme {}
}
다른 theme을 추가할 때 Theme 타입을 사용. 항상 defaultTheme에 먼저 항목을 추가/삭제하고, 나머지를 여기에 맞추면 된다.
어떤 프로퍼티가 빠지고 추가됐는지 알 수 있다.
import Theme from "./Theme";
const darkTheme: Theme = {
colors: {
background: "#000",
text: "#FFF",
primary: "#F00",
secondary: "#00F",
},
};
export default darkTheme;
의미를 명확히 드러냈다면, 다크 모드를 지원하는 것도 쉽다.
import { useDarkMode } from "usehooks-ts";
import { ThemeProvider } from "styled-components";
import { Reset } from "styled-reset";
import defaultTheme from "./styles/defaultTheme";
import darkTheme from "./styles/darkTheme";
import GlobalStyle from "./styles/GlobalStyle";
import Greeting from "./components/Greeting";
import Button from "./components/Button";
export default function App() {
const { isDarkMode, toggle } = useDarkMode();
const theme = isDarkMode ? darkTheme : defaultTheme;
return (
<ThemeProvider theme={theme}>
<Reset />
<GlobalStyle />
<Greeting />
<Button onClick={toggle}>Dark Theme Toggle</Button>
</ThemeProvider>
);
}
Jest 테스트 쪽에서 “window.matchMedia” 문제 발생.
// src/setupTests.ts
Object.defineProperty(window, "matchMedia", {
writable: true,
value: jest.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // deprecated
removeListener: jest.fn(), // deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});
Last updated