47 lines
1.5 KiB
TypeScript
47 lines
1.5 KiB
TypeScript
import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react'
|
|
import { clx } from '@/helpers/utils'
|
|
|
|
type ButtonProps = {
|
|
variant?: 'primary' | 'secondary' | 'outline'
|
|
leftIcon?: ReactNode
|
|
rightIcon?: ReactNode
|
|
} & ButtonHTMLAttributes<HTMLButtonElement>
|
|
|
|
const variantClasses: Record<NonNullable<ButtonProps['variant']>, string> = {
|
|
primary: 'bg-black text-white hover:bg-black/90',
|
|
secondary: 'bg-white text-black border border-black hover:bg-black/5',
|
|
outline: 'border border-black text-black hover:bg-black/5'
|
|
}
|
|
|
|
const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {
|
|
const {
|
|
children,
|
|
className,
|
|
variant = 'primary',
|
|
leftIcon,
|
|
rightIcon,
|
|
...rest
|
|
} = props
|
|
|
|
return (
|
|
<button
|
|
ref={ref}
|
|
className={clx(
|
|
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full px-4 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-black/10 disabled:pointer-events-none disabled:opacity-50',
|
|
variantClasses[variant],
|
|
className
|
|
)}
|
|
{...rest}
|
|
>
|
|
{leftIcon ? <span className='flex items-center'>{leftIcon}</span> : null}
|
|
{children}
|
|
{rightIcon ? <span className='flex items-center'>{rightIcon}</span> : null}
|
|
</button>
|
|
)
|
|
})
|
|
|
|
Button.displayName = 'Button'
|
|
|
|
export default Button
|
|
|