기본 Variants
defaultVariants를 정해 두면, props를 생략해도 스타일이 적용된 컴포넌트를 얻을 수 있어요. 이 레시피에서는 언제 쓰면 좋은지, 흔히 빠지는 함정, 그리고 합리적인 기본값 패턴을 살펴봐요.
가장 흔한 경우를 기본값으로
코드베이스의 <Button> 호출 중 80%가 size: 'medium', color: 'primary'를 쓴다면, 그게 기본값이 돼야 해요.
ts
const button = ev({
variants: {
size: {
small: {},
medium: {},
large: {},
},
color: {
primary: {},
secondary: {},
danger: {},
},
},
defaultVariants: {
size: 'medium',
color: 'primary',
},
});
button(); // medium primary
button({ size: 'large' }); // large primary선택 props를 그대로 넘기기
기본값은 키 단위로 props[key] ?? defaultVariants[key]로 메워져요. 그래서 undefined와 null은 둘 다 기본값으로 떨어져요. 선택 prop을 따로 걸러내지 않고 variant 함수에 그대로 넘겨도 돼요.
tsx
type Props = {
size?: 'small' | 'medium' | 'large';
};
function Button({ size }: Props) {
// prop을 생략하면 size는 undefined지만, 'medium'이 그대로 적용돼요.
return <button css={button({ size })}>Click</button>;
}ts
button({ size: undefined }); // button()과 완전히 같아요 — medium primarynull도 런타임에서는 똑같이 기본값으로 떨어지지만, EvVariants 타입에는 null이 없어요. strictNullChecks에서는 nullable한 값을 넘기기 전에 undefined로 바꿔 줘야 해요.
그래서 defaultVariants가 있는데 prop 기본값({ size = 'medium' })까지 또 줄 필요는 없어요. 기본값은 한 곳에서만 선언하세요. 컴포넌트 밖에서 button()을 직접 부르는 경우까지 덮어 주는 쪽은 defaultVariants예요.
WARNING
false와 0은 유효한 variant 값이라서, 기본값으로 떨어지지 않고 그 값 그대로 쓰여요.
ts
const badge = ev({
variants: {
outlined: {
true: {
border: '1px solid',
},
false: {
border: 'none',
},
},
},
defaultVariants: {
outlined: true,
},
});
badge({ outlined: false }); // border: none. 기본값 `true` 스타일이 아니에요Boolean variant의 기본값
문자열 키 'true' / 'false'가 아니라 실제 Boolean true / false를 써요.
ts
const chip = ev({
variants: {
outlined: {
true: {
border: '1px solid',
},
false: {
border: 'none',
},
},
},
defaultVariants: {
outlined: false,
},
});
chip(); // false 스타일이 적용돼요복합 variant와도 잘 맞아요
기본값은 복합 매칭을 평가할 때 쓰일 variant 값으로도 들어가요.
ts
const button = ev({
variants: {
size: {
small: {},
large: {},
},
color: {
primary: {},
danger: {},
},
},
compoundVariants: [
{
variants: {
size: 'large',
color: 'primary',
},
style: {
fontWeight: 'bold',
},
},
],
defaultVariants: {
size: 'large',
color: 'primary',
},
});
button(); // 기본값이 복합 조건을 만족하므로 bold가 적용돼요