[object Object]

← 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 →