vanila-extract

with Typescript

CSSProperties

ํ‘œ์ค€ CSS ์†์„ฑ๋“ค์˜ ์ •ํ™•ํ•œ ํƒ€์ž…๋“ค์„ ์ œ๊ณต

import { CSSProperties } from '@vanila-extract/css'

export type StyleProps = {
  align?: CSSProperties['textAlign'],
  decoration?: CSSProperties['textDecoration'],
  ...,
}
  • CSS ์†์„ฑ์— ์–ด๋–ค ๊ฐ’์ด ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ TypeScript ์ˆ˜์ค€์—์„œ ์ •ํ™•ํ•˜๊ฒŒ ๋ณด์žฅํ•ด์ฃผ๋Š” ํƒ€์ž…๋“ค์„ ์ œ๊ณต

Packages

vanilla-extract๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ •์  ๋นŒ๋“œ์ด์ง€๋งŒ, emotion์˜ style props์ฒ˜๋Ÿผ ๋Ÿฐํƒ€์ž„์— ๋™์ ์œผ๋กœ ์Šคํƒ€์ผ ๊ฐ’์„ ๋ฐ”๊ฟ€ ์ˆ˜์žˆ๋Š” ๊ธฐ๋Šฅ๋“ค์„ ์ œ๊ณต

clsx

  • ์—ฌ๋Ÿฌ className๋“ค์„ ์กฐํ•ฉํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

๋™์ ? ์ •์ ?

  • css-in-js๋Š” ๋Ÿฐํƒ€์ž„์— ์Šคํƒ€์ผ์„ ๊ณ„์‚ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์Šคํƒ€์ผ์„ ์ž์œ ๋กญ๊ฒŒ ํ™•์žฅํ•˜๊ฑฐ๋‚˜ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜๊ธฐ์— ์œ ์—ฐํ•จ

    • ๋ณดํ†ต ์Šคํƒ€์ผ์„ ์ž์œ ๋กญ๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(Chakra๋‚˜ MUI)๋“ค์„ ๋ณด๋ฉด ๋‚ด๋ถ€์ ์œผ๋กœ emotion ๊ฐ™์€ css-in-js๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Œ

    • ๋Ÿฐํƒ€์ž„ ์Šคํƒ€์ผ ๊ณ„์‚ฐ ๋ฐฉ์‹๋•Œ๋ฌธ์— ์œ ์—ฐํ•˜๊ฒŒ ์Šคํƒ€์ผ์„ ํ™•์žฅ๊ฐ€๋Šฅํ•œ ๊ฒƒ

  • ๋ฐ˜๋ฉด, vanilla-extract๋Š” ์ •์  CSS๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ์‹์ด๋ผ ๋ฏธ๋ฆฌ ์ •์˜๋œ ์กฐํ•ฉ ์•ˆ์—์„œ๋งŒ ์Šคํƒ€์ผ์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๊ณ , ํ™•์žฅ์ด๋‚˜ ์˜ค๋ฒ„๋ผ์ด๋“œ๋Š” ํด๋ž˜์Šค๋„ค์ž„ ๋‹จ์œ„๋กœ ์ œํ•œ๋จ

    • ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ์‚ฌ์ „์— ํด๋ž˜์Šค ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•ด ์ •์ ์œผ๋กœ ์ƒ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ

    • ์ด๋Ÿฐ ์ƒํ™ฉ์—์„œ ํ™•์žฅ์„ฑ ์žˆ๊ฒŒ ์ž์œ ๋กญ๊ฒŒ ์Šคํƒ€์ผ์„ ์ปค์Šคํ…€ํ•˜๋ ค๋ฉด ๊ฒฐ๊ตญ style ์†์„ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜๋ฐ–์— ์—†์Œ

    • ๋‹ค๋งŒ, style์€ ์ธ๋ผ์ธ ์Šคํƒ€์ผ์ด๊ธฐ ๋•Œ๋ฌธ์— className์œผ๋กœ ์ ์šฉํ•œ ์Šคํƒ€์ผ๋ณด๋‹ค ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์Œ

    • ์ฆ‰, ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์Šคํƒ€์ผ ๋ฎ์–ด์“ฐ๊ธฐ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ฃผ์˜ํ•ด์•ผํ•จ

Sprinkles

์Šคํƒ€์ผ ๊ฐ’๋“ค์„ ๋ฏธ๋ฆฌ ์„ ์–ธํ•ด์„œ ์ƒ์„ฑํ•ด๋‘๊ณ  css์˜ ํด๋ž˜์Šค๋ฅผ ๋ฐ”๊ฟ”์„œ ๋™์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋Š”๊ฒƒ์ฒ˜๋Ÿผ ๋™์ž‘

