CVA, 재사용 컴포넌트를 만들 수 있는

박희수·2023년 11월 13일
0

CVA란? (class-variance-authority)

전통적인 CSS 접근 방식으로는 스타일 출력을 완전히 제어하기 어렵기 때문에, 보다 간편한 방법으로 UI를 정의할 수 있게 도와주는 라이브러리이다.

예시로 알아보기

import { cva } from "class-variance-authority";
 
const button = cva("button", {
  variants: {
    intent: {
      primary: "button--primary",
      secondary: "button--secondary",
    },
    size: {
      small: "button--small",
      medium: "button--medium",
    },
  },
  compoundVariants: [
    { intent: "primary", size: "medium", class: "button--primary-small" },
  ],
  defaultVariants: {
    intent: "primary",
    size: "medium",
  },
});
 
button();
// => "button button--primary button--medium"
 
button({ intent: "secondary", size: "small" });
// => "button button--secondary button--small"

위 코드는 공식 문서에 나와있는 예시이다.
intent와 size의 값에 따라 다른 디자인을 보여줄 수 있도록 구성되어 있다.
cva 첫번째 인자에는 모든 경우 공통으로 들어갈 css를 입력하게 된다. 만약 없다면 '' 비워두어도 된다.
두번째 인자에서부터 조건에 따른 객체를 넣어주면 된다.

여기서 나오는 cn은 무엇인가?

cva를 사용하기 전, tailwind 사용자들은 tailwind를 merge할 때 클래스 충돌 문제가 생길수도 있다.

만약, cva 없이 재사용 컴포넌트를 만들었다면 ?

const Button = () => {
         <button
            className={`
              ${
              intent == 'primary ? 'button--primary' : 'secondary' : button--secondary: button--secondary
                size == 'small'
                  ? 'mt-[20px] h-[27px] w-[120px] rounded-[13px] text-[10px]'
                  : 'big'
                  ? 'mt-[20px] h-[30px] w-[140px] rounded-[12px] text-[12px]'
                  : 'mt-[20px] h-[30px] w-[140px] rounded-[14px] text-[12px]'
              }  `}
          >
            확인
          </button>
}

이런식으로 구현했어야 할 것이다.
cva로 구현한 것에 비해 jsx에서 많은 조건들이 붙게 되고, 조건마다 스타일이 점점 길어져서 코드의 가독성이 많이 떨어지는 것으로 보인다.

profile
프론트엔드 개발자입니다 :)

0개의 댓글