diff options
| author | Craig Jennings <c@cjennings.net> | 2026-07-16 09:11:29 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-07-16 09:11:29 -0500 |
| commit | 6189466dd21f3e19b6bdae9bf74e38f6211ae542 (patch) | |
| tree | 0ca48eb533345dcd71a2e8933b21070cf1f5bd56 /docs/prototypes/panel-widget-gallery.html | |
| parent | 910993b25ba1736fc7f5958c53a7cdc523f98cf2 (diff) | |
| download | archsetup-6189466dd21f3e19b6bdae9bf74e38f6211ae542.tar.gz archsetup-6189466dd21f3e19b6bdae9bf74e38f6211ae542.zip | |
feat(gallery): rework the console-key and slide-toggle colour vocabulary
Console keys read SCAN before LIVE, and LIVE is green. The palette already defines --pass as "run lamps, gear greens, monitor bars, LIVE lamps", so the widget contradicted the language it draws from. Its note asserted the old colours too. The per-key `red` boolean became a `tone` field, since a boolean can't express three states.
The slide toggle gains red and warn on its `on` axis, so the engaged state can be the notable one (mute, record, airplane mode). Red was reachable only on the `off` axis before, which paints the disengaged state: the opposite claim. A new onText axis makes the ON ink reachable at all. `on` had bundled background and ink together, so "dark pill, green legend" couldn't be expressed.
Presets name a combination (panel, run, armed, caution, dark), which is what a consumer reaches for. The axes are how one gets built.
Diffstat (limited to 'docs/prototypes/panel-widget-gallery.html')
| -rw-r--r-- | docs/prototypes/panel-widget-gallery.html | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/docs/prototypes/panel-widget-gallery.html b/docs/prototypes/panel-widget-gallery.html index 2a2910b..e64ddd3 100644 --- a/docs/prototypes/panel-widget-gallery.html +++ b/docs/prototypes/panel-widget-gallery.html @@ -1187,7 +1187,7 @@ card(C,'01','Slide toggle', '<b>on / off, the touchscreen way.</b> The one born-digital control in the kit — the smartphone pill toggle the live net/bt/audio panels use. Click to flip; readout shows the state. Physical cousins: the bat-handle (R03) and the rocker (N01).'); card(C,'02','Console key', (st,rd)=>GW.consoleKeys(st,{onChange:(i,t)=>rd(t)}), - '<b>physical push button.</b> Mutually exclusive — click one to engage. Gold = live, terracotta = muted.'); + '<b>physical push button.</b> Mutually exclusive — click one to engage. Green = live, terracotta = muted, gold = any other engaged key.'); card(C,'03','Horizontal fader', (st,rd)=>GW.faderH(st,{value:68,onChange:(v,t)=>rd(t)}), '<b>continuous 0-100.</b> Per-device volume, brightness. Drag the gold cap; readout tracks.'); @@ -1657,25 +1657,57 @@ BOOST.forEach(no=>{const rd=document.getElementById('rd-'+no); m=>ids.has(m)?`<a class="xref" href="#card-${m}">${m}</a>`:m);});})(); /* style chips: shared demo rig for builders with constructor style opts — - reads a builder's STYLES table and drives setStyle on the live card instance */ -function styleChips(no,STYLES,AXES){ + reads a builder's STYLES table and drives setStyle on the live card instance. + PRESETS (optional) adds a leading group of named combinations: a preset chip + applies all axes at once and resyncs the axis chips beneath it, and changing + any axis afterwards clears the preset — the chips must never claim a preset + the widget has since diverged from. */ +function styleChips(no,STYLES,AXES,PRESETS,defPreset){ const h=$('card-'+no)?.gw; if(!h)return; const cardEl=h.el.closest('.card'); const row=document.createElement('div'); row.className='famchips'; + const sel={}, sync={}, groups=[]; let clearPreset=()=>{}; + /* Re-apply every axis on any change rather than just the one clicked: axes are + not independent (onText overrides the ink `on` sets), so a lone setStyle can + drop a selection the chips still show as lit — the card would then display a + combination the widget isn't in. Applying all of them in AXES order makes + the outcome independent of click order. */ + const applyAll=()=>{for(const [,axis] of AXES) if(sel[axis]) h.setStyle(axis,sel[axis]);}; for(const [label,axis,def] of AXES){ + sel[axis]=def; const g=document.createElement('span'); g.className='fgroup'; const lab=document.createElement('span'); lab.className='lab'; lab.textContent=label; g.appendChild(lab); const chips=[]; for(const [name,o] of Object.entries(STYLES[axis])){ const b=document.createElement('span'); b.className='fc'+(name===def?' on':''); b.style.background=o.dot; b.title=name; chips.push(b); - b.addEventListener('click',()=>{h.setStyle(axis,name); - chips.forEach(x=>x.classList.toggle('on',x===b));}); + b.addEventListener('click',()=>{sel[axis]=name; applyAll(); + chips.forEach(x=>x.classList.toggle('on',x===b)); clearPreset();}); g.appendChild(b);} + sync[axis]=name=>{sel[axis]=name; chips.forEach(x=>x.classList.toggle('on',x.title===name));}; + groups.push(g);} + if(PRESETS&&h.setPreset){ + const g=document.createElement('span'); g.className='fgroup'; + const lab=document.createElement('span'); lab.className='lab'; lab.textContent='preset'; g.appendChild(lab); + const chips=[]; + for(const [name,p] of Object.entries(PRESETS)){ + const b=document.createElement('span'); b.className='fc'+(name===defPreset?' on':''); b.title=name; + /* the on-tone is the preset's identity, so it doubles as the swatch */ + b.style.background=STYLES.on[p.on].dot; chips.push(b); + b.addEventListener('click',()=>{ + const applied=h.setPreset(name); if(!applied)return; + chips.forEach(x=>x.classList.toggle('on',x===b)); + for(const [axis,style] of Object.entries(applied)) sync[axis]?.(style);}); + g.appendChild(b);} + clearPreset=()=>chips.forEach(x=>x.classList.remove('on')); row.appendChild(g);} + groups.forEach(g=>row.appendChild(g)); cardEl.querySelector('.opts').appendChild(row); } -styleChips('01',GW.slideToggle.STYLES,[['on','on','amber'],['off','off','dark'],['off text','offText','white'],['thumb','thumb','light']]); +styleChips('01',GW.slideToggle.STYLES, + [['on','on','amber'],['on text','onText','panel'],['off','off','dark'], + ['off text','offText','white'],['thumb','thumb','light']], + GW.slideToggle.PRESETS,'panel'); styleChips('R05',GW.filterBank.STYLES,[['panel','panel','silver'],['shape','caps','block'],['color','capColor','black']]); styleChips('06',GW.segmented.STYLES,[['accent','accent','amber']]); styleChips('25',GW.slideRule.STYLES,[['face','skin','warm']]); |
