스타일 선언을 축약해주는 기능을 지원하는 vanilla-extract 패키지입니다.
Sprinkles는 런타임/컴파일 타임 상관 없이 모두 사용 가능합니다.
.css.ts에서 작성하는 모든 스타일 코드들은 컴파일 타임에서 빌드되는데요. 아래 작성한 sprinkles도 컴파일 타임에 css로 변환됩니다.
import { sprinkles } from './sprinkles.css.ts';
export const container = sprinkles({
display: 'flex',
paddingX: 'small',
flexDirection: {
mobile: 'column',
desktop: 'row'
},
background: {
lightMode: 'blue-50',
darkMode: 'gray-700'
}
});
내부족으로 style api를 사용하고 클래스 리스트를 반환하기 때문에 selector로도 사용할 수 있습니다.
export const container = sprinkles({
padding: 'small'
});
globalStyle(`${container} *`, {
boxSizing: 'border-box'
});
.css.ts에서 작성하지 않은 스타일은 런타임에 빌드됩니다.
import { sprinkles } from './sprinkles.css.ts';
const flexDirection =
Math.random() > 0.5 ? 'column' : 'row';
document.write(`
<section class="${sprinkles({
display: 'flex',
flexDirection
})}">
...
</section>
`);
defineProperties는 properties, conditions, shorhands라는 키 값을 받습니다.
const space = {
none: 0,
small: '4px',
medium: '8px',
large: '16px'
// etc.
};
const colors = {
blue50: '#eff6ff',
blue100: '#dbeafe',
blue200: '#bfdbfe'
// etc.
};
디자인 시스템에서 정의했거나 미리 적어놓고 사용하고 싶은 스타일을 object literal 형식으로 만들어 놓습니다.
const responsiveProperties = defineProperties({
conditions: {
mobile: {},
tablet: { '@media': 'screen and (min-width: 768px)' },
desktop: { '@media': 'screen and (min-width: 1024px)' }
},
defaultCondition: 'mobile',
properties: {
display: ['none', 'block', 'flex'],
flexDirection: ['row', 'column'],
padding: space
// etc.
}
});
반응형 페이지를 위해 responsiveProperties를 선언하겠습니다.
properties에 padding에는 space를 넣었는데요. 이 것은 sprinkles를 사용할 때 사용할 수 있는 padding의 값으로 0, 4, 8, 16px만 가능하게 한다는 말입니다.
즉, sprinkles에서 사용할 수 있는 display, flexDirection, padding의 값을 일부 값으로 제한한것입니다.
사용할 수 있는 css 속성 값을 정의합니다.
import { defineProperties } from '@vanilla-extract/sprinkles';
const responsiveProperties = defineProperties({
properties: {
display: ['none', 'block', 'flex'],
flexDirection: ['row', 'column'],
alignItems: [
'stretch',
'flex-start',
'center',
'flex-end'
],
justifyContent: [
'stretch',
'flex-start',
'center',
'flex-end'
]
// etc.
}
});
간단한 매핑은 배열을 사용할 수 있습니다.
import { defineProperties } from '@vanilla-extract/sprinkles';
const responsiveProperties = defineProperties({
properties: {
gap: {
none: 0,
small: 4,
medium: 8,
large: 16
}
// etc.
}
});
의미론적 매핑은 객체를 사용할 수 있습니다.
import { defineProperties } from '@vanilla-extract/sprinkles';
import { vars } from './vars.css.ts';
const responsiveProperties = defineProperties({
properties: {
gap: vars.space
// etc.
}
});
vanilla-extract에서 제공하는 themes를 사용할 수도 있습니다.
shorthands는 축약어를 선언하는 것입니다. paddingX, paddingY 등을 선언하는 데 유용합니다.
import { defineProperties } from '@vanilla-extract/sprinkles';
import { vars } from './vars.css.ts';
const responsiveProperties = defineProperties({
properties: {
paddingTop: vars.space,
paddingBottom: vars.space,
paddingLeft: vars.space,
paddingRight: vars.space
},
shorthands: {
padding: [
'paddingTop',
'paddingBottom',
'paddingLeft',
'paddingRight'
],
paddingX: ['paddingLeft', 'paddingRight'],
paddingY: ['paddingTop', 'paddingBottom']
}
});
conditions 제공된 속성에 대한 미디어/기능/컨테이너 쿼리 집합을 정의합니다.
import { defineProperties } from '@vanilla-extract/sprinkles';
const responsiveProperties = defineProperties({
conditions: {
mobile: {},
tablet: { '@media': 'screen and (min-width: 768px)' },
desktop: { '@media': 'screen and (min-width: 1024px)' }
},
defaultCondition: 'mobile'
// etc.
});
selectors로 지정할 수도 있습니다.
import { defineProperties } from '@vanilla-extract/sprinkles';
const properties = defineProperties({
conditions: {
default: {},
hover: { selector: '&:hover' },
focus: { selector: '&:focus' }
},
defaultCondition: 'default'
// etc.
});
말 그대로 기본 조건을 설정합니다.
import { defineProperties } from '@vanilla-extract/sprinkles';
const responsiveProperties = defineProperties({
conditions: {
mobile: {},
tablet: { '@media': 'screen and (min-width: 768px)' },
desktop: { '@media': 'screen and (min-width: 1024px)' }
},
defaultCondition: 'mobile'
// etc.
});
만약 조건이 상호 배타적인 경우 배열로 설정할 수 있습니다.
import { defineProperties } from '@vanilla-extract/sprinkles';
const responsiveProperties = defineProperties({
conditions: {
lightMode: {
'@media': '(prefers-color-scheme: light)'
},
darkMode: { '@media': '(prefers-color-scheme: dark)' }
},
defaultCondition: ['lightMode', 'darkMode']
// etc.
});
정의된 속성에 접근하기 위한 함수를 만듭니다.
import {
defineProperties,
createSprinkles
} from '@vanilla-extract/sprinkles';
const responsiveProperties = defineProperties({
/* ... */
});
const unconditionalProperties = defineProperties({
/* ... */
});
const colorProperties = defineProperties({
/* ... */
});
export const sprinkles = createSprinkles(
responsiveProperties,
unconditionalProperties,
colorProperties
);