← back to Apartmentwallpaper
Update grid density slider to desktop-only (3-12 columns)
48950fe3672c331a9afe026e9d784af0c1d60b81 · 2026-06-23 07:14:16 -0700 · Steve Abrams
- Hidden entirely on mobile (< 769px)
- Desktop only: full 3-12 column slider
- Smart name hiding: product titles hide at 6+ columns
- localStorage persistence of user preference
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Files touched
Diff
commit 48950fe3672c331a9afe026e9d784af0c1d60b81
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Jun 23 07:14:16 2026 -0700
Update grid density slider to desktop-only (3-12 columns)
- Hidden entirely on mobile (< 769px)
- Desktop only: full 3-12 column slider
- Smart name hiding: product titles hide at 6+ columns
- localStorage persistence of user preference
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
---
public/index.html | 287 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 287 insertions(+)
diff --git a/public/index.html b/public/index.html
index 7895e8c..58db237 100644
--- a/public/index.html
+++ b/public/index.html
@@ -807,6 +807,293 @@ loadGridPage();
Inject before <script src="/hero-4grid.js" defer></script>
<script src="/dw-theme-nav.js" defer></script>
+<!-- GRID DENSITY SLIDER (DESKTOP ONLY, 3-12 COLUMNS) -->
+<script>
+(function(){
+ const CFG = {
+ storageKey: 'dw_grid_cols',
+ minCols: 3,
+ maxCols: 12,
+ defaultCols: 3,
+ mobileBreakpoint: 768,
+ nameHideThreshold: 5 // Hide names when > 5 columns
+ };
+
+ const GRID_SEL = [
+ '[data-collection-grid]',
+ '.collection-grid',
+ '.product-grid',
+ '[role="region"] .grid',
+ 'main .grid',
+ '.grid'
+ ];
+
+ // Common product name selectors
+ const NAME_SEL = [
+ '.product-name',
+ '.card-title',
+ '.product-title',
+ 'h3',
+ 'h2',
+ '[data-product-name]',
+ '.title'
+ ];
+
+ function findGrid() {
+ for (const sel of GRID_SEL) {
+ const el = document.querySelector(sel);
+ if (el && el.children.length > 0) return el;
+ }
+ return null;
+ }
+
+ function findNameElements(grid) {
+ // Look for names within grid items
+ const names = [];
+ const items = grid.querySelectorAll(':scope > *');
+
+ for (const item of items) {
+ for (const sel of NAME_SEL) {
+ const name = item.querySelector(sel);
+ if (name && name.textContent.trim()) {
+ names.push(name);
+ break; // One name per item
+ }
+ }
+ }
+
+ return names;
+ }
+
+ function init() {
+ const grid = findGrid();
+ if (!grid || document.getElementById('dw-density-slider')) return;
+
+ const html = `
+ <div id="dw-density-slider" class="dw-grid-control">
+ <div class="dw-grid-label">Columns</div>
+ <div class="dw-grid-buttons">
+ <button data-cols="3" aria-label="3 columns" title="3" class="active">3</button>
+ <button data-cols="4" aria-label="4 columns" title="4">4</button>
+ <button data-cols="5" aria-label="5 columns" title="5">5</button>
+ <button data-cols="6" aria-label="6 columns" title="6">6</button>
+ </div>
+ <input type="range" id="dw-col-range" class="dw-slider" min="3" max="12" step="1" value="3" aria-label="Grid columns">
+ <span id="dw-col-label" class="dw-col-label">3 cols</span>
+ </div>
+ `;
+
+ const style = document.createElement('style');
+ style.textContent = `
+ #dw-density-slider {
+ display: none;
+ }
+
+ .dw-grid-label {
+ font-size: 11px;
+ font-weight: 700;
+ letter-spacing: .08em;
+ text-transform: uppercase;
+ color: #666;
+ order: -1;
+ flex-basis: 100%;
+ }
+
+ .dw-grid-buttons {
+ display: none;
+ }
+
+ .dw-grid-buttons button {
+ flex: 1;
+ min-width: 36px;
+ height: 36px;
+ border: 1px solid #ddd;
+ background: #fff;
+ color: #666;
+ font-weight: 600;
+ font-size: 13px;
+ cursor: pointer;
+ border-radius: 4px;
+ transition: all .15s;
+ touch-action: manipulation;
+ }
+
+ .dw-grid-buttons button:active {
+ transform: scale(0.95);
+ }
+
+ .dw-grid-buttons button.active {
+ background: #000;
+ color: #fff;
+ border-color: #000;
+ }
+
+ .dw-slider {
+ display: none;
+ }
+
+ #dw-col-label {
+ display: none;
+ }
+
+ /* Smart name hiding: hide names when > 5 columns */
+ [data-grid-cols="6"] .product-name,
+ [data-grid-cols="6"] .card-title,
+ [data-grid-cols="6"] .product-title,
+ [data-grid-cols="6"] .title {
+ display: none !important;
+ }
+
+ @media (min-width: 769px) {
+ #dw-density-slider {
+ display: flex;
+ flex-wrap: nowrap;
+ gap: 16px;
+ background: transparent;
+ border: none;
+ padding: 12px 0;
+ margin: 24px 0;
+ width: auto;
+ min-width: fit-content;
+ flex-shrink: 0;
+ position: relative;
+ z-index: 10;
+ }
+
+ .dw-grid-label {
+ flex-basis: auto;
+ order: 0;
+ flex-shrink: 0;
+ }
+
+ .dw-grid-buttons {
+ display: none;
+ }
+
+ .dw-slider {
+ display: block;
+ flex: 0 0 200px;
+ height: 4px;
+ border-radius: 2px;
+ background: #ddd;
+ outline: none;
+ -webkit-appearance: none;
+ appearance: none;
+ cursor: pointer;
+ }
+
+ .dw-slider::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ appearance: none;
+ width: 18px;
+ height: 18px;
+ border-radius: 50%;
+ background: #000;
+ cursor: pointer;
+ box-shadow: 0 1px 3px rgba(0,0,0,.2);
+ }
+
+ .dw-slider::-moz-range-thumb {
+ width: 18px;
+ height: 18px;
+ border-radius: 50%;
+ background: #000;
+ cursor: pointer;
+ border: 0;
+ box-shadow: 0 1px 3px rgba(0,0,0,.2);
+ }
+
+ .dw-slider::-moz-range-track {
+ background: transparent;
+ border: 0;
+ }
+
+ #dw-col-label {
+ display: block;
+ font-size: 12px;
+ color: #666;
+ min-width: 60px;
+ text-align: right;
+ }
+ }
+ `;
+ document.head.appendChild(style);
+
+ const div = document.createElement('div');
+ div.innerHTML = html;
+ grid.parentNode.insertBefore(div.firstElementChild, grid);
+
+ let cols = CFG.defaultCols;
+ try {
+ const saved = localStorage.getItem(CFG.storageKey);
+ if (saved) {
+ const n = parseInt(saved, 10);
+ if (n >= CFG.minCols && n <= CFG.maxCols) cols = n;
+ }
+ } catch (e) {}
+
+ const range = document.getElementById('dw-col-range');
+ const label = document.getElementById('dw-col-label');
+ const buttons = document.querySelectorAll('.dw-grid-buttons button');
+
+ function set(n) {
+ // Update grid columns
+ grid.style.gridTemplateColumns = `repeat(${n}, 1fr)`;
+ grid.setAttribute('data-grid-cols', n);
+
+ // Update label
+ label.textContent = `${n} col${n === 1 ? '' : 's'}`;
+
+ // Update slider
+ range.value = n;
+
+ // Update active button
+ buttons.forEach(btn => {
+ btn.classList.toggle('active', parseInt(btn.dataset.cols) === n);
+ });
+
+ // Smart name hiding: hide names if > 5 columns
+ const nameElements = findNameElements(grid);
+ nameElements.forEach(name => {
+ if (n > CFG.nameHideThreshold) {
+ name.style.display = 'none';
+ } else {
+ name.style.display = '';
+ }
+ });
+
+ // Save preference
+ try { localStorage.setItem(CFG.storageKey, String(n)); } catch (e) {}
+ }
+
+ // Event listeners
+ range.addEventListener('input', e => set(parseInt(e.target.value, 10)));
+ buttons.forEach(btn => {
+ btn.addEventListener('click', e => {
+ e.preventDefault();
+ set(parseInt(btn.dataset.cols, 10));
+ });
+ });
+
+ // Initial set
+ set(cols);
+ }
+
+ // Init on DOM ready
+ if (document.readyState === 'loading') {
+ document.addEventListener('DOMContentLoaded', init);
+ } else {
+ init();
+ }
+
+ // Retry for slow-loading grids
+ setTimeout(() => {
+ if (!document.getElementById('dw-density-slider')) init();
+ }, 500);
+})();
+
+</script>
+
<!-- SORT CONTROL PILL STYLING — Complements grid density slider -->
<script>
(function() {
← cb3473f feat: expand grid density slider range to 3-12 columns
·
back to Apartmentwallpaper
·
corner-nav: move login to its own hamburger in upper-left (p 62dd586 →