ButtonLink

Interactive UI Explorer

아래에서 각 컴포넌트의 다양한 Variants States를 문서화된 형태로 테스트해볼 수 있습니다.

Live Preview
자세히 보기외부 사이트

ButtonLink

Link attributes mapped functionally to premium button designs.

Variants & Icons

Supported variants for the navigation button link.

Source Code
<ButtonLink href="#" variant="outline" iconDirection="left">이전 페이지</ButtonLink>
<ButtonLink href="#" variant="solid" iconDirection="right">다음 단계로</ButtonLink>
<ButtonLink href="#" variant="ghost" iconDirection="none">단순 텍스트 링크</ButtonLink>

Premium & Icon Only

Premium gradient styles and icon-only circle button variants.

Source Code
<ButtonLink href="#" variant="gradient" isIconOnly iconDirection="none">
  <PlusIcon className="h-4 w-4" />
</ButtonLink>

<ButtonLink href="#" variant="solid" isIconOnly iconDirection="none">
  <ArrowRightIcon className="h-4 w-4" />
</ButtonLink>
Live Preview
Implementation

제작 코드

이 컴포넌트가 실제로 어떻게 구현되어 있는지 — 본체 .tsx 파일을 그대로 보여줍니다. variant 매핑·접근성 처리·forwardRef 패턴 등 디테일을 그대로 확인할 수 있어요.

ButtonLinktypescript
import Link from "next/link";
import { cn } from "@/lib/cn";
import { AnchorHTMLAttributes } from "react";

export interface ButtonLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
  href: string;
  variant?: "outline" | "solid" | "ghost" | "gradient";
  iconDirection?: "left" | "right" | "none";
  isIconOnly?: boolean;
}

export function ButtonLink({
  href,
  variant = "outline",
  iconDirection = "left",
  isIconOnly = false,
  className,
  children,
  ...props
}: ButtonLinkProps) {
  return (
    <Link
      href={href}
      className={cn(
        "group inline-flex items-center justify-center transition-colors hover:cursor-pointer",
        !isIconOnly && "gap-2 rounded-xl px-4 py-2.5 text-sm font-semibold",
        isIconOnly && "size-9 rounded-full",
        variant === "outline" && "border border-slate-300 bg-white text-slate-700 hover:border-slate-400 hover:bg-slate-50 hover:text-slate-900",
        variant === "solid" && "bg-slate-900 text-white shadow-sm hover:bg-slate-800",
        variant === "ghost" && "bg-transparent text-slate-600 hover:bg-slate-100 hover:text-slate-900",
        variant === "gradient" && "bg-gradient-to-r from-violet-600 to-violet-500 text-white shadow-sm shadow-violet-500/20 hover:shadow-md hover:shadow-violet-500/25",
        className
      )}
      {...props}
    >
      {iconDirection === "left" && (
        <svg
          className="size-3.5 text-slate-400 transition-transform duration-300 group-hover:-translate-x-0.5 group-hover:text-current"
          fill="none"
          stroke="currentColor"
          viewBox="0 0 24 24"
        >
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
        </svg>
      )}
      {children}
      {iconDirection === "right" && (
        <svg
          className="size-3.5 text-slate-400 transition-transform duration-300 group-hover:translate-x-0.5 group-hover:text-current"
          fill="none"
          stroke="currentColor"
          viewBox="0 0 24 24"
        >
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M14 5l7 7m0 0l-7 7m7-7H3" />
        </svg>
      )}
    </Link>
  );
}