

버튼 컴포넌트는 다양한 스타일과 기능을 필요로 하기 때문에 유연하게 만드는 것이 특히 중요합니다. 이번 블로그 포스트에서는 class-variance-authority (CVA) 라이브러리를 사용하여 !
애플리케이션에서 유연한 버튼 컴포넌트를 만드는 방법을 살펴보겠습니다.
class-variance-authority 설치
npm install class-variance-authority
버튼 컴포넌트를 작성할 때, CVA를 사용하여 다양한 스타일 옵션을 쉽게 정의할 수 있습니다. 아래는 그 예시입니다:
import { VariantProps, cva } from "class-variance-authority";
import Link from "next/link";
import { ComponentProps, PropsWithChildren } from "react";
const buttonVariant = cva("border rounded font-semibold transition hover:brightness-90 active:brightness-75", {
variants: {
intent: {
primary: "border-sky-500",
secondary: "border-slate-500",
danger: "border-red-500",
},
size: {
sm: "px-3 py-1 text-[13px]",
md: "px-4 py-1.5 text-[15px]",
lg: "px-5 py-2 text-[17px]",
},
variant: {
outline: "bg-white",
contained: "text-white",
},
},
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: {
intent: "primary",
size: "md",
variant: "contained",
},
});
type ButtonVariant = VariantProps<typeof buttonVariant>;
type ButtonProps = ButtonVariant & (({} & ComponentProps<"button">) | ({ href: string } & ComponentProps<typeof Link>));
function Button({ intent, size, variant, children, ...props }: PropsWithChildren<ButtonProps>) {
if ("href" in props) {
return (
<a className={buttonVariant({ intent, size, variant })} {...props}>
{children}
</a>
);
} else {
return (
<button className={buttonVariant({ intent, size, variant })} {...props}>
{children}
</button>
);
}
}
export default Button;
buttonVariant 객체를 사용하여 버튼의 다양한 스타일 옵션을 정의합니다. intent, size, variant 등의 변형을 설정할 수 있습니다.ButtonVariant 타입과 ButtonProps 타입을 정의하여 TypeScript에서 사용합니다.Button 컴포넌트를 작성하여, href 속성이 있으면 Link 컴포넌트를 사용하고, 그렇지 않으면 button 태그를 사용합니다.이와 같은 방식으로 버튼 컴포넌트를 유연하게 설정하면, 다양한 스타일과 기능을 쉽게 적용할 수 있습니다. CVA를 활용하여 복잡한 스타일링을 단순하게 관리해보았습니다.