[object Object]

← back to Commercialrealestate

direct-listings: add density slider (Steve grid rule — every grid needs sort + density)

2645a2211a8ae5093d2359f2b567caa6a128a9e3 · 2026-08-20 13:13:12 -0700 · Steve Abrams

CTA click-through audit caught direct-listings.html had a sort select but no
density control. Added a persisted row-density range (4-16px --rowpad) beside the
sort select; verified headless that dragging it moves td padding 7->14px, saves
to localStorage, zero console errors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 2645a2211a8ae5093d2359f2b567caa6a128a9e3
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu Aug 20 13:13:12 2026 -0700

    direct-listings: add density slider (Steve grid rule — every grid needs sort + density)
    
    CTA click-through audit caught direct-listings.html had a sort select but no
    density control. Added a persisted row-density range (4-16px --rowpad) beside the
    sort select; verified headless that dragging it moves td padding 7->14px, saves
    to localStorage, zero console errors.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 public/direct-listings.html | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/public/direct-listings.html b/public/direct-listings.html
index 88bf631..f192c3f 100644
--- a/public/direct-listings.html
+++ b/public/direct-listings.html
@@ -17,6 +17,9 @@ h1{font-size:17px;margin:0}h1 b{color:var(--ink)}
 .stat b{font-size:18px;color:var(--ink)}.stat span{display:block;font-size:10px;text-transform:uppercase;color:var(--mut);letter-spacing:.4px}
 .prov{font-size:11.5px;color:var(--mut);margin:0 0 12px;line-height:1.5}
 .toolbar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-bottom:10px}
+.dens-ctrl{display:inline-flex;align-items:center;gap:6px;color:var(--mut);font-size:13px}
+.dens-ctrl input[type=range]{width:90px;accent-color:var(--blue);cursor:pointer}
+.dens-ic{font-size:15px;line-height:1}
 .search{flex:1;min-width:200px;background:var(--card);border:1px solid var(--line);color:var(--ink);border-radius:8px;padding:8px 11px;font-size:13px}
 select{background:var(--card);border:1px solid var(--line);color:var(--ink);border-radius:8px;padding:7px 9px;font-size:12px}
 .chips{display:flex;flex-wrap:wrap;gap:6px}
@@ -54,6 +57,7 @@ td.price{color:var(--gold);font-weight:600}
     <input class="search" id="q" placeholder="search agent, firm, address, city…">
     <div class="chips" id="srcChips"></div>
     <select id="sort"></select>
+    <label class="dens-ctrl" title="Row density"><span class="dens-ic">≡</span><input type="range" id="dens" min="4" max="16" step="1" value="7"></label>
     <span class="count" id="count"></span>
   </div>
   <div class="tablewrap"><table><thead id="thead"></thead><tbody id="tbody"></tbody></table></div>
@@ -91,7 +95,6 @@ function filtered(){
 let _dlInf=null,_dlRows=[];
 function _dlRow(x){ return '<tr>'+COLS.map(c=>`<td class="${c.num?'num ':''}${c.cls||''}">${c.r(x)}</td>`).join('')+'</tr>'; }
 function render(){
-  document.documentElement.style.setProperty('--rowpad','7px');
   const rows=filtered();
   $('#thead').innerHTML='<tr>'+COLS.map(c=>`<th data-k="${c.k}" class="${c.num?'num':''}${c.k===sortKey?' sorted':''}">${c.l}${c.k===sortKey?(sortDir===1?' ▲':' ▼'):''}</th>`).join('')+'</tr>';
   // Windowed infinite scroll (was rows.slice(0,2000)): reveal a batch, load more on scroll.
@@ -103,6 +106,10 @@ function render(){
 }
 $('#thead').addEventListener('click',e=>{const th=e.target.closest('th');if(!th)return;const k=th.dataset.k;if(k===sortKey)sortDir=-sortDir;else{sortKey=k;sortDir=COLS.find(c=>c.k===k)?.num?-1:1;}render();});
 $('#q').addEventListener('input',()=>{q=$('#q').value.trim();render();});
+// Density slider — controls row padding (compact ↔ roomy), persisted (Steve's grid standard).
+const _setDens=v=>document.documentElement.style.setProperty('--rowpad',v+'px');
+(()=>{const saved=+localStorage.getItem('dl:dens')||7;$('#dens').value=saved;_setDens(saved);})();
+$('#dens').addEventListener('input',()=>{const v=$('#dens').value;_setDens(v);localStorage.setItem('dl:dens',v);});
 $('#sort').innerHTML=[['scraped_at:desc','Newest scraped'],['price:desc','Price ↓'],['price:asc','Price ↑'],['agent:asc','Agent A→Z'],['firm:asc','Firm A→Z'],['city:asc','City A→Z']].map(([k,l])=>`<option value="${k}">Sort: ${l}</option>`).join('');
 $('#sort').addEventListener('change',()=>{const v=$('#sort').value.split(':');sortKey=v[0];sortDir=v[1]==='asc'?1:-1;render();});
 fetch('/api/direct-listings').then(r=>r.json()).then(d=>{

← 3716477 CRCP table view: columns expand full-width + sticky header &  ·  back to Commercialrealestate  ·  direct-listings: add aria-label to density slider (a11y — Co 7777839 →