Recipes는 컴포넌트의 다양한 상태와 변형을 체계적으로 관리하기 위한 스타일링 API 패턴이다.
-
base- 컴포넌트의 기본 스타일을 정의하는 속성
- 모든 변형에 공통적으로 적용되는 스타일을 정의
- CSS 변수를 활용하면 JavaScript를 통한 테마 변경이 용이
-
variants- 컴포넌트의 다양한 변형을 정의하는 속성
- 크기(size), 색상(color), 상태(state) 등 독립적인 스타일 변형을 그룹화
- 각 변형은 서로 조합 가능
-
compoundVariants- 여러 variant가 동시에 적용될 때의 특별한 스타일을 정의
- 복잡한 조건부 스타일링을 선언적으로 처리
- 조건문 없이도 세밀한 스타일 제어가 가능
-
defaultVariants- 컴포넌트의 기본 variant 값을 지정
- 명시적 지정이 없을 때 적용될 기본값 설정
예제: 버튼 컴포넌트
import { cva } from '../styled-system/css'
const button = cva({
// 기본 스타일
base: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: '4px',
transition: 'all 0.2s'
},
// 변형 스타일
variants: {
visual: {
solid: { bg: 'blue.500', color: 'white' },
outline: { borderWidth: '1px', borderColor: 'blue.500', color: 'blue.500' }
},
size: {
sm: { padding: '0.5rem 1rem', fontSize: '14px' },
md: { padding: '0.75rem 1.5rem', fontSize: '16px' },
lg: { padding: '1rem 2rem', fontSize: '18px' }
},
isDisabled: {
true: { opacity: 0.5, cursor: 'not-allowed' }
}
},
// 복합 변형 스타일
compoundVariants: [
{
visual: 'outline',
isDisabled: true,
css: {
borderStyle: 'dashed'
}
}
],
// 기본 변형 설정
defaultVariants: {
visual: 'solid',
size: 'md'
}
})
// 사용 예시
const Button = () => (
<button className={button({ visual: 'outline', size: 'lg', isDisabled: true })}>
Click me
</button>
)이 패턴은 Stitches에서 처음 대중화되었으며, 이후 vanilla-extract, Panda CSS, Chakra UI 등 다양한 스타일링 라이브러리에서 채택되었다. cva(Class Variance Authority)와 tailwind-variants를 통해 Utility-first 접근에도 유용하게 사용되고 있다.
초기 Recipes는 단일 컴포넌트(single slot)에 대한 스타일 변형만을 다루었으나, 복잡한 컴포넌트 구조를 효과적으로 관리하기 위해 여러 하위 요소(multi slot)의 스타일을 동시에 제어할 수 있는 형태로 발전했다.
참고
- Panda CSS - Atomic vs Config Recipes
- https://stitches.dev/docs/variants
- https://vanilla-extract.style/documentation/packages/recipes/
- https://panda-css.com/docs/concepts/recipes
- https://chakra-ui.com/docs/theming/recipes
- https://cva.style/docs/getting-started/variants
- https://www.tailwind-variants.org/docs/variants