// CommandPalette — ⌘K overlay. Glass surface, blue focus ring. const CommandPalette = ({ open, onClose, onRun }) => { const [q, setQ] = React.useState(''); const [sel, setSel] = React.useState(0); const inputRef = React.useRef(null); const items = React.useMemo(() => [ { id: 'build', label: 'Build project', hint: '⌘B', kind: 'Action' }, { id: 'deploy', label: 'Deploy to prod', hint: '⌘D', kind: 'Action' }, { id: 'theme', label: 'Theme: Australis Dark', hint: '⌘T', kind: 'Setting' }, { id: 'tokens', label: 'Open tokens.css', hint: 'go', kind: 'File' }, { id: 'aurora', label: 'Open aurora.ts', hint: 'go', kind: 'File' }, { id: 'sign', label: 'Sign out', hint: '', kind: 'Action', danger: true }, ], []); const filtered = items.filter(i => i.label.toLowerCase().includes(q.toLowerCase())); React.useEffect(() => { if (open && inputRef.current) inputRef.current.focus(); setQ(''); setSel(0); }, [open]); React.useEffect(() => { if (!open) return; const onKey = (e) => { if (e.key === 'Escape') onClose(); if (e.key === 'ArrowDown') { e.preventDefault(); setSel(s => Math.min(s + 1, filtered.length - 1)); } if (e.key === 'ArrowUp') { e.preventDefault(); setSel(s => Math.max(s - 1, 0)); } if (e.key === 'Enter' && filtered[sel]) { onRun(filtered[sel]); onClose(); } }; window.addEventListener('keydown', onKey); return () => window.removeEventListener('keydown', onKey); }, [open, sel, filtered, onClose, onRun]); if (!open) return null; return (
e.stopPropagation()}>
{ setQ(e.target.value); setSel(0); }} placeholder="Type a command…" style={cpStyles.input} /> esc
{filtered.length === 0 && (
No matches.
)} {filtered.map((it, i) => (
setSel(i)} onClick={() => { onRun(it); onClose(); }} style={{ ...cpStyles.item, background: i === sel ? 'rgba(99,136,216,0.18)' : 'transparent', color: i === sel ? '#a4c4ff' : (it.danger ? '#ff854f' : 'var(--fg-1)'), }}> {it.label} {it.kind} {it.hint && {it.hint}}
))}
); }; const cpStyles = { scrim: { position: 'absolute', inset: 0, background: 'rgba(34,37,49,0.72)', backdropFilter: 'blur(4px)', display: 'flex', alignItems: 'flex-start', justifyContent: 'center', paddingTop: '15vh', zIndex: 100, }, panel: { width: 540, background: 'rgba(55,59,70,0.85)', backdropFilter: 'blur(16px)', border: '1px solid #565f69', borderRadius: 10, boxShadow: '0 24px 64px rgba(10,12,18,0.6), 0 8px 16px rgba(10,12,18,0.45)', overflow: 'hidden', }, head: { display: 'flex', alignItems: 'center', gap: 10, padding: '12px 14px', borderBottom: '1px solid #414751', }, input: { flex: 1, background: 'transparent', border: 0, outline: 'none', color: 'var(--fg-0)', fontFamily: 'var(--font-sans)', fontSize: 14, }, esc: { fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--fg-3)', background: '#1b1e28', padding: '2px 6px', borderRadius: 4, border: '1px solid #414751', }, list: { padding: 6, maxHeight: 360, overflowY: 'auto' }, item: { display: 'flex', alignItems: 'center', gap: 10, padding: '8px 10px', borderRadius: 5, fontSize: 13, cursor: 'pointer', }, kind: { fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--fg-3)', textTransform: 'uppercase', letterSpacing: '0.06em', }, hint: { fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--fg-3)', background: '#1b1e28', padding: '2px 6px', borderRadius: 4, border: '1px solid #414751', }, empty: { padding: 16, fontSize: 13, color: 'var(--fg-3)' }, }; window.CommandPalette = CommandPalette;