/ components / ui / button.tsx
button.tsx
 1  import * as React from "react"
 2  import { Slot } from "@radix-ui/react-slot"
 3  import { cva, type VariantProps } from "class-variance-authority"
 4  
 5  import { cn } from "@/lib/utils"
 6  
 7  const buttonVariants = cva(
 8    "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
 9    {
10      variants: {
11        variant: {
12          default:
13            "bg-primary text-primary-foreground shadow hover:bg-primary/90",
14          destructive:
15            "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
16          outline:
17            "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
18          secondary:
19            "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
20          ghost: "hover:bg-accent hover:text-accent-foreground",
21          link: "text-primary underline-offset-4 hover:underline",
22        },
23        size: {
24          default: "h-9 px-4 py-2",
25          sm: "h-8 rounded-md px-3 text-xs",
26          lg: "h-10 rounded-md px-8",
27          icon: "h-9 w-9",
28        },
29      },
30      defaultVariants: {
31        variant: "default",
32        size: "default",
33      },
34    }
35  )
36  
37  export interface ButtonProps
38    extends React.ButtonHTMLAttributes<HTMLButtonElement>,
39      VariantProps<typeof buttonVariants> {
40    asChild?: boolean
41  }
42  
43  const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
44    ({ className, variant, size, asChild = false, ...props }, ref) => {
45      const Comp = asChild ? Slot : "button"
46      return (
47        <Comp
48          className={cn(buttonVariants({ variant, size, className }))}
49          ref={ref}
50          {...props}
51        />
52      )
53    }
54  )
55  Button.displayName = "Button"
56  
57  export { Button, buttonVariants }