chore: import codes
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
const Button = ({
|
||||
children,
|
||||
onClick,
|
||||
type = 'button',
|
||||
variant = 'primary',
|
||||
size = 'sm',
|
||||
disabled = false,
|
||||
loading = false,
|
||||
icon,
|
||||
iconPosition = 'left',
|
||||
className = '',
|
||||
...props
|
||||
}) => {
|
||||
const baseClassName = 'cursor-pointer inline-flex items-center justify-center font-medium rounded-xl transition-all duration-200 focus:outline-none focus:ring-1 disabled:opacity-50 disabled:cursor-not-allowed';
|
||||
|
||||
const variants = {
|
||||
primary: 'bg-neutral-900 text-white hover:bg-neutral-800 focus:ring-neutral-900/20 dark:bg-white dark:text-black dark:hover:bg-neutral-100 dark:focus:ring-white/20',
|
||||
secondary: 'bg-transparent border border-neutral-300 text-neutral-700 hover:bg-neutral-100 focus:ring-neutral-500/20 dark:bg-neutral-800/60 dark:border-neutral-700/50 dark:text-white dark:hover:bg-neutral-800/80 dark:focus:ring-neutral-600/20 dark:backdrop-blur-sm',
|
||||
danger: 'bg-red-50 border border-red-200 text-red-700 hover:bg-red-100 focus:ring-red-500/20 dark:bg-red-500/20 dark:border-red-500/30 dark:text-red-400 dark:hover:bg-red-500/30 dark:focus:ring-red-500/20',
|
||||
ghost: 'text-neutral-600 hover:text-neutral-900 hover:bg-neutral-100 focus:ring-neutral-500/20 dark:text-neutral-400 dark:hover:text-white dark:hover:bg-neutral-700/30 dark:focus:ring-neutral-600/20',
|
||||
success: 'bg-green-50 border border-green-200 text-green-700 hover:bg-green-100 focus:ring-green-500/20 dark:bg-green-500/20 dark:border-green-500/30 dark:text-green-400 dark:hover:bg-green-500/30 dark:focus:ring-green-500/20',
|
||||
warning: 'bg-yellow-50 border border-yellow-200 text-yellow-700 hover:bg-yellow-100 focus:ring-yellow-500/20 dark:bg-yellow-500/20 dark:border-yellow-500/30 dark:text-yellow-400 dark:hover:bg-yellow-500/30 dark:focus:ring-yellow-500/20'
|
||||
};
|
||||
|
||||
const sizes = {
|
||||
sm: 'px-3 py-2 text-xs gap-1.5',
|
||||
md: 'px-4 py-2.5 text-sm gap-2',
|
||||
lg: 'px-6 py-3 text-base gap-2.5'
|
||||
};
|
||||
|
||||
const iconSizes = {
|
||||
sm: 'w-3.5 h-3.5',
|
||||
md: 'w-4 h-4',
|
||||
lg: 'w-5 h-5'
|
||||
};
|
||||
|
||||
const LoadingSpinner = () => (
|
||||
<div className={`border-2 border-current border-t-transparent rounded-full animate-spin ${iconSizes[size]}`} />
|
||||
);
|
||||
|
||||
const handleClick = (e) => {
|
||||
if (!disabled && !loading && onClick) {
|
||||
onClick(e);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
type={type}
|
||||
onClick={handleClick}
|
||||
disabled={disabled || loading}
|
||||
className={`${baseClassName} ${variants[variant]} ${sizes[size]} ${className}`}
|
||||
{...props}
|
||||
>
|
||||
{loading ? (
|
||||
<LoadingSpinner />
|
||||
) : (
|
||||
<>
|
||||
{icon && iconPosition === 'left' && (
|
||||
<span className={iconSizes[size]}>{icon}</span>
|
||||
)}
|
||||
{children}
|
||||
{icon && iconPosition === 'right' && (
|
||||
<span className={iconSizes[size]}>{icon}</span>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default Button;
|
||||
Reference in New Issue
Block a user