| import React from 'react' | |
| import { motion } from 'framer-motion' | |
| const Button = ({ | |
| children, | |
| variant = 'primary', | |
| size = 'md', | |
| icon: Icon, | |
| onClick, | |
| disabled = false, | |
| loading = false, | |
| className = '', | |
| ...props | |
| }) => { | |
| const baseClasses = 'font-semibold rounded-xl transition-all flex items-center justify-center gap-2' | |
| const variants = { | |
| primary: 'bg-gradient-to-r from-primary-600 to-primary-700 text-white shadow-lg hover:shadow-xl', | |
| secondary: 'bg-white text-primary-700 border-2 border-primary-200 hover:bg-primary-50 hover:border-primary-300', | |
| success: 'bg-gradient-to-r from-green-600 to-emerald-700 text-white shadow-lg hover:shadow-xl', | |
| danger: 'bg-gradient-to-r from-red-600 to-pink-700 text-white shadow-lg hover:shadow-xl', | |
| ghost: 'bg-transparent text-slate-700 hover:bg-slate-100' | |
| } | |
| const sizes = { | |
| sm: 'px-4 py-2 text-sm', | |
| md: 'px-6 py-3', | |
| lg: 'px-8 py-4 text-lg' | |
| } | |
| const classes = `${baseClasses} ${variants[variant]} ${sizes[size]} ${className} ${ | |
| disabled || loading ? 'opacity-50 cursor-not-allowed' : '' | |
| }` | |
| return ( | |
| <motion.button | |
| whileHover={{ scale: disabled || loading ? 1 : 1.05 }} | |
| whileTap={{ scale: disabled || loading ? 1 : 0.95 }} | |
| onClick={onClick} | |
| disabled={disabled || loading} | |
| className={classes} | |
| {...props} | |
| > | |
| {loading ? ( | |
| <div className="animate-spin rounded-full h-5 w-5 border-b-2 border-white"></div> | |
| ) : Icon ? ( | |
| <Icon className="w-5 h-5" /> | |
| ) : null} | |
| {children} | |
| </motion.button> | |
| ) | |
| } | |
| export default Button |