← back to Analytics Chips
index: add density slider + localStorage hydration for sort/filter/density
d173ece24e8aaa2c720689ba0e431d4818dab0d0 · 2026-05-19 17:27:21 -0700 · SteveStudio2
Standing-rule fix: any grid-rendering page needs sort + density controls
persisted to localStorage and hydrated before the first render.
categories.html already had this; index.html only had sort with no persistence.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Files touched
Diff
commit d173ece24e8aaa2c720689ba0e431d4818dab0d0
Author: SteveStudio2 <steve@designerwallcoverings.com>
Date: Tue May 19 17:27:21 2026 -0700
index: add density slider + localStorage hydration for sort/filter/density
Standing-rule fix: any grid-rendering page needs sort + density controls
persisted to localStorage and hydrated before the first render.
categories.html already had this; index.html only had sort with no persistence.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
public/index.html | 36 +++++++++++++++++++++++++++++++-----
1 file changed, 31 insertions(+), 5 deletions(-)
diff --git a/public/index.html b/public/index.html
index a867fbf..5a6abcb 100644
--- a/public/index.html
+++ b/public/index.html
@@ -12,6 +12,7 @@
--rule: #2a2a2e; --gold: #d4a04a; --good: #8fb89a; --warn: #d8b04a; --bad: #c87a6e;
--serif: ui-serif, Georgia, "Times New Roman", serif;
--mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
+ --card-min: 240px;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; background: var(--bg); color: var(--ink); font: 400 14px/1.45 -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif; min-height: 100vh; }
@@ -35,7 +36,9 @@
main { padding: 22px 26px 60px; max-width: 1600px; margin: 0 auto; }
- .chips { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; }
+ .chips { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--card-min), 1fr)); gap: 10px; }
+ header .controls .density { display: flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: 10px; color: var(--ink-mute); letter-spacing: 0.10em; text-transform: uppercase; }
+ header .controls input[type=range] { width: 110px; cursor: pointer; }
.chip {
background: var(--bg-2); border: 1px solid var(--rule); border-radius: 4px;
padding: 12px 14px 14px; transition: transform 120ms ease, border-color 120ms ease, background 120ms ease;
@@ -73,6 +76,7 @@
<option value="sessions">Sessions (7d)</option>
<option value="template">Template</option>
</select>
+ <span class="density">density <input id="density" type="range" min="160" max="380" step="20"></span>
<button id="refresh">Refresh</button>
</div>
<div class="meta">
@@ -94,8 +98,16 @@ const esc = (s) => String(s == null ? '' : s).replace(/&/g,'&').replace(/</g
let PROPERTIES = [];
let METRICS = {};
-let SORT = 'alpha';
-let FILTER = '';
+// Hydrate persisted controls BEFORE first render so the grid doesn't flash defaults.
+let SORT = localStorage.getItem('chips.sort') || 'alpha';
+let FILTER = localStorage.getItem('chips.filter') || '';
+
+function applyDensity(px) {
+ document.documentElement.style.setProperty('--card-min', px + 'px');
+ const el = document.getElementById('density');
+ if (el) el.value = px;
+ localStorage.setItem('chips.density', px);
+}
function fmtNum(n) {
if (n == null) return '—';
@@ -193,10 +205,24 @@ async function loadMetrics() {
}
}
-$('#filter').addEventListener('input', e => { FILTER = e.target.value; applyFilterSort(); });
-$('#sort').addEventListener('change', e => { SORT = e.target.value; applyFilterSort(); });
+$('#filter').addEventListener('input', e => {
+ FILTER = e.target.value;
+ localStorage.setItem('chips.filter', FILTER);
+ applyFilterSort();
+});
+$('#sort').addEventListener('change', e => {
+ SORT = e.target.value;
+ localStorage.setItem('chips.sort', SORT);
+ applyFilterSort();
+});
+$('#density').addEventListener('input', e => applyDensity(parseInt(e.target.value, 10)));
$('#refresh').addEventListener('click', loadMetrics);
+// Reflect hydrated values in the controls before kicking off the first load.
+$('#filter').value = FILTER;
+$('#sort').value = SORT;
+applyDensity(parseInt(localStorage.getItem('chips.density') || '240', 10));
+
loadProperties();
</script>
</body></html>
← 331b54b categories: harden external chip links with rel="noopener no
·
back to Analytics Chips
·
(newest)