import * as React from 'react'
import { cva, type VariantProps } from 'class-variance-authority'
import { cn } from '@/lib/utils'
const buttonVariants = cva(
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-[var(--radius)] text-sm font-medium transition-all duration-[var(--transition-base)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))] focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
{
variants: {
variant: {
default:
'bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] shadow-[var(--shadow-sm)] hover:bg-[hsl(var(--primary-hover))] hover:shadow-[var(--shadow)]',
destructive:
'bg-[hsl(var(--destructive))] text-[hsl(var(--destructive-foreground))] shadow-[var(--shadow-sm)] hover:bg-[hsl(var(--destructive))/0.9]',
outline:
'border border-[hsl(var(--border))] bg-[hsl(var(--background))] shadow-[var(--shadow-xs)] hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--accent-foreground))]',
secondary:
'bg-[hsl(var(--secondary))] text-[hsl(var(--secondary-foreground))] shadow-[var(--shadow-xs)] hover:bg-[hsl(var(--secondary))/0.8]',
ghost:
'hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--accent-foreground))]',
link: 'text-[hsl(var(--primary))] underline-offset-4 hover:underline',
success:
'bg-[hsl(var(--success))] text-[hsl(var(--success-foreground))] shadow-[var(--shadow-sm)] hover:bg-[hsl(var(--success))/0.9]',
},
size: {
default: 'h-9 px-4 py-2',
sm: 'h-8 rounded-[var(--radius-sm)] px-3 text-xs',
lg: 'h-10 rounded-[var(--radius-md)] px-8',
xl: 'h-12 rounded-[var(--radius-lg)] px-10 text-base',
icon: 'h-9 w-9',
'icon-sm': 'h-8 w-8',
'icon-lg': 'h-10 w-10',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
}
)
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
// If asChild is true, the first child will be rendered instead of a button
// For simplicity, we always render a button but pass down className
return (
<button
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
}
)
Button.displayName = 'Button'
export { Button, buttonVariants }