npm install @vanilla-extract/sprinkles

depineProperties

์‚ฌ์šฉํ•˜๊ณ ์žํ•˜๋Š” ์Šคํƒ€์ผ ๊ฐ’(properties)๋“ค์„ ๋ฏธ๋ฆฌ ์„ ์–ธ

  • ํ”„๋กœํผํ‹ฐ์— ํ—ˆ์šฉ๋˜๋Š” ๊ฐ’๋“ค์„ ๋ฏธ๋ฆฌ ์ •์˜ํ•ด ๋‘๊ณ , ์Šคํƒ€์ผ ์ž‘์„ฑ ์‹œ ์–ด๋–ค ๊ฐ’๋“ค์ด ๊ฐ€๋Šฅํ•œ์ง€ ํƒ€์ž…๊ณผ ํ•จ๊ป˜ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ด€๋ฆฌ ๊ฐ€๋Šฅ

  • ์กฐ๊ฑด์— ๋”ฐ๋ฅธ ๊ฐ’๋“ค์„ ๋ถ„๊ธฐ ๊ฐ€๋Šฅ (๋ฐ˜์‘ํ˜•, ๋‹คํฌ๋ชจ๋“œ ๋“ฑ)

  • shorthands : ์ •์˜ํ•ด๋‘” ๊ฐ’๋“ค์„ ํ•˜๋‚˜์˜ ์ถ•์•ฝ ํ‚ค์›Œ๋“œ๋กœ ๋ฌถ์–ด์„œ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ฒŒ ํ•ด์ค„ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ

import { defineProperties, createSprinkles } from '@vanila-extract/sprinkles';

const responsiveProperties = defineProperties({
  // ๋ฐ˜์‘ํ˜• ์กฐ๊ฑด
  conditions: {
    mobile: {},
    tablet: { '@media': 'screen and (min-width: 768px)' },
    desktop: { '@media': 'screen and (min-width: 1024px)' },
  },
  defaultCondition: 'mobile',
  
  /* ex: ๋‹คํฌ๋ชจ๋“œ
  conditions: {
    lightMode: {},
    darkMode: { '@media': '(prefers-color-scheme: dark)' }
  }
  defaultCondition: 'lightMode'
  */

  
  properties: {
    paddingTop: {
      none: 0,
      xs: '4px',
      sm: '6px',
      md: '8px',
    },
    ...
  },
  shorthands: {
    padding: ['paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight']
  }
})

export const sprinkles = createSprinkles(
  responsiveProperties,
  //...etc,
);

// It's a good idea to export the Sprinkles type too
export type Sprinkles = Parameters<typeof sprinkles>[0];

Usage

className: clsx(sprinkles(props), props.className) 

Recipes

์—ฌ๋Ÿฌ ์Šคํƒ€์ผ ๋ณ€ํ˜•(variants)์„ ์ฒด๊ณ„์ ์œผ๋กœ ๊ตฌ์„ฑํ•  ๋•Œ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ

npm install @vanilla-extract/recipes
  • ๋ฒ„ํŠผ์ฒ˜๋Ÿผ ๋‹ค์–‘ํ•œ ์ƒํƒœ (color, size, variants)๋ฅผ ์กฐํ•ฉํ•ด์„œ ๊ด€๋ฆฌํ•ด์•ผํ•  ๋•Œ ์œ ์šฉ

  • props๋ฅผ ๋ฐ›์•„ ์ž๋™์œผ๋กœ ๋Œ€์‘๋˜๋Š” ์Šคํƒ€์ผ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์คŒ

  • ๋นŒ๋“œ ๋‹จ๊ณ„์—์„œ ์Šคํƒ€์ผ ์กฐํ•ฉ์˜ ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๋ฏธ๋ฆฌ ๊ณ„์‚ฐํ•ด CSS ํด๋ž˜์Šค๋กœ ๋ณ€ํ™˜

  • ๋Ÿฐํƒ€์ž„์—์„œ๋Š” props์— ๋”ฐ๋ผ ํ•ด๋‹น ํด๋ž˜์Šค๋งŒ ๊ต์ฒดํ•ด ์ ์šฉ๋Š”์‹์œผ๋กœ, ๋งˆ์น˜ ๋™์ ์œผ๋กœ ์Šคํƒ€์ผ์ด ์ ์šฉ๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋™์ž‘

import { recipes } from '@vanila-extract/recipes';

export const styles = recipes({
  variants: {
    size: {
      xs: {},
      sm: {},
      md: {},
    },
  },
  defaultVariants: {
    size: 'xs',
  } 
})

Last updated