class-variance-authority (cva) 사용법 간단 정리

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,
  },
});