cva란?
cva는 class-variance-authority 라이브러리의 함수로, 조건부로 CSS 클래스 이름을 생성하고, 일관성 있는 UI 정의와 관리를 하기 위해 사용된다
이 라이브러리는 다양한 변형(variants)을 정의하고, 이러한 변형을 기반으로 동적으로 클래스 이름을 생성할 수 있게 한다
이를 통해 CSS 클래스 이름을 조합하고 조건부로 적용하는 작업을 간편하게 처리할 수 있다!
cva(baseStyle, {option})
먼저 코드를 보면
const buttonVariant = cva("rounded border font-semibold hover:brightness-90 active:brightness-75", {
variants: {
intent: {
primary: "bg-blue-500 text-white border-blue-500",
danger: "bg-red-500 text-white border-red-500",
},
size: {
sm: "px-3 py-1.5 text-sm",
md: "px-4 py-2 text-[15px]",
lg: "px-5 py-2.5 text-[17px]",
},
outline: {
true: "bg-white",
false: "",
},
},
compoundVariants: [
{ intent: "primary", outline: true, className: " !text-blue-500" },
{ intent: "danger", outline: true, className: "text-red-500" },
],
defaultVariants: {
intent: "primary",
size: "md",
outline: false,
},
});
1. baseStyle : string[] | string
공통적으로 사용될 baseStyle을 첫번째 인자에 작성한다
tailwindCSS처럼 단순 문자열로 넣어도 되고, 배열에 각각 넣어도 된다
2. option {}
option에는 3가지의 속성이 있다
- variants
- compoundVariants
- defaultVariants
variants {}
커스텀하여 사용할 속성을 적는다
variants에 작성한 특정 속성에 따라 CSS 클래스를 적용한다
여기서는 intent, size, outline을 변화 속성으로 사용했다
variants: {
intent: {
primary: "bg-blue-500 text-white border-blue-500",
danger: "bg-red-500 text-white border-red-500",
},
size: {
sm: "px-3 py-1.5 text-sm",
md: "px-4 py-2 text-[15px]",
lg: "px-5 py-2.5 text-[17px]",
},
outline: {
true: "bg-white",
false: "",
},
},
compoundVariants []
특정 조합의 변형에 따라 추가적인 클래스 이름을 정의한다
조합 안의 변형 조건이 충족될 때 적용된다
compoundVariants: [
{
intent: 'primary',
variant: 'contained',
className: 'bg-sky-500 ',
},
{
intent: 'primary',
variant: 'outline',
className: ' text-sky-500',
},
{
intent: 'secondary',
variant: 'contained',
className: 'bg-slate-500 ',
},
{
intent: 'secondary',
variant: 'outline',
className: ' text-slate-500',
},
{
intent: 'danger',
variant: 'contained',
className: 'bg-red-500 ',
},
{
intent: 'danger',
variant: 'outline',
className: ' text-red-500',
},
],
defaultVariants
속성을 명시하지 않았을 때 기본적으로 적용될 값을 정의한다
defaultVariants: {
intent: "primary",
size: "md",
outline: false,
},
최종적으로 코드는 다음과 같다
const buttonVariant = cva("rounded border font-semibold hover:brightness-90 active:brightness-75", {
variants: {
intent: {
primary: "bg-blue-500 text-white border-blue-500",
danger: "bg-red-500 text-white border-red-500",
},
size: {
sm: "px-3 py-1.5 text-sm",
md: "px-4 py-2 text-[15px]",
lg: "px-5 py-2.5 text-[17px]",
},
outline: {
true: "bg-white",
false: "",
},
},
compoundVariants: [
{ intent: "primary", outline: true, className: " !text-blue-500" },
{ intent: "danger", outline: true, className: "text-red-500" },
],
defaultVariants: {
intent: "primary",
size: "md",
outline: false,
},
});