aboutsummaryrefslogtreecommitdiff
path: root/docs/prototypes/panel-widget-gallery.html
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-16 09:11:29 -0500
committerCraig Jennings <c@cjennings.net>2026-07-16 09:11:29 -0500
commit6189466dd21f3e19b6bdae9bf74e38f6211ae542 (patch)
tree0ca48eb533345dcd71a2e8933b21070cf1f5bd56 /docs/prototypes/panel-widget-gallery.html
parent910993b25ba1736fc7f5958c53a7cdc523f98cf2 (diff)
downloadarchsetup-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.html44
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']]);