import React, { useState } from 'react'; import { LucideIcon } from 'lucide-react'; interface AnimatedButtonProps { children: React.ReactNode; onClick?: () => void; variant?: 'primary' | 'secondary' | 'ghost' | 'danger' | 'success'; size?: 'sm' | 'md' | 'lg'; icon?: LucideIcon; iconPosition?: 'left' | 'right'; disabled?: boolean; loading?: boolean; className?: string; ripple?: boolean; glow?: boolean; type?: 'button' | 'submit' | 'reset'; } /** * 增强的动画按钮组件 * 支持涟漪效果、发光效果和各种微交互 */ export const AnimatedButton: React.FC = ({ children, onClick, variant = 'primary', size = 'md', icon: Icon, iconPosition = 'left', disabled = false, loading = false, className = '', ripple = true, glow = false, type = 'button' }) => { const [ripples, setRipples] = useState>([]); const handleClick = (e: React.MouseEvent) => { if (disabled || loading) return; // 创建涟漪效果 if (ripple) { const rect = e.currentTarget.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const newRipple = { id: Date.now(), x, y }; setRipples(prev => [...prev, newRipple]); // 移除涟漪效果 setTimeout(() => { setRipples(prev => prev.filter(r => r.id !== newRipple.id)); }, 600); } onClick?.(); }; const getVariantClasses = () => { const base = 'btn relative overflow-hidden'; const variants = { primary: 'btn-primary', secondary: 'btn-secondary', ghost: 'btn-ghost', danger: 'btn-danger', success: 'btn-success' }; return `${base} ${variants[variant]}`; }; const getSizeClasses = () => { const sizes = { sm: 'btn-sm', md: '', lg: 'btn-lg' }; return sizes[size]; }; const glowClasses = glow ? 'shadow-glow hover:shadow-glow-lg' : ''; const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : ''; const loadingClasses = loading ? 'cursor-wait' : ''; return ( ); }; /** * 浮动操作按钮组件 */ export const FloatingActionButton: React.FC<{ icon: LucideIcon; onClick: () => void; className?: string; size?: 'sm' | 'md' | 'lg'; }> = ({ icon: Icon, onClick, className = '', size = 'md' }) => { const sizeClasses = { sm: 'w-12 h-12', md: 'w-14 h-14', lg: 'w-16 h-16' }; const iconSizes = { sm: 20, md: 24, lg: 28 }; return ( ); };