[object Object]

← back to Commercialrealestate

sort-bar (Cody gate): preserve <optgroup> labels as rail section headers so dynamic 20+ column sorts show grouped (Financial/Location/…) not a wall of unlabeled chips

19586842fea41139d195a0562c17ef9fded32279 · 2026-08-03 13:08:48 -0700 · Steve Abrams

Files touched

Diff

commit 19586842fea41139d195a0562c17ef9fded32279
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Aug 3 13:08:48 2026 -0700

    sort-bar (Cody gate): preserve <optgroup> labels as rail section headers so dynamic 20+ column sorts show grouped (Financial/Location/…) not a wall of unlabeled chips
---
 public/sort-bar.js | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/public/sort-bar.js b/public/sort-bar.js
index fc2e86a..39d8b06 100644
--- a/public/sort-bar.js
+++ b/public/sort-bar.js
@@ -14,7 +14,8 @@
     '.sbchip{background:var(--card,#141925);color:var(--mut,#8b949e);border:1px solid var(--line,#232a38);border-radius:7px;padding:4px 9px;font-size:12px;cursor:pointer;line-height:1.2;}',
     '.sbchip:hover{color:var(--ink,#e6edf3);border-color:var(--mut,#8A93A2);}',
     '.sbchip.on{border-color:var(--blue,#58a6ff);color:var(--blue,#58a6ff);background:rgba(88,166,255,.14);font-weight:600;}',
-    'span.sb-sec{display:inline-flex;align-items:center;gap:5px;flex-wrap:wrap}'
+    'span.sb-sec{display:inline-flex;align-items:center;gap:5px;flex-wrap:wrap}',
+    '.sb-grp{flex-basis:100%;width:100%;font-size:9.5px;text-transform:uppercase;letter-spacing:.5px;color:var(--mut,#8A93A2);opacity:.8;margin:7px 0 1px;font-weight:600}'
   ].join('');
   document.head.appendChild(css);
 
@@ -42,10 +43,16 @@
   function build() {
     var s = sel(); if (!s || s.tagName !== 'SELECT' || !s.options.length) return;
     var chips = ensureChips(s);
-    chips.innerHTML = Array.prototype.map.call(s.options, function (o, i) {
+    // Preserve <optgroup> labels (dynamic column-driven selects have 20+ options across groups) so
+    // the rail shows "Financial / Location / …" headers instead of a wall of unlabeled chips (Cody gate).
+    var html = '', lastGrp = null;
+    Array.prototype.forEach.call(s.options, function (o, i) {
+      var grp = (o.parentElement && o.parentElement.tagName === 'OPTGROUP') ? (o.parentElement.label || '') : '';
+      if (grp !== lastGrp) { if (grp) html += '<span class="sb-grp">' + grp.replace(/</g, '&lt;') + '</span>'; lastGrp = grp; }
       var label = (o.textContent || '').replace(/^Sort:\s*/i, '').trim() || ('Option ' + (i + 1));
-      return '<button class="sbchip' + (i === s.selectedIndex ? ' on' : '') + '" data-i="' + i + '">' + label.replace(/</g, '&lt;') + '</button>';
-    }).join('');
+      html += '<button class="sbchip' + (i === s.selectedIndex ? ' on' : '') + '" data-i="' + i + '">' + label.replace(/</g, '&lt;') + '</button>';
+    });
+    chips.innerHTML = html;
   }
 
   document.addEventListener('click', function (e) {

← 75aff2f afternoon CRE update 2026-08-03  ·  back to Commercialrealestate  ·  chore: v0.18.0 (session close) — sort-option chip bar on lef 096bff8 →