53 lines
1.5 KiB
TypeScript
53 lines
1.5 KiB
TypeScript
'use client'
|
|
|
|
import React from 'react'
|
|
|
|
type ButtonVariant = 'primary' | 'secondary' | 'outline'
|
|
type ButtonSize = 'sm' | 'md' | 'lg'
|
|
|
|
export type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
variant?: ButtonVariant
|
|
size?: ButtonSize
|
|
}
|
|
|
|
export function Button({
|
|
variant = 'primary',
|
|
size = 'md',
|
|
className,
|
|
children,
|
|
...props
|
|
}: ButtonProps) {
|
|
const baseClasses =
|
|
'inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed dark:ring-offset-gray-900'
|
|
|
|
const variantClasses: Record<ButtonVariant, string> = {
|
|
primary:
|
|
'bg-indigo-600 text-white hover:bg-indigo-700 active:bg-indigo-800 dark:bg-indigo-500 dark:hover:bg-indigo-400',
|
|
secondary:
|
|
'bg-gray-100 text-gray-900 hover:bg-gray-200 active:bg-gray-300 dark:bg-gray-800 dark:text-gray-100 dark:hover:bg-gray-700',
|
|
outline:
|
|
'border border-gray-300 text-gray-900 hover:bg-gray-50 active:bg-gray-100 dark:border-gray-600 dark:text-gray-100 dark:hover:bg-gray-800',
|
|
}
|
|
|
|
const sizeClasses: Record<ButtonSize, string> = {
|
|
sm: 'px-3 py-1.5 text-xs',
|
|
md: 'px-4 py-2 text-sm',
|
|
lg: 'px-5 py-2.5 text-sm',
|
|
}
|
|
|
|
const classes = [
|
|
baseClasses,
|
|
variantClasses[variant],
|
|
sizeClasses[size],
|
|
className,
|
|
]
|
|
.filter(Boolean)
|
|
.join(' ')
|
|
|
|
return (
|
|
<button className={classes} {...props}>
|
|
{children}
|
|
</button>
|
|
)
|
|
}
|