6. Global Style & Theme
Reset CSS
box-sizing
์์ฑword-break
์์ฑTheme
ThemeProvider
๊ฐ์ ์ ๋ฆฌ
Reset CSS
๋ธ๋ผ์ฐ์ ๋ค๋ง๋ค ์คํ์ผ์ด ์ ์ฉ๋๋ ๋ฐฉ๋ฒ์ด ๋ค ๋ฌ๋ผ์ ๋ชจ๋ ์คํ์ผ์ ์ด๊ธฐํํด๋๊ณ , 0๋ถํฐ ์์ํ๊ธฐ ์ํด Reset CSS๋ฅผ ์ฌ์ฉํ๋ค.
ํจํค์ง ์ค์น
npm i styled-reset
์ปดํฌ๋ํธ ํํ๋ก ์คํ์ผ์ ์ด๊ธฐํํด์ค ์ ์๋ค.
import { Reset } from 'styled-reset';
export default function App() {
return (
<>
<Reset />
<Greeting />
</>
);
}
styled-components์์ ์ ์ญ ์คํ์ผ์ ์ง์ ํ๋ ๋ฐฉ์
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;
Reset CSS์ ๋์ผํ๊ฒ App ์ปดํฌ๋ํธ์ ์ ์ฉํด์ค๋ค.
import { Reset } from 'styled-reset';
import GlobalStyle from './styles/GlobalStyle';
export default function App() {
return (
<>
<Reset />
<GlobalStyle />
<Greeting />
</>
);
}
Theme
๋์์ธ ์์คํ ์ ๊ทผ๊ฐ์ ๋ง๋ จํ๋๋ฐ ํ์ฉํ๋ค. React Context๋ฅผ ์ด์ฉํ์ฌ ๋ด๋ ค์ค๋ค.
const defaultTheme = {
colors: {
background: '#FFF',
text: '#000',
primary: '#F00',
secondary: '#00F',
},
};
export default defaultTheme;
ํ์ ์ ์ก์์ฃผ๋๊ฒ ์์ ์ ์ผ๋ก ์์ฑํ๊ธฐ์ ๋ ์ข๋ค.
const Theme = typeof defaultTheme;
export default Theme
App ์ปดํฌ๋ํธ์์ ThemeProvider๋ก ๊ฐ์ธ์ค๋ค.
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>
);
}
์ค์ ๋ก styled-components ๋ด๋ถ์์ theme์ ์ฌ์ฉํ๋ ค๊ณ ํ๋ฉด type์ ์ก์ง ๋ชปํ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋๋ฐ type์ ์ก์์ค์ผ ํ๋ค.
import 'styled-components';
import Theme from './Theme'
declare module 'styled-components' {
export interface DefaultTheme extends Theme {}
}
usehooks-ts๋ฅผ ์ด์ฉํ์ฌ ๋คํฌ๋ชจ๋ ์ง์ํ๊ธฐ.
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} isActive={isDarkMode}>
Dark Theme Toggle
</Button>
</ThemeProvider>
);
}
defaultTheme์ ํ๋ ์ก์๋๊ณ , ์ดํ๋ฆฌ์ผ์ด์ ์ ์ฒด์์ ์ฌ์ฉํ๋ฉด ๋๋ค.
Jest์์ window.matchMedia ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด matchMedia๋ฅผ ์ก์์ฃผ๋ฉด ๋๋ค.
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