← back to Designer Wallcoverings
auto-save: 2026-06-22T14:06:44 (2 files) — shopify/collection-layout-override.json shopify/sections/
d61b657d06336e711de2d8f8bb3bb08a8d3ce8eb · 2026-06-22 14:06:49 -0700 · Steve Abrams
Files touched
A shopify/collection-layout-override.jsonA shopify/sections/collection-filters-horizontal.liquidA shopify/sections/collection-toolbar.liquid
Diff
commit d61b657d06336e711de2d8f8bb3bb08a8d3ce8eb
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon Jun 22 14:06:49 2026 -0700
auto-save: 2026-06-22T14:06:44 (2 files) — shopify/collection-layout-override.json shopify/sections/
---
shopify/collection-layout-override.json | 43 +++
.../sections/collection-filters-horizontal.liquid | 261 +++++++++++++++
shopify/sections/collection-toolbar.liquid | 357 +++++++++++++++++++++
3 files changed, 661 insertions(+)
diff --git a/shopify/collection-layout-override.json b/shopify/collection-layout-override.json
new file mode 100644
index 00000000..3a9ae32c
--- /dev/null
+++ b/shopify/collection-layout-override.json
@@ -0,0 +1,43 @@
+{
+ "sections": {
+ "main": {
+ "type": "collection",
+ "settings": {
+ "show_collection_image": true,
+ "show_description": true,
+ "sorting": false,
+ "show_filters": false,
+ "layout": "default",
+ "products_per_row": 4,
+ "number_of_rows": 2
+ }
+ },
+ "collection-toolbar": {
+ "type": "collection-toolbar",
+ "settings": {
+ "show_sort": true,
+ "show_density": true,
+ "show_search": true,
+ "density_min": 3,
+ "density_max": 12,
+ "density_default": 4
+ }
+ },
+ "collection-filters": {
+ "type": "collection-filters-horizontal",
+ "settings": {
+ "show_color": true,
+ "show_style": true,
+ "show_brand": true,
+ "show_durability": true,
+ "show_price": true,
+ "layout": "horizontal"
+ }
+ }
+ },
+ "order": [
+ "collection-filters",
+ "collection-toolbar",
+ "main"
+ ]
+}
diff --git a/shopify/sections/collection-filters-horizontal.liquid b/shopify/sections/collection-filters-horizontal.liquid
new file mode 100644
index 00000000..c02a9516
--- /dev/null
+++ b/shopify/sections/collection-filters-horizontal.liquid
@@ -0,0 +1,261 @@
+{%- comment -%}
+ Horizontal Collection Filters — Replaces vertical sidebar filters
+
+ Features:
+ - Horizontal tab/chip layout for Color, Style, Brand, Durability, Price
+ - Wraps on mobile
+ - Active state persistence via URL params
+ - Accessible ARIA labels
+
+ Revision: 2026-06-22
+{%- endcomment -%}
+
+<div class="collection-filters" data-section-id="{{ section.id }}">
+ <style>
+ .collection-filters {
+ display: flex;
+ gap: 8px;
+ flex-wrap: wrap;
+ align-items: center;
+ padding: 16px 0;
+ border-bottom: 1px solid var(--border-color, rgba(0,0,0,0.1));
+ margin-bottom: 20px;
+ }
+
+ .filter-group {
+ display: flex;
+ gap: 6px;
+ align-items: center;
+ }
+
+ .filter-label {
+ font-size: 10px;
+ letter-spacing: 0.32em;
+ text-transform: uppercase;
+ font-weight: 700;
+ color: var(--text-muted, rgba(0,0,0,0.6));
+ margin-right: 4px;
+ }
+
+ .filter-chip {
+ padding: 6px 12px;
+ font-size: 11px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ font-weight: 600;
+ color: var(--text-color, inherit);
+ background: transparent;
+ border: 1px solid var(--border-color, rgba(0,0,0,0.12));
+ border-radius: 20px;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ text-decoration: none;
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ }
+
+ .filter-chip:hover {
+ border-color: var(--accent-color, rgba(0,0,0,0.3));
+ background: var(--bg-hover, rgba(0,0,0,0.02));
+ }
+
+ .filter-chip.active {
+ background: var(--accent-color, #000);
+ color: #fff;
+ border-color: var(--accent-color, #000);
+ }
+
+ .filter-chip .close {
+ font-size: 12px;
+ font-weight: 700;
+ opacity: 0.6;
+ transition: opacity 0.2s;
+ }
+
+ .filter-chip:hover .close {
+ opacity: 1;
+ }
+
+ .filter-divider {
+ width: 1px;
+ height: 20px;
+ background: var(--border-color, rgba(0,0,0,0.1));
+ margin: 0 4px;
+ }
+
+ .clear-filters {
+ font-size: 10px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ font-weight: 600;
+ color: var(--accent-color, #000);
+ background: transparent;
+ border: 0;
+ cursor: pointer;
+ padding: 0;
+ margin-left: auto;
+ transition: opacity 0.2s;
+ }
+
+ .clear-filters:hover {
+ opacity: 0.7;
+ }
+
+ /* Mobile responsive */
+ @media (max-width: 720px) {
+ .collection-filters {
+ gap: 6px;
+ padding: 12px 0;
+ }
+
+ .filter-label {
+ display: none;
+ }
+
+ .filter-divider {
+ display: none;
+ }
+
+ .clear-filters {
+ margin-left: 0;
+ margin-top: 8px;
+ flex: 1 1 100%;
+ }
+ }
+ </style>
+
+ {%- assign active_filters = request.params -%}
+
+ <div class="filter-group">
+ <span class="filter-label">Filters</span>
+ </div>
+
+ {%- if section.settings.show_color -%}
+ <div class="filter-group">
+ <span class="filter-label">Color</span>
+ {%- for color in collection.metafields.custom.colors -%}
+ {%- assign color_url = request.path | append: '?color=' | append: color -%}
+ <a href="{{ color_url }}" class="filter-chip {% if request.params.color == color %}active{% endif %}">
+ {{ color }}
+ </a>
+ {%- endfor -%}
+ </div>
+ {%- endif -%}
+
+ {%- if section.settings.show_style -%}
+ <div class="filter-group">
+ <span class="filter-label">Style</span>
+ <button class="filter-chip" data-filter="style" aria-label="Filter by style">
+ Style
+ </button>
+ </div>
+ {%- endif -%}
+
+ {%- if section.settings.show_brand -%}
+ <div class="filter-group">
+ <span class="filter-label">Brand</span>
+ <button class="filter-chip" data-filter="brand" aria-label="Filter by brand">
+ Brand
+ </button>
+ </div>
+ {%- endif -%}
+
+ {%- if section.settings.show_durability -%}
+ <div class="filter-group">
+ <span class="filter-label">Durability</span>
+ <button class="filter-chip" data-filter="durability" aria-label="Filter by durability">
+ Durability
+ </button>
+ </div>
+ {%- endif -%}
+
+ {%- if section.settings.show_price -%}
+ <div class="filter-group">
+ <span class="filter-label">Price</span>
+ <button class="filter-chip" data-filter="price" aria-label="Filter by price">
+ Price
+ </button>
+ </div>
+ {%- endif -%}
+
+ {%- if active_filters -%}
+ <button class="clear-filters" aria-label="Clear all filters">
+ Clear Filters
+ </button>
+ {%- endif -%}
+</div>
+
+<script>
+(function() {
+ const clearBtn = document.querySelector('.clear-filters');
+ if (clearBtn) {
+ clearBtn.addEventListener('click', function() {
+ window.location.href = window.location.pathname;
+ });
+ }
+
+ // Future: Wire up filter dropdowns / modals for more complex filtering
+ // This is a simplified version that shows the chip layout
+})();
+</script>
+
+{% schema %}
+{
+ "name": "Collection Filters (Horizontal)",
+ "description": "Horizontal filter chips for collection pages",
+ "settings": [
+ {
+ "type": "checkbox",
+ "id": "show_color",
+ "label": "Show color filter",
+ "default": true
+ },
+ {
+ "type": "checkbox",
+ "id": "show_style",
+ "label": "Show style filter",
+ "default": true
+ },
+ {
+ "type": "checkbox",
+ "id": "show_brand",
+ "label": "Show brand filter",
+ "default": true
+ },
+ {
+ "type": "checkbox",
+ "id": "show_durability",
+ "label": "Show durability filter",
+ "default": true
+ },
+ {
+ "type": "checkbox",
+ "id": "show_price",
+ "label": "Show price filter",
+ "default": true
+ },
+ {
+ "type": "select",
+ "id": "layout",
+ "label": "Layout",
+ "options": [
+ {
+ "value": "horizontal",
+ "label": "Horizontal"
+ },
+ {
+ "value": "vertical",
+ "label": "Vertical"
+ }
+ ],
+ "default": "horizontal"
+ }
+ ],
+ "presets": [
+ {
+ "name": "Collection Filters (Horizontal)"
+ }
+ ]
+}
+{% endschema %}
diff --git a/shopify/sections/collection-toolbar.liquid b/shopify/sections/collection-toolbar.liquid
new file mode 100644
index 00000000..7cb2e83e
--- /dev/null
+++ b/shopify/sections/collection-toolbar.liquid
@@ -0,0 +1,357 @@
+{%- comment -%}
+ Collection Toolbar — Horizontal sort + grid density slider + search
+ Replaces Shopify's native sorting/filtering UI with a unified toolbar.
+
+ Features:
+ - Sort dropdown (Newest, Color, Style, SKU, Title, Price)
+ - Grid density slider (3–12 columns)
+ - localStorage persistence
+ - Responsive mobile stacking
+
+ Revision: 2026-06-22
+{%- endcomment -%}
+
+<div class="collection-toolbar" data-section-id="{{ section.id }}">
+ <style>
+ .collection-toolbar {
+ display: flex;
+ gap: 16px;
+ align-items: center;
+ justify-content: space-between;
+ flex-wrap: wrap;
+ padding: 20px 0;
+ border-bottom: 1px solid var(--border-color, rgba(0,0,0,0.1));
+ margin-bottom: 24px;
+ }
+
+ .toolbar-left {
+ display: flex;
+ gap: 14px;
+ align-items: center;
+ flex-wrap: wrap;
+ }
+
+ .toolbar-label {
+ font-size: 11px;
+ letter-spacing: 0.22em;
+ text-transform: uppercase;
+ font-weight: 600;
+ color: var(--text-muted, rgba(0,0,0,0.6));
+ }
+
+ #collectionSort {
+ background: transparent;
+ border: 1px solid var(--border-color, rgba(0,0,0,0.12));
+ padding: 6px 10px;
+ font-family: inherit;
+ font-size: 12px;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ font-weight: 500;
+ color: var(--text-color, inherit);
+ cursor: pointer;
+ transition: all 0.2s ease;
+ }
+
+ #collectionSort:hover {
+ border-color: var(--accent-color, rgba(0,0,0,0.3));
+ }
+
+ #collectionSort:focus {
+ outline: 2px solid var(--accent-color, #000);
+ outline-offset: 2px;
+ }
+
+ .density-control {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 6px 0;
+ }
+
+ .density-control input[type="range"] {
+ flex: 0 0 120px;
+ -webkit-appearance: none;
+ appearance: none;
+ height: 1px;
+ background: var(--border-color, rgba(0,0,0,0.1));
+ outline: none;
+ cursor: pointer;
+ }
+
+ .density-control input[type="range"]::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ appearance: none;
+ width: 13px;
+ height: 13px;
+ background: var(--accent-color, #000);
+ border-radius: 50%;
+ cursor: pointer;
+ transition: transform 0.2s ease;
+ }
+
+ .density-control input[type="range"]::-webkit-slider-thumb:hover {
+ transform: scale(1.2);
+ }
+
+ .density-control input[type="range"]::-moz-range-thumb {
+ width: 13px;
+ height: 13px;
+ background: var(--accent-color, #000);
+ border-radius: 50%;
+ border: 0;
+ cursor: pointer;
+ transition: transform 0.2s ease;
+ }
+
+ .density-control input[type="range"]::-moz-range-thumb:hover {
+ transform: scale(1.2);
+ }
+
+ .density-display {
+ font-size: 11px;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ font-weight: 600;
+ color: var(--text-muted, rgba(0,0,0,0.6));
+ min-width: 60px;
+ text-align: right;
+ }
+
+ .toolbar-search {
+ flex: 0 1 200px;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ border-bottom: 1px solid var(--border-color, rgba(0,0,0,0.1));
+ padding: 4px 0;
+ }
+
+ .toolbar-search input {
+ flex: 1;
+ background: transparent;
+ border: 0;
+ padding: 4px 0;
+ font-family: inherit;
+ font-size: 12px;
+ letter-spacing: 0.04em;
+ color: var(--text-color, inherit);
+ outline: none;
+ }
+
+ .toolbar-search input::placeholder {
+ color: var(--text-muted, rgba(0,0,0,0.4));
+ }
+
+ .toolbar-search svg {
+ width: 14px;
+ height: 14px;
+ stroke: var(--text-muted, rgba(0,0,0,0.4));
+ fill: none;
+ stroke-width: 1.5;
+ flex-shrink: 0;
+ }
+
+ /* Mobile responsive */
+ @media (max-width: 720px) {
+ .collection-toolbar {
+ gap: 12px;
+ }
+
+ .toolbar-left {
+ flex: 1 1 100%;
+ order: 1;
+ }
+
+ .toolbar-search {
+ flex: 1 1 100%;
+ order: 2;
+ margin-top: 8px;
+ }
+
+ .density-control {
+ display: none;
+ }
+ }
+ </style>
+
+ <div class="toolbar-left">
+ <label for="collectionSort" class="toolbar-label">Sort</label>
+ <select id="collectionSort" aria-label="Sort products">
+ <option value="newest">Newest</option>
+ <option value="color">Color</option>
+ <option value="style">Style</option>
+ <option value="sku">SKU A→Z</option>
+ <option value="title">Title A→Z</option>
+ <option value="price-asc">Price ↑</option>
+ <option value="price-desc">Price ↓</option>
+ </select>
+
+ <div class="density-control">
+ <span class="toolbar-label">Grid</span>
+ <input type="range" id="densitySlider" min="3" max="12" value="4" aria-label="Grid density">
+ <div class="density-display"><span id="densityLabel">4</span> col</div>
+ </div>
+ </div>
+
+ {% if section.settings.show_search %}
+ <div class="toolbar-search">
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
+ <circle cx="11" cy="11" r="8"></circle>
+ <path d="m21 21-4.35-4.35"></path>
+ </svg>
+ <input type="text" id="collectionSearch" placeholder="Search products…" aria-label="Search products">
+ </div>
+ {% endif %}
+</div>
+
+<script>
+(function() {
+ const sortSelect = document.getElementById('collectionSort');
+ const densitySlider = document.getElementById('densitySlider');
+ const densityLabel = document.getElementById('densityLabel');
+ const searchInput = document.getElementById('collectionSearch');
+ const STORAGE_KEY_SORT = 'dw_collection_sort';
+ const STORAGE_KEY_DENSITY = 'dw_collection_density';
+ const STORAGE_KEY_SEARCH = 'dw_collection_search';
+
+ // Load saved state
+ try {
+ const savedSort = localStorage.getItem(STORAGE_KEY_SORT);
+ if (savedSort) sortSelect.value = savedSort;
+
+ const savedDensity = localStorage.getItem(STORAGE_KEY_DENSITY);
+ if (savedDensity) {
+ densitySlider.value = savedDensity;
+ densityLabel.textContent = savedDensity;
+ updateGridDensity(parseInt(savedDensity));
+ }
+
+ const savedSearch = localStorage.getItem(STORAGE_KEY_SEARCH);
+ if (savedSearch) searchInput.value = savedSearch;
+ } catch (e) {}
+
+ // Sort change
+ sortSelect.addEventListener('change', function() {
+ try { localStorage.setItem(STORAGE_KEY_SORT, this.value); } catch (e) {}
+ applySort(this.value);
+ });
+
+ // Density slider
+ densitySlider.addEventListener('input', function() {
+ const cols = parseInt(this.value);
+ densityLabel.textContent = cols;
+ try { localStorage.setItem(STORAGE_KEY_DENSITY, cols); } catch (e) {}
+ updateGridDensity(cols);
+ });
+
+ // Search
+ searchInput.addEventListener('input', debounce(function() {
+ try { localStorage.setItem(STORAGE_KEY_SEARCH, this.value); } catch (e) {}
+ applySearch(this.value);
+ }, 300));
+
+ function updateGridDensity(cols) {
+ const productGrid = document.querySelector('[role="list"]') || document.querySelector('.grid') || document.querySelector('[data-product-grid]');
+ if (productGrid) {
+ productGrid.style.gridTemplateColumns = `repeat(${cols}, 1fr)`;
+ productGrid.setAttribute('data-cols', cols);
+ }
+ }
+
+ function applySort(mode) {
+ const url = new URL(window.location);
+ if (mode === 'newest') {
+ url.searchParams.delete('sort_by');
+ } else {
+ // Map DW sort modes to Shopify's sort_by values
+ const sortMap = {
+ 'title': 'title-ascending',
+ 'price-asc': 'price-ascending',
+ 'price-desc': 'price-descending'
+ };
+ url.searchParams.set('sort_by', sortMap[mode] || mode);
+ }
+ window.location.href = url.toString();
+ }
+
+ function applySearch(query) {
+ if (query.trim() === '') {
+ window.location.href = window.location.pathname;
+ } else {
+ const url = new URL(window.location);
+ url.searchParams.set('q', query);
+ window.location.href = url.toString();
+ }
+ }
+
+ function debounce(fn, delay) {
+ let timer;
+ return function(...args) {
+ clearTimeout(timer);
+ timer = setTimeout(() => fn.apply(this, args), delay);
+ };
+ }
+
+ // Initialize grid on page load
+ window.addEventListener('load', function() {
+ updateGridDensity(parseInt(densitySlider.value));
+ });
+})();
+</script>
+
+{% schema %}
+{
+ "name": "Collection Toolbar",
+ "description": "Horizontal sort, grid density, and search for collection pages",
+ "settings": [
+ {
+ "type": "checkbox",
+ "id": "show_sort",
+ "label": "Show sort dropdown",
+ "default": true
+ },
+ {
+ "type": "checkbox",
+ "id": "show_density",
+ "label": "Show grid density slider",
+ "default": true
+ },
+ {
+ "type": "checkbox",
+ "id": "show_search",
+ "label": "Show search input",
+ "default": true
+ },
+ {
+ "type": "range",
+ "id": "density_min",
+ "label": "Minimum columns",
+ "min": 2,
+ "max": 6,
+ "default": 3
+ },
+ {
+ "type": "range",
+ "id": "density_max",
+ "label": "Maximum columns",
+ "min": 6,
+ "max": 12,
+ "default": 12
+ },
+ {
+ "type": "range",
+ "id": "density_default",
+ "label": "Default columns",
+ "min": 2,
+ "max": 12,
+ "default": 4
+ }
+ ],
+ "presets": [
+ {
+ "name": "Collection Toolbar"
+ }
+ ]
+}
+{% endschema %}
← ce69f4cc Backup: live PDP section pre-MOQ-push (rollback source)
·
back to Designer Wallcoverings
·
Bucket B Coordonné roll-variant recovery script (feed-first, 248277a7 →