Global Style & Theme

Global Style

์ „์—ญ์œผ๋กœ ์Šคํƒ€์ผ์„ ์ง€์ •

createGlobalStyle

์ „์—ญ ์Šคํƒ€์ผ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํŠน๋ณ„ํ•œ ์Šคํƒ€์ผ๋“œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ—ฌํผ ํ•จ์ˆ˜

์ผ๋ฐ˜์ ์ธ ์Šคํƒ€์ผ๋“œ ์ปดํฌ๋„ŒํŠธ๋Š” ์ž๋™์œผ๋กœ ํด๋ž˜์Šค ๋ฒ”์œ„๊ฐ€ ์ง€์ •๋˜์–ด ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๋กœ๋ถ€ํ„ฐ ๊ฒฉ๋ฆฌ๋˜์ง€๋งŒ createGlobalStyle ์€ ์ด๋Ÿฌํ•œ ์ œํ•œ์ด ์—†์–ด์„œ ์ „์—ญ ์Šคํƒ€์ผ๋ง์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์ „์—ญ ์Šคํƒ€์ผ์— reset css๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ดˆ๊ธฐํ™”๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

The 62.5% Font Size Trick

// styles/GlobalStyle.ts
import { createGlobalStyle } from 'styled-components';
import reset from 'styled-reset';

const GlobalStyle = createGlobalStyle`
  ${reset}
  html {
    box-sizing: border-box;
  }

  *,
  *::before,
  *::after {
    box-sizing: inherit;
  }

  html {
  // ๋ธŒ๋ผ์šฐ์ €์˜ ํฐํŠธ ํฌ๊ธฐ ์„ค์ •๊ณผ ์—ฐ๋™๋˜๋Š” rem ๋‹จ์œ„๋ฅผ ์‚ฌ์šฉ,
  // rem ๋‹จ์œ„๋ฅผ ๊ณ„์‚ฐํ•˜๊ธฐ ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ๊ธฐ๋ณธ ํฐํŠธ๋ฅผ 62.5%(10px)๋กœ ์„ค์ •ํ•œ๋‹ค.
    font-size: 62.5%; // 10px, (100% === 16px)
  }

  body {
    font-size: 1.6rem;
  }

  :lang(ko) {
  // ํ•œ๊ธ€๋กœ ์ž‘์„ฑ๋œ ์š”์†Œ ์ค‘ ํ—ค๋”ฉ ํƒœ๊ทธ์— ์˜๋„์น˜ ์•Š์€ ์ค„๋ฐ”๊ฟˆ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์„ค์ •
    h1, h2, h3 {
      word-break: keep-all;
    }
  }
`;

export default GlobalStyle;

Reset CSS๋ž€ ๋ธŒ๋ผ์šฐ์ €์— ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ค์ •๋œ ์Šคํƒ€์ผ์„ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.

Install

Usage

Theme

๋””์ž์ธ ์‹œ์Šคํ…œ ์ „์ฒด์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ƒ‰์ƒ, ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ, ์•„์ด์ฝ˜ ๋“ฑ์˜ ๋””์ž์ธ ์š”์†Œ์˜ ์ง‘ํ•ฉ

ํ…Œ๋งˆ๋ฅผ ์ •์˜ํ•  ๋•Œ ๋””์ž์ธ ์‹œ์Šคํ…œ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ปฌ๋Ÿฌ ํŒ”๋ ˆํŠธ, ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ, ๊ฐ„๊ฒฉ ๋“ฑ์„ ํ† ํฐ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ , ์ด๋ฅผ ์ด์šฉํ•ด์„œ ๋””์ž์ธ ์‹œ์Šคํ…œ ์ „์ฒด์˜ ์ผ๊ด€์„ฑ ์žˆ๋Š” ๋””์ž์ธ์„ ์œ ์ง€ํ•˜๊ณ  ์ž‘์—…์˜ ํšจ์œจ์„ฑ์„ ๋†’ํžŒ๋‹ค.

๋””์ž์ธ ํ† ํฐ(token)์ด๋ž€ ๋””์ž์ธ ์š”์†Œ์˜ ์†์„ฑ ๊ฐ’์„ ๋ณ€์ˆ˜ํ™”ํ•˜์—ฌ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ์‹

Token Naming

๋ˆˆ์— ๋ณด์ด๋Š” ๋‹จํŽธ์ ์ธ ์ •๋ณด๋ฅผ ๋„˜์–ด์„œ, โ€œ์˜๋ฏธโ€์— ์ง‘์ค‘

๋””์ž์ธ ์‹œ์Šคํ…œ ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ํ† ํฐ์˜ ๋””์ž์ธ ์˜๋„์™€ ์‚ฌ์šฉ๋ฒ•์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ค‘์š”ํ•˜๋‹ค.

