TypeScript 97.5%
SQL 1.4%
Python 0.8%
1import * as React from "react";2import { Slot } from "@radix-ui/react-slot";3import { cva, type VariantProps } from "class-variance-authority";4import { Loader2 } from "lucide-react";5import { cn } from "@/lib/utils";67const buttonVariants = cva(8 "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[background-color,border-color,color,box-shadow,transform] duration-150 select-none disabled:pointer-events-none disabled:opacity-50 active:translate-y-px [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",9 {10 variants: {11 variant: {12 default: "bg-fg text-bg hover:bg-fg/90 shadow-xs",13 primary: "bg-accent text-accent-fg hover:brightness-110 shadow-xs",14 secondary: "bg-bg-muted text-fg hover:bg-border",15 outline: "border border-border bg-bg hover:bg-bg-subtle text-fg shadow-xs",16 ghost: "hover:bg-bg-muted text-fg-muted hover:text-fg",17 danger: "bg-danger text-white hover:brightness-110 shadow-xs",18 link: "text-accent underline-offset-4 hover:underline h-auto p-0",19 },20 size: {21 default: "h-9 px-3.5",22 sm: "h-8 px-3 text-[13px] rounded-md",23 xs: "h-7 px-2.5 text-xs rounded-sm",24 lg: "h-10 px-5 text-[15px] rounded-lg",25 icon: "size-9",26 "icon-sm": "size-8",27 },28 },29 defaultVariants: { variant: "default", size: "default" },30 },31);3233export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {34 asChild?: boolean;35 loading?: boolean;36}3738export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(({ className, variant, size, asChild = false, loading, children, disabled, ...props }, ref) => {39 if (asChild) {40 // Slot requires exactly one child element; the loader is not rendered in asChild mode.41 return (42 <Slot className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props}>43 {children}44 </Slot>45 );46 }47 return (48 <button className={cn(buttonVariants({ variant, size, className }))} ref={ref} disabled={disabled || loading} {...props}>49 {loading ? <Loader2 className="animate-spin" aria-hidden /> : null}50 {children}51 </button>52 );53});54Button.displayName = "Button";5556export { buttonVariants };57