keyword
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(),
})),
});