← back to Commercialrealestate
CRCP listings: property panel now docks to the right full-height (no longer a floating center card) + drag its left edge to widen (savable); corner-nav Sections drawer also resizable + saved
890dbe13c6a3a374eeddac10dd73567e77161737 · 2026-08-17 17:29:19 -0700 · steve
Files touched
M public/corner-nav.jsM public/mls.html
Diff
commit 890dbe13c6a3a374eeddac10dd73567e77161737
Author: steve <steve@designerwallcoverings.com>
Date: Mon Aug 17 17:29:19 2026 -0700
CRCP listings: property panel now docks to the right full-height (no longer a floating center card) + drag its left edge to widen (savable); corner-nav Sections drawer also resizable + saved
---
public/corner-nav.js | 31 ++++++++++++++++++++++++++++++-
public/mls.html | 46 +++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 71 insertions(+), 6 deletions(-)
diff --git a/public/corner-nav.js b/public/corner-nav.js
index 403e281..c37ffe7 100644
--- a/public/corner-nav.js
+++ b/public/corner-nav.js
@@ -44,12 +44,16 @@
'.cnav-burger .lbl{font-size:12px;letter-spacing:.3px;} @media(max-width:640px){.cnav-burger .lbl{display:none;}}' +
'.cnav-ov{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:9998;opacity:0;pointer-events:none;transition:opacity .18s;}' +
'.cnav-ov.on{opacity:1;pointer-events:auto;}' +
- '.cnav-drawer{position:fixed;top:0;bottom:0;width:min(330px,88vw);background:#11161f;color:#e6e8ec;z-index:9999;' +
+ '.cnav-drawer{position:fixed;top:0;bottom:0;width:var(--cnav-w,min(330px,88vw));background:#11161f;color:#e6e8ec;z-index:9999;' +
'box-shadow:0 0 40px rgba(0,0,0,.5);display:flex;flex-direction:column;transition:transform .2s ease;' +
'font:14px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;}' +
'.cnav-drawer.left{left:0;border-right:1px solid #232a38;transform:translateX(-104%);}' +
'.cnav-drawer.right{right:0;border-left:1px solid #232a38;transform:translateX(104%);}' +
'.cnav-drawer.on{transform:translateX(0);}' +
+ /* drag the inner vertical edge to widen the drawer (right→left edge, left→right edge); width persists */
+ '.cnav-rsz{position:absolute;top:0;bottom:0;width:9px;cursor:ew-resize;z-index:3;}' +
+ '.cnav-drawer.right .cnav-rsz{left:0;} .cnav-drawer.left .cnav-rsz{right:0;}' +
+ '.cnav-rsz:hover,.cnav-rsz.on{background:rgba(200,162,75,.55);}' +
'.cnav-hd{display:flex;align-items:center;justify-content:space-between;padding:14px 16px;border-bottom:1px solid #232a38;' +
'font-size:12px;text-transform:uppercase;letter-spacing:.7px;color:#C8A24B;}' +
'.cnav-hd .sub{display:block;color:#8A93A2;font-size:10.5px;letter-spacing:.3px;text-transform:none;margin-top:2px;}' +
@@ -144,6 +148,31 @@
var body = el('div', 'cnav-body');
d.appendChild(hd); d.appendChild(body); document.body.appendChild(d); d._body = body;
+ // ── resizable: drag the inner vertical edge to widen the drawer; width persists per side ──
+ var rsz = el('div', 'cnav-rsz'); rsz.setAttribute('title', 'Drag to widen · double-click to reset'); d.appendChild(rsz);
+ var RKEY = 'cnav_w_' + side;
+ var savedW = parseInt(localStorage.getItem(RKEY));
+ if (!isNaN(savedW) && savedW > 0) d.style.setProperty('--cnav-w', savedW + 'px');
+ (function () {
+ var drag = false, startX = 0, startW = 0;
+ var curW = function () { return d.getBoundingClientRect().width; };
+ rsz.addEventListener('mousedown', function (e) {
+ drag = true; startX = e.clientX; startW = curW();
+ document.body.style.userSelect = 'none'; rsz.classList.add('on'); e.preventDefault();
+ });
+ window.addEventListener('mousemove', function (e) {
+ if (!drag) return;
+ var delta = side === 'right' ? (startX - e.clientX) : (e.clientX - startX); // right drawer widens by dragging left
+ var w = Math.max(260, Math.min(Math.round(window.innerWidth * 0.95), Math.round(startW + delta)));
+ d.style.setProperty('--cnav-w', w + 'px');
+ });
+ window.addEventListener('mouseup', function () {
+ if (!drag) return; drag = false; document.body.style.userSelect = ''; rsz.classList.remove('on');
+ try { localStorage.setItem(RKEY, String(Math.round(curW()))); } catch (e) {}
+ });
+ rsz.addEventListener('dblclick', function () { d.style.removeProperty('--cnav-w'); try { localStorage.removeItem(RKEY); } catch (e) {} });
+ })();
+
// Focus trap: keep Tab/Shift+Tab inside the open drawer; arrow keys navigate links.
d.addEventListener('keydown', function (e) {
if (!d.classList.contains('on')) return;
diff --git a/public/mls.html b/public/mls.html
index 5cf9582..735bc52 100644
--- a/public/mls.html
+++ b/public/mls.html
@@ -38,9 +38,13 @@
widths (inline width), which overflows/scrolls and leaves the divider-drag doing nothing to the
columns. Force 100% so table-layout:fixed stretches the columns to fill — and the records expand
wider as you drag the divider right. Column drag-resize still works (adjusts proportions). */
- #tableView table.mls{width:100% !important;}
+ #tableView table.mls{width:var(--rec-w,100%) !important;min-width:100%;}
#tableView table.mls colgroup[data-cr] col{width:auto !important;}
#tableView table.mls td,#tableView table.mls th{overflow:hidden;text-overflow:ellipsis;}
+ /* right-edge grip: drag to widen the records past the screen edge (columns get wider, table scrolls) */
+ .recgrip{flex:0 0 7px;align-self:stretch;position:sticky;top:53px;height:calc(100vh - 53px);background:var(--line);cursor:ew-resize;z-index:6;transition:background .12s;}
+ .recgrip:hover,.recgrip.dragging{background:var(--acc);}
+ @media(max-width:820px){ .recgrip{display:none;} }
table.mls thead th{position:sticky;top:0;background:var(--bg2);color:var(--mut);text-transform:uppercase;letter-spacing:.3px;font-size:10.5px;padding:8px 10px;border-bottom:1px solid var(--line);cursor:pointer;user-select:none;z-index:2;}
table.mls thead th:hover{color:var(--ink);}
table.mls thead th.asc::after{content:' ▲';color:var(--acc);} table.mls thead th.desc::after{content:' ▼';color:var(--acc);}
@@ -72,9 +76,13 @@
.gc .row{display:flex;justify-content:space-between;font-size:12.5px;padding:2px 0;border-top:1px solid var(--line);}
.gc .row .k{color:var(--mut);} .gc .row .v{font-variant-numeric:tabular-nums;}
.hide{display:none;}
- #ov{display:none;position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:60;align-items:flex-start;justify-content:center;padding:40px 14px;overflow-y:auto;}
+ /* property panel docks to the RIGHT as a full-height, resizable side panel (no longer a floating card) */
+ #ov{display:none;position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:60;align-items:stretch;justify-content:flex-end;padding:0;overflow:hidden;}
#ov.on{display:flex;}
- #modal{width:min(680px,96vw);background:var(--card);border:1px solid var(--line);border-radius:15px;padding:20px 22px;position:relative;}
+ #modal{width:var(--modal-w,min(760px,96vw));max-width:96vw;height:100vh;overflow-y:auto;background:var(--card);border-left:1px solid var(--line);border-radius:0;padding:20px 26px 40px 22px;position:relative;box-shadow:-12px 0 40px rgba(0,0,0,.4);}
+ /* drag the LEFT edge of the panel to widen it (savable); double-click resets */
+ #modalRsz{position:absolute;top:0;left:0;bottom:0;width:11px;cursor:ew-resize;z-index:3;}
+ #modalRsz:hover,#modalRsz.on{background:color-mix(in srgb,var(--acc) 45%,transparent);}
#modal h3{margin:0 0 2px;font-size:19px;} .ph-sub{color:var(--warn);font-size:13px;}
.ph-x{position:absolute;top:12px;right:14px;background:none;border:0;color:var(--mut);font-size:22px;cursor:pointer;}
.ph-ci{display:flex;gap:14px;flex-wrap:wrap;margin:8px 0;font-size:13.5px;}
@@ -173,7 +181,7 @@
<div class="wrap">
<div class="tblbar" id="tblbar">
<button class="csvbtn" id="csv2" title="Download the current filtered rows as a CSV spreadsheet">⬇ Download CSV</button>
- <span class="mut" style="font-size:11px">Drag the vertical bar between the filters and the records to widen the table → · double-click it to collapse/restore the filters.</span>
+ <span class="mut" style="font-size:11px">Drag the <b>left</b> bar (filters↔records) to reclaim space · drag the <b>right</b> edge bar to widen the columns wider than the screen (scrolls) · double-click either to reset.</span>
<span id="acctbar" style="margin-left:auto;display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:12px"></span>
</div>
<div class="statsbar" id="statsbar"></div>
@@ -182,8 +190,9 @@
<div id="listView" class="hide"></div>
<div id="moreWrap" style="text-align:center;padding:16px 0"></div>
</div>
+<div class="recgrip" id="recgrip" title="Drag left to widen the records / columns (table scrolls past the edge) · double-click to reset to fit"></div>
</div>
-<div id="ov"><div id="modal"><button class="ph-x" aria-label="Close" onclick="document.getElementById('ov').classList.remove('on')">✕</button><div id="mbody"></div></div></div>
+<div id="ov"><div id="modal"><div id="modalRsz" title="Drag to widen the panel · double-click to reset"></div><button class="ph-x" aria-label="Close" onclick="document.getElementById('ov').classList.remove('on')">✕</button><div id="mbody"></div></div></div>
<script>
// Day/Night theme — pre-applied before first paint (see head snippet).
// apply() only PAINTS — does NOT persist (passive loads must not lock in a theme;
@@ -585,6 +594,33 @@ if($('#csv2')) $('#csv2').addEventListener('click',exportCSV);
window.addEventListener('mouseup',()=>{ if(!dragging) return; dragging=false; div.classList.remove('dragging'); document.body.classList.remove('raildrag'); try{localStorage.setItem(KEY,String(cur()));}catch(e){} });
div.addEventListener('dblclick',()=>{ const c=cur(); if(c>10){ lastW=c; setW(0); } else setW(lastW>10?lastW:DEF); try{localStorage.setItem(KEY,String(cur()));}catch(e){} });
})();
+// ── right-edge grip: drag LEFT to widen the records/columns past the screen edge (table scrolls);
+// drag RIGHT to shrink back to fit; double-click resets to fill. Persisted. ──
+(function(){
+ const shell=document.querySelector('.shell'), grip=$('#recgrip'), tw=document.querySelector('#tableView'); if(!shell||!grip||!tw) return;
+ const KEY='cre_mls_recw', MULT=2;
+ const contW=()=>tw.clientWidth||1;
+ const curPx=()=>{ const n=parseInt(getComputedStyle(shell).getPropertyValue('--rec-w')); return isNaN(n)?contW():n; };
+ const setPx=w=>{ const min=contW(), max=min*3; w=Math.max(min,Math.min(max,Math.round(w))); shell.style.setProperty('--rec-w', w<=min+2?'100%':(w+'px')); };
+ const saved=parseInt(localStorage.getItem(KEY)); if(!isNaN(saved)&&saved>0) requestAnimationFrame(()=>setPx(saved));
+ let drag=false,startX=0,startW=0;
+ grip.addEventListener('mousedown',e=>{ drag=true; startX=e.clientX; startW=Math.max(contW(),curPx()); grip.classList.add('dragging'); document.body.classList.add('raildrag'); e.preventDefault(); });
+ window.addEventListener('mousemove',e=>{ if(drag) setPx(startW + (startX-e.clientX)*MULT); }); // drag LEFT → wider
+ window.addEventListener('mouseup',()=>{ if(!drag) return; drag=false; grip.classList.remove('dragging'); document.body.classList.remove('raildrag'); const w=curPx(); try{localStorage.setItem(KEY, w>contW()+2?String(w):'0');}catch(e){} });
+ grip.addEventListener('dblclick',()=>{ shell.style.setProperty('--rec-w','100%'); try{localStorage.setItem(KEY,'0');}catch(e){} });
+})();
+// ── property panel: drag its LEFT edge to widen the right-docked panel (savable); double-click resets ──
+(function(){
+ const modal=$('#modal'), rsz=$('#modalRsz'); if(!modal||!rsz) return;
+ const KEY='cre_mls_modalw';
+ const saved=parseInt(localStorage.getItem(KEY)); if(!isNaN(saved)&&saved>0) modal.style.setProperty('--modal-w', saved+'px');
+ const curW=()=>modal.getBoundingClientRect().width;
+ let drag=false,startX=0,startW=0;
+ rsz.addEventListener('mousedown',e=>{ drag=true; startX=e.clientX; startW=curW(); rsz.classList.add('on'); document.body.style.userSelect='none'; e.preventDefault(); });
+ window.addEventListener('mousemove',e=>{ if(!drag) return; const w=Math.max(420, Math.min(Math.round(window.innerWidth*0.96), Math.round(startW+(startX-e.clientX)))); modal.style.setProperty('--modal-w', w+'px'); });
+ window.addEventListener('mouseup',()=>{ if(!drag) return; drag=false; rsz.classList.remove('on'); document.body.style.userSelect=''; try{localStorage.setItem(KEY,String(Math.round(curW())));}catch(e){} });
+ rsz.addEventListener('dblclick',()=>{ modal.style.removeProperty('--modal-w'); try{localStorage.removeItem(KEY);}catch(e){} });
+})();
// ── per-user settings: sign in with your own un/pw → your view (columns, order, rail width, theme,
// heat, sort) follows you across browsers; auto-saves on exit; shows "last saved". Layered on the
// existing CRCP accounts system (scrypt-hashed passwords, session cookie). ──
← 5a913c4 CRCP listings: records table fills the full panel width and
·
back to Commercialrealestate
·
auto-data-snapshot: 2026-08-17T18:01:33 (8 data files) — scr 7e0658e →