From a1d9839ac97c050c1f0c8ddd38e0b2418faefdcf Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Tue, 9 Jun 2026 21:48:42 -0500 Subject: feat(theme-studio): order add-all around the base as -n .. base .. +n Add-all inserted every step after the source, giving base, -2, -1, +1, +2. Now the darker steps go before the base and the lighter ones after, so the palette reads -2 -1 base +1 +2, matching the preview row and how a ramp reads left to right. Inserting a darker step before the base shifted the base's index, so I bump the selected index to keep the selection (and the next preview's base) on the base color rather than drifting onto an inserted step. The #ramptest gate now checks the steps surround the base in order. --- scripts/theme-studio/theme-studio.html | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'scripts/theme-studio/theme-studio.html') diff --git a/scripts/theme-studio/theme-studio.html b/scripts/theme-studio/theme-studio.html index ab7d115c..529f5d30 100644 --- a/scripts/theme-studio/theme-studio.html +++ b/scripts/theme-studio/theme-studio.html @@ -861,20 +861,24 @@ function renderRamp(){ if(dups.length)parts.push('name already in palette, will be skipped on add: '+dups.join(', ')); rampNote(parts.join(' | '),dups.length>0); } -// Insert a step adjacent to the source swatch, keeping the ramp siblings in -// -n..+n order. A name collision is flagged and skipped (never overwrites); a -// hex that already exists under another name is added but flagged as a duplicate. +// Insert a step around the source swatch so the family reads -n .. base .. +n: +// darker (negative) steps go before the base, lighter (positive) ones after, each +// ordered among its existing siblings. A name collision is skipped (never +// overwrites); a hex matching another entry is added but flagged as a duplicate. function rampInsertIndex(off){ const bn=rampBase.name,re=new RegExp('^'+bn.replace(/[.*+?^${}()|[\]\\]/g,'\\$&')+'([+-]\\d+)$'); - let src=PALETTE.findIndex(p=>p[1]===bn);if(src<0)src=PALETTE.length-1; - let idx=src+1;while(idxp[1]===bn);if(src<0)src=PALETTE.length; + const sib=i=>{const m=i>=0&&i0){let idx=src+1;while(idx0&&v0){const v=sib(idx-1);if(v<0&&v>off){idx--;continue;}break;}return idx; } function addRampStep(s){ const nm=rampStepName(s.offset); if(PALETTE.some(p=>p[1].toLowerCase()===nm.toLowerCase())){rampNote('"'+nm+'" already exists — rename or skip',true);return false;} const dup=PALETTE.find(p=>p[0].toLowerCase()===s.hex.toLowerCase()); - PALETTE.splice(rampInsertIndex(s.offset),0,[s.hex,nm]);const healed=healGone(nm,s.hex);renderPalette();buildTable();buildUITable(); + const at=rampInsertIndex(s.offset);PALETTE.splice(at,0,[s.hex,nm]); + if(selectedIdx!=null&&at<=selectedIdx)selectedIdx++; // a darker step inserted before the base keeps the selection on the base + const healed=healGone(nm,s.hex);renderPalette();buildTable();buildUITable(); if(healed){renderCode();applyGround();} rampNote(dup?('added "'+nm+'" (same hex as "'+dup[1]+'")'):('added "'+nm+'"'),false);return true; } @@ -1565,7 +1569,7 @@ if(location.hash==='#ramptest'){let ok=true;const notes=[];const A=(c,n)=>{if(!c A(document.querySelectorAll('#rampprev .rchip .rhex').length===4,'each step tile shows its hex'); addAllRampSteps(); const names=PALETTE.map(p=>p[1]),bi=names.indexOf('blue'); - A(names.slice(bi,bi+5).join(',')==='blue,blue-2,blue-1,blue+1,blue+2','order after blue: '+names.slice(bi,bi+5).join(',')); + A(names.slice(bi-2,bi+3).join(',')==='blue-2,blue-1,blue,blue+1,blue+2','order around blue: '+names.slice(Math.max(0,bi-2),bi+3).join(',')); const before=PALETTE.length;addAllRampSteps();A(PALETTE.length===before,'re-add should skip existing names'); A(/skipped \(name already in palette\): blue-2, blue-1, blue\+1, blue\+2/.test(document.getElementById('rampmsg').textContent),'add-all names the skipped collisions: '+document.getElementById('rampmsg').textContent); renderRamp(); -- cgit v1.2.3