// Atomic UI primitives
const { useState, useEffect, useRef, useMemo, useCallback } = React;
function Btn({ children, active, variant='ghost', size='md', title, onClick, style, disabled, icon }) {
const sizes = {
sm: { padding: '4px 8px', fontSize: 11, height: 24, gap: 5 },
md: { padding: '6px 10px', fontSize: 12, height: 30, gap: 6 },
lg: { padding: '8px 14px', fontSize: 13, height: 36, gap: 8 },
};
const variants = {
ghost: { background: active ? 'var(--bg-3)' : 'transparent', color: active ? 'var(--ink-0)' : 'var(--ink-2)', border: '1px solid transparent' },
outline: { background: 'var(--bg-2)', color: 'var(--ink-1)', border: '1px solid var(--line-2)' },
solid: { background: 'var(--ink-0)', color: 'var(--bg-0)', border: '1px solid var(--ink-0)', fontWeight: 600 },
accent: { background: 'var(--accent)', color: 'var(--accent-text)', border: '1px solid var(--accent)', fontWeight: 600 },
danger: { background: 'transparent', color: 'var(--reject)', border: '1px solid transparent' },
};
return (
);
}
function Kbd({ children }) {
return {children};
}
function Chip({ children, active, color, onClick, onRemove, style }) {
const colorMap = {
red: { bg: 'rgba(229,72,77,0.16)', fg: '#ff9ba0' },
orange: { bg: 'rgba(255,155,80,0.16)', fg: '#ffb27a' },
yellow: { bg: 'rgba(244,185,66,0.16)', fg: '#f4d58a' },
green: { bg: 'rgba(82,200,120,0.16)', fg: '#88ddaa' },
blue: { bg: 'rgba(112,165,255,0.16)',fg: '#a7c6ff' },
purple: { bg: 'rgba(186,128,240,0.16)',fg: '#d0a8f5' },
};
const c = color && colorMap[color] ? colorMap[color] : { bg: active ? 'var(--blue-soft)' : 'var(--bg-3)', fg: active ? '#a7c6ff' : 'var(--ink-2)'};
return (
{children}
{onRemove && }
);
}
function Stars({ rating, onRate, size = 12, compact }) {
return (
e.stopPropagation()}>
{[1,2,3,4,5].map(i => {
const filled = i <= (rating||0);
return (
);
})}
);
}
function ColorDot({ color, size = 10, onClick, active }) {
const map = {
red: '#e5484d', orange: '#ff9b50', yellow: '#f4b942',
green: '#52c878', blue: '#70a5ff', purple: '#ba80f0',
};
return (
);
}
function Pill({ children, color = 'neutral', style }) {
const map = {
neutral: { bg: 'var(--bg-3)', fg: 'var(--ink-2)', border: 'var(--line-2)' },
raw: { bg: 'transparent', fg: 'var(--ink-1)', border: 'var(--line-3)' },
jpg: { bg: 'transparent', fg: 'var(--ink-2)', border: 'var(--line-2)' },
accent: { bg: 'var(--accent-soft)', fg: 'var(--accent)', border: 'transparent' },
reject: { bg: 'var(--reject-soft)', fg: 'var(--reject)', border: 'transparent' },
live: { bg: 'rgba(82,200,120,0.14)', fg: '#88ddaa', border: 'transparent' },
};
const c = map[color] || map.neutral;
return {children};
}
function Divider({ vertical, style }) {
return ;
}
function Toast({ msg, onClose }) {
useEffect(() => {
if (!msg) return;
const t = setTimeout(onClose, 2600);
return () => clearTimeout(t);
}, [msg]);
if (!msg) return null;
return (
{msg}
);
}
Object.assign(window, { Btn, Kbd, Chip, Stars, ColorDot, Pill, Divider, Toast });