์ด๋Ÿฌํ•œ ์ฒ ํ•™์€ ์˜๋„์— ๋”ฐ๋ฅธ ๋””์ž์ธ์„ ๊ฐ€๋Šฅ์ผ€ ํ•œ๋‹ค.

์ปฌ๋Ÿฌ ํ† ํฐ์„ ์˜ˆ๋กœ ๋“ค๋ฉด ์ƒ‰์ƒ ๊ฐ’์— ์–ฝ๋งค์ด์ง€ ์•Š๊ณ  ์˜๋„๊ฐ€ ๋” ์ž˜ ๋‹ด๊ธด ์ถ”์ƒํ™”๋œ ๋„ค์ด๋ฐ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค,

์ถ”ํ›„ ์ƒ‰์ƒ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋Š” ์ƒํ™ฉ์ด ์ƒ๊ฒจ๋„ ์ฝ”๋“œ ๋ณ€๊ฒฝ์ด ์‰ฝ๊ณ , ์œ ์ง€๋ณด์ˆ˜์„ฑ์ด ๋†’๋‹ค.

ํ•˜์ง€๋งŒ ์–ด๋–ค ๊ฒฝ์šฐ๋Š” ์˜๋„๊ฐ€ ๋‹ด๊ธด ๋„ค์ด๋ฐ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜๋„ ์žˆ๋‹ค. ์ค‘์š”ํ•œ๊ฑด ์ผ๊ด€์„ฑ๊ณผ ๊ฐ€๋…์„ฑ์ด๋‹ค.

Theme Provider

์Šคํƒ€์ผ๋“œ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ œ๊ณต๋˜๋Š” ThemeProvider๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ Context API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž์‹๋“ค์—๊ฒŒ ํ…Œ๋งˆ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

ํ…Œ๋งˆ ํƒ€์ž… ์„ ์–ธ ๋ณ‘ํ•ฉ

์Šคํƒ€์ผ ์ปดํฌ๋„ŒํŠธ ํƒ€์ž… ์ •์˜ ํŒŒ์ผ์— ์„ ์–ธ๋œ ํ…Œ๋งˆ ์ธํ„ฐํŽ˜์ด์Šค ํƒ€์ž…์„ ์‚ฌ์šฉ์ž๊ฐ€ ๋งŒ๋“  ํ…Œ๋งˆ์˜ ํƒ€์ž…์œผ๋กœ ํ™•์žฅํ•˜๋ ค๋ฉด, ์„ ์–ธ ๋ณ‘ํ•ฉ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

์‚ฌ์šฉ์ž๊ฐ€ ์ •์˜ํ•œ ํ…Œ๋งˆ์—์„œ ์—ญ์œผ๋กœ ํƒ€์ž…์„ ์ถ”์ถœํ•ด์„œ ํ™•์žฅํ•˜๋ฉด ํŽธ-ํ•˜๋‹ค.

styled.d.ts

ํƒ€์ž… ์†์„ฑ์„ ํ™•์žฅํ•˜๋Š” ๊ฒƒ์„ ์„ ์–ธ ๋ณ‘ํ•ฉ(declaration merging)์ด๋ผ ํ•œ๋‹ค. ๊ฐ™์€ interface๋ฅผ ์žฌ์„ ์–ธ ํ•จ์œผ๋กœ์จ ํƒ€์ž… ์†์„ฑ์„ ์ถ”๊ฐ€์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. โ†’ ๋ณด๊ฐ•

.d.ts๋Š” TypeScript์—์„œ ํƒ€์ž… ์ •์˜(type definition)๋ฅผ ์œ„ํ•œ ํŒŒ์ผ ํ™•์žฅ์ž,

declare module์€ Typescript์—์„œ ์™ธ๋ถ€ ๋ชจ๋“ˆ์— ๋Œ€ํ•œ ํƒ€์ž… ์„ ์–ธ์„ ์ œ๊ณตํ•˜๋Š” ๊ตฌ๋ฌธ

DarkMode ๊ตฌํ˜„ํ•˜๊ธฐ

ํ…Œ๋งˆ๋ฅผ ๊ฐˆ์•„๋ผ์šฐ๋Š” ์‹์œผ๋กœ ๋‹คํฌ๋ชจ๋“œ๋ฅผ ๊ตฌํ˜„ ๊ฐ€๋Šฅ

useDarkTheme

jest 'window.matchMedia' ์˜ค๋ฅ˜

jest์—์„œ ์‚ฌ์šฉ๋˜๋Š” jsdom์—์„œ ๊ตฌํ˜„๋˜์ง€ ์•Š์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

์ด ๊ฒฝ์šฐ ๋ชจํ‚น์„ ํ†ตํ•ด ํ•ด๊ฒฐ์ด ๊ฐ€๋Šฅํ•˜๋‹ค

setupTests.ts

Last updated