// MOMO Pro - 共用 UI 元件 // ===== Badge ===== const Badge = ({ tone = 'secondary', children, dot = false, style }) => { const tones = { primary: { bg: 'var(--momo-primary-100)', text: 'var(--momo-primary-700)', dot: 'var(--momo-primary)' }, success: { bg: 'var(--momo-success-bg)', text: 'var(--momo-success-text)', dot: 'var(--momo-success)' }, danger: { bg: 'var(--momo-danger-bg)', text: 'var(--momo-danger-text)', dot: 'var(--momo-danger)' }, warning: { bg: 'var(--momo-warning-bg)', text: 'var(--momo-warning-text)', dot: 'var(--momo-warning)' }, info: { bg: 'var(--momo-info-bg)', text: 'var(--momo-info-text)', dot: 'var(--momo-info)' }, secondary: { bg: 'var(--momo-bg-muted)', text: 'var(--momo-text-secondary)', dot: 'var(--momo-text-tertiary)' }, }; const t = tones[tone] || tones.secondary; return ( {dot && } {children} ); }; // ===== Button ===== const Button = ({ variant = 'gradient', size = 'md', icon, iconRight, children, onClick, style, disabled, type = 'button' }) => { const sizes = { sm: { padding: '6px 12px', fontSize: 'var(--momo-font-size-xs)', height: 30, gap: 6 }, md: { padding: '8px 16px', fontSize: 'var(--momo-font-size-sm)', height: 38, gap: 8 }, lg: { padding: '10px 20px', fontSize: 'var(--momo-font-size-base)', height: 44, gap: 10 }, }; const variants = { gradient: { background: 'var(--momo-gradient-primary)', color: 'var(--momo-text-inverse)', boxShadow: 'var(--momo-shadow-sm)', }, solid: { background: 'var(--momo-primary)', color: 'var(--momo-text-inverse)', }, outline: { background: 'var(--momo-bg-surface)', color: 'var(--momo-primary)', border: '1.5px solid var(--momo-primary)', }, ghost: { background: 'transparent', color: 'var(--momo-text-secondary)', }, 'ghost-hover': { background: 'var(--momo-bg-subtle)', color: 'var(--momo-text-primary)', }, secondary: { background: 'var(--momo-bg-surface)', color: 'var(--momo-text-primary)', border: '1px solid var(--momo-border)', }, danger: { background: 'var(--momo-danger)', color: 'var(--momo-text-inverse)', }, }; const s = sizes[size]; const v = variants[variant] || variants.gradient; return ( ); }; // ===== Avatar ===== const Avatar = ({ name = '?', size = 32, gradient = false, style }) => { const initial = (name || '?').trim().charAt(0).toUpperCase(); // 從名字 hash 出穩定色相 let hash = 0; for (let i = 0; i < name.length; i++) hash = name.charCodeAt(i) + ((hash << 5) - hash); const hue = Math.abs(hash) % 360; return (