47 lines
1.7 KiB
TypeScript
47 lines
1.7 KiB
TypeScript
import { forwardRef } from 'react'
|
|
import { cn } from '@/lib/utils'
|
|
import { type LucideIcon } from 'lucide-react'
|
|
|
|
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
variant?: 'primary' | 'secondary' | 'ghost' | 'danger'
|
|
size?: 'sm' | 'md' | 'lg'
|
|
icon?: LucideIcon
|
|
children: React.ReactNode
|
|
}
|
|
|
|
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
|
({ className, variant = 'primary', size = 'md', icon: Icon, children, ...props }, ref) => {
|
|
return (
|
|
<button
|
|
ref={ref}
|
|
className={cn(
|
|
// Base styles
|
|
'inline-flex items-center justify-center gap-2 rounded-xl font-medium transition-all duration-200',
|
|
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-background',
|
|
'disabled:opacity-50 disabled:cursor-not-allowed',
|
|
|
|
// Variants
|
|
variant === 'primary' && 'bg-foreground text-background hover:bg-foreground/90 hover:scale-[1.02] active:scale-[0.98]',
|
|
variant === 'secondary' && 'bg-background-card text-foreground hover:bg-background-elevated border border-border',
|
|
variant === 'ghost' && 'hover:bg-background-card',
|
|
variant === 'danger' && 'bg-danger hover:bg-danger/90 text-white',
|
|
|
|
// Sizes
|
|
size === 'sm' && 'px-3 py-1.5 text-sm',
|
|
size === 'md' && 'px-4 py-2 text-base',
|
|
size === 'lg' && 'px-6 py-3 text-lg',
|
|
|
|
className
|
|
)}
|
|
{...props}
|
|
>
|
|
{Icon && <Icon className="w-4 h-4" />}
|
|
{children}
|
|
</button>
|
|
)
|
|
}
|
|
)
|
|
|
|
Button.displayName = 'Button'
|
|
export default Button
|