import { forwardRef } from 'react' import type { ButtonHTMLAttributes, ReactNode } from 'react' import { Slot } from 'radix-ui' import { cva, type VariantProps } from 'class-variance-authority' import { cn } from '@/lib/utils' import { Spinner } from './spinner' const buttonVariants = cva( 'inline-flex items-center justify-center gap-1.5 font-medium transition-[color,background-color,border-color,box-shadow,transform] duration-200 active:scale-[0.98] focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-border focus-visible:ring-offset-2 focus-visible:ring-offset-bg-base disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer', { variants: { variant: { primary: 'bg-primary text-text-on-primary hover:bg-primary-hover', secondary: 'bg-bg-highlight text-text-on-primary hover:bg-bg-highlight-hover', tertiary: 'bg-fill-secondary text-text hover:bg-fill', outline: 'border border-border-tertiary bg-bg-container text-text hover:bg-fill-secondary', ghost: 'bg-transparent text-text-secondary hover:bg-fill-secondary hover:text-text', text: 'bg-transparent text-text-secondary hover:text-text', destructive: 'bg-error text-text-on-primary hover:bg-error-hover', }, size: { sm: 'h-[var(--control-height-sm)] px-[var(--control-padding-x-sm)] text-[length:var(--control-font-size-sm)] leading-[var(--control-line-height-sm)]', md: 'h-[var(--control-height-md)] px-[var(--control-padding-x-md)] text-[length:var(--control-font-size-md)] leading-[var(--control-line-height-md)]', lg: 'h-[var(--control-height-lg)] px-[var(--control-padding-x-lg)] text-[length:var(--control-font-size-lg)] leading-[var(--control-line-height-lg)]', }, rounded: { square: 'rounded', pill: 'rounded-full', }, textOnly: { true: 'h-auto px-[var(--control-text-padding-x)] py-[var(--control-text-padding-y)]', false: '', }, }, compoundVariants: [ { variant: 'text', className: 'px-[var(--control-text-padding-x)]' }, ], defaultVariants: { variant: 'ghost', size: 'md', rounded: 'square', textOnly: false, }, } ) export interface ButtonProps extends ButtonHTMLAttributes, VariantProps { children: ReactNode textButton?: boolean prefixIcon?: ReactNode suffixIcon?: ReactNode loading?: boolean asChild?: boolean } const Button = forwardRef( ( { variant = 'ghost', children, size = 'md', textButton = false, prefixIcon, suffixIcon, rounded = 'square', disabled = false, loading = false, asChild = false, className, ...props }, ref ) => { const Comp = asChild ? Slot.Root : 'button' const isDisabled = disabled || loading return ( {asChild ? ( children ) : ( <> {loading ? ( ) : prefixIcon ? ( {prefixIcon} ) : null} {children} {suffixIcon && ( {suffixIcon} )} )} ) } ) Button.displayName = 'Button' export { Button, buttonVariants }