/* bits.jsx — atomic UI bits: icons, sparkline, etc. */ const Icon = ({ name, size=16, color, style, className }) => { const s = { width:size, height:size, color:color||'currentColor', flex:'none', ...style }; const P = (paths) => {paths}; switch(name){ case 'home': return P(<>); case 'bolt': return P(<>); case 'sun': return P(<>); case 'cloudy': return P(<>); case 'cloud': return P(<>); case 'battery': return P(<>); case 'car': return P(<>); case 'plug': return P(<>); case 'flash': return P(<>); case 'grid': return P(<>); case 'chart': return P(<>); case 'gear': return P(<>); case 'bell': return P(<>); case 'search': return P(<>); case 'lightning': return P(<>); case 'leaf': return P(<>); case 'wallet': return P(<>); case 'chevron': return P(<>); case 'expand': return P(<>); case 'wifi': return P(<>); case 'arrowup': return P(<>); case 'arrowdown': return P(<>); case 'arrowr': return P(<>); case 'wind': return P(<>); case 'snow': return P(<>); case 'eye': return P(<>); case 'pause': return P(<>); case 'play': return P(<>); case 'thermo': return P(<>); default: return null; } }; /* ---- small sparkline ---- */ const Sparkline = ({ data, width=80, height=24, color="currentColor", area=true, stroke=1.4 }) => { if (!data || data.length<2) return null; const min = Math.min(...data), max = Math.max(...data); const range = (max-min) || 1; const pts = data.map((v,i)=>{ const x = (i/(data.length-1)) * (width-2) + 1; const y = height - 2 - ((v-min)/range) * (height-4); return [x,y]; }); const d = pts.map((p,i)=> (i?'L':'M') + p[0].toFixed(1) + ' ' + p[1].toFixed(1)).join(' '); const dArea = d + ` L ${(width-1).toFixed(1)} ${(height-1).toFixed(1)} L 1 ${(height-1).toFixed(1)} Z`; return ( {area && } ); }; /* ---- diagonal stripe pattern as inline svg url ---- */ const stripePattern = (color, opacity=1) => `url("data:image/svg+xml;utf8,${encodeURIComponent( `` )}")`; Object.assign(window, { Icon, Sparkline, stripePattern });