[object Object]

← back to Designer Wallcoverings

PDP: replace native variant dropdown with side-by-side name-only buttons

050da83033a49f5c759b5501002be0eadfe3b90a · 2026-06-21 18:13:29 -0700 · Steve Abrams

Inject a product-page-scoped enhancement in theme.liquid: hides the native
custom dropdown and renders one button per option value (labels pulled
dynamically from each product's variants, so it works for Single Roll / Double
Roll / yardage / Sample etc.), driving the existing .single-option-selector via
a change event so the theme handles price, variant id, URL and add-to-cart.
Idempotent, degrades to the native control if JS fails.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Files touched

Diff

commit 050da83033a49f5c759b5501002be0eadfe3b90a
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Sun Jun 21 18:13:29 2026 -0700

    PDP: replace native variant dropdown with side-by-side name-only buttons
    
    Inject a product-page-scoped enhancement in theme.liquid: hides the native
    custom dropdown and renders one button per option value (labels pulled
    dynamically from each product's variants, so it works for Single Roll / Double
    Roll / yardage / Sample etc.), driving the existing .single-option-selector via
    a change event so the theme handles price, variant id, URL and add-to-cart.
    Idempotent, degrades to the native control if JS fails.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---
 shopify/_cwFIX/layout/theme.liquid    | 49 +++++++++++++++++++++++++++++++++++
 shopify/_cwLIVE/layout/theme.liquid   | 49 +++++++++++++++++++++++++++++++++++
 shopify/_cwLIVE2/layout/theme.liquid  | 49 +++++++++++++++++++++++++++++++++++
 shopify/_cwLIVE3/layout/theme.liquid  | 49 +++++++++++++++++++++++++++++++++++
 shopify/_cwVERIFY/layout/theme.liquid | 49 +++++++++++++++++++++++++++++++++++
 5 files changed, 245 insertions(+)

diff --git a/shopify/_cwFIX/layout/theme.liquid b/shopify/_cwFIX/layout/theme.liquid
index 9e672734..24b6cb4a 100644
--- a/shopify/_cwFIX/layout/theme.liquid
+++ b/shopify/_cwFIX/layout/theme.liquid
@@ -514,6 +514,55 @@
 
 <!-- /DW -->
 
+{% if template contains 'product' %}
+<!-- DW: variant option buttons — replace native dropdown with side-by-side name-only buttons (2026-06-21) -->
+<style>
+  .dw-variant-btns{display:flex;gap:10px;margin:10px 0 4px;flex-wrap:wrap}
+  .dw-variant-btns button{flex:1 1 0;min-width:120px;padding:12px 14px;border:1px solid #111;
+    background:#fff;color:#111;font:inherit;letter-spacing:.04em;text-transform:uppercase;
+    font-size:12px;cursor:pointer;border-radius:2px;transition:background .12s,color .12s}
+  .dw-variant-btns button:hover{background:#f2f2f2}
+  .dw-variant-btns button[aria-pressed="true"],
+  .dw-variant-btns button[aria-pressed="true"]:hover{background:#111;color:#fff}
+  .dw-hide-native{display:none !important}
+</style>
+<script>
+(function(){
+  function build(){
+    var sels=document.querySelectorAll('.single-option-selector,[id^="single-option-"]');
+    Array.prototype.forEach.call(sels,function(sel){
+      if(sel.dataset.dwBtnDone) return;
+      if(!sel.options||sel.options.length<2){ sel.dataset.dwBtnDone='1'; return; }
+      sel.dataset.dwBtnDone='1';
+      var wrap=document.createElement('div'); wrap.className='dw-variant-btns';
+      Array.prototype.forEach.call(sel.options,function(opt){
+        var b=document.createElement('button');
+        b.type='button';
+        b.textContent=(opt.text||'').trim();          /* NAME ONLY, dynamic per product */
+        b.setAttribute('data-value',opt.value);
+        b.setAttribute('aria-pressed', opt.selected?'true':'false');
+        b.addEventListener('click',function(){
+          sel.value=opt.value;
+          sel.dispatchEvent(new Event('change',{bubbles:true}));
+          Array.prototype.forEach.call(wrap.querySelectorAll('button'),function(x){
+            x.setAttribute('aria-pressed', x===b?'true':'false');
+          });
+        });
+        wrap.appendChild(b);
+      });
+      var host=sel.closest('.select-wrapper')||sel.closest('.selector-wrapper')||sel.parentElement;
+      host.classList.add('dw-hide-native');
+      host.parentElement.insertBefore(wrap,host);
+    });
+  }
+  function init(){ build(); setTimeout(build,400); setTimeout(build,1200); }
+  if(document.readyState!=='loading') init();
+  else document.addEventListener('DOMContentLoaded',init);
+})();
+</script>
+<!-- /DW variant buttons -->
+{% endif %}
+
 {% comment %} DW: ItemList structured data for the Shop-by-Brand page (script tags are stripped from page body_html, so injected here) {% endcomment %}
 {% if page.handle == 'brands' %}{% render 'brands-jsonld' %}{% endif %}
 
diff --git a/shopify/_cwLIVE/layout/theme.liquid b/shopify/_cwLIVE/layout/theme.liquid
index 81e9f0b4..274f332b 100644
--- a/shopify/_cwLIVE/layout/theme.liquid
+++ b/shopify/_cwLIVE/layout/theme.liquid
@@ -514,6 +514,55 @@
 
 <!-- /DW -->
 
+{% if template contains 'product' %}
+<!-- DW: variant option buttons — replace native dropdown with side-by-side name-only buttons (2026-06-21) -->
+<style>
+  .dw-variant-btns{display:flex;gap:10px;margin:10px 0 4px;flex-wrap:wrap}
+  .dw-variant-btns button{flex:1 1 0;min-width:120px;padding:12px 14px;border:1px solid #111;
+    background:#fff;color:#111;font:inherit;letter-spacing:.04em;text-transform:uppercase;
+    font-size:12px;cursor:pointer;border-radius:2px;transition:background .12s,color .12s}
+  .dw-variant-btns button:hover{background:#f2f2f2}
+  .dw-variant-btns button[aria-pressed="true"],
+  .dw-variant-btns button[aria-pressed="true"]:hover{background:#111;color:#fff}
+  .dw-hide-native{display:none !important}
+</style>
+<script>
+(function(){
+  function build(){
+    var sels=document.querySelectorAll('.single-option-selector,[id^="single-option-"]');
+    Array.prototype.forEach.call(sels,function(sel){
+      if(sel.dataset.dwBtnDone) return;
+      if(!sel.options||sel.options.length<2){ sel.dataset.dwBtnDone='1'; return; }
+      sel.dataset.dwBtnDone='1';
+      var wrap=document.createElement('div'); wrap.className='dw-variant-btns';
+      Array.prototype.forEach.call(sel.options,function(opt){
+        var b=document.createElement('button');
+        b.type='button';
+        b.textContent=(opt.text||'').trim();          /* NAME ONLY, dynamic per product */
+        b.setAttribute('data-value',opt.value);
+        b.setAttribute('aria-pressed', opt.selected?'true':'false');
+        b.addEventListener('click',function(){
+          sel.value=opt.value;
+          sel.dispatchEvent(new Event('change',{bubbles:true}));
+          Array.prototype.forEach.call(wrap.querySelectorAll('button'),function(x){
+            x.setAttribute('aria-pressed', x===b?'true':'false');
+          });
+        });
+        wrap.appendChild(b);
+      });
+      var host=sel.closest('.select-wrapper')||sel.closest('.selector-wrapper')||sel.parentElement;
+      host.classList.add('dw-hide-native');
+      host.parentElement.insertBefore(wrap,host);
+    });
+  }
+  function init(){ build(); setTimeout(build,400); setTimeout(build,1200); }
+  if(document.readyState!=='loading') init();
+  else document.addEventListener('DOMContentLoaded',init);
+})();
+</script>
+<!-- /DW variant buttons -->
+{% endif %}
+
 <!-- cache-bust: 2026-03-25T00:54:55.724677 -->
 </head>
 
diff --git a/shopify/_cwLIVE2/layout/theme.liquid b/shopify/_cwLIVE2/layout/theme.liquid
index bf23c86e..8bd96f57 100644
--- a/shopify/_cwLIVE2/layout/theme.liquid
+++ b/shopify/_cwLIVE2/layout/theme.liquid
@@ -514,6 +514,55 @@
 
 <!-- /DW -->
 
+{% if template contains 'product' %}
+<!-- DW: variant option buttons — replace native dropdown with side-by-side name-only buttons (2026-06-21) -->
+<style>
+  .dw-variant-btns{display:flex;gap:10px;margin:10px 0 4px;flex-wrap:wrap}
+  .dw-variant-btns button{flex:1 1 0;min-width:120px;padding:12px 14px;border:1px solid #111;
+    background:#fff;color:#111;font:inherit;letter-spacing:.04em;text-transform:uppercase;
+    font-size:12px;cursor:pointer;border-radius:2px;transition:background .12s,color .12s}
+  .dw-variant-btns button:hover{background:#f2f2f2}
+  .dw-variant-btns button[aria-pressed="true"],
+  .dw-variant-btns button[aria-pressed="true"]:hover{background:#111;color:#fff}
+  .dw-hide-native{display:none !important}
+</style>
+<script>
+(function(){
+  function build(){
+    var sels=document.querySelectorAll('.single-option-selector,[id^="single-option-"]');
+    Array.prototype.forEach.call(sels,function(sel){
+      if(sel.dataset.dwBtnDone) return;
+      if(!sel.options||sel.options.length<2){ sel.dataset.dwBtnDone='1'; return; }
+      sel.dataset.dwBtnDone='1';
+      var wrap=document.createElement('div'); wrap.className='dw-variant-btns';
+      Array.prototype.forEach.call(sel.options,function(opt){
+        var b=document.createElement('button');
+        b.type='button';
+        b.textContent=(opt.text||'').trim();          /* NAME ONLY, dynamic per product */
+        b.setAttribute('data-value',opt.value);
+        b.setAttribute('aria-pressed', opt.selected?'true':'false');
+        b.addEventListener('click',function(){
+          sel.value=opt.value;
+          sel.dispatchEvent(new Event('change',{bubbles:true}));
+          Array.prototype.forEach.call(wrap.querySelectorAll('button'),function(x){
+            x.setAttribute('aria-pressed', x===b?'true':'false');
+          });
+        });
+        wrap.appendChild(b);
+      });
+      var host=sel.closest('.select-wrapper')||sel.closest('.selector-wrapper')||sel.parentElement;
+      host.classList.add('dw-hide-native');
+      host.parentElement.insertBefore(wrap,host);
+    });
+  }
+  function init(){ build(); setTimeout(build,400); setTimeout(build,1200); }
+  if(document.readyState!=='loading') init();
+  else document.addEventListener('DOMContentLoaded',init);
+})();
+</script>
+<!-- /DW variant buttons -->
+{% endif %}
+
 <!-- cache-bust: 2026-03-25T00:54:55.724677 -->
 </head>
 
diff --git a/shopify/_cwLIVE3/layout/theme.liquid b/shopify/_cwLIVE3/layout/theme.liquid
index d3c964ce..4f1d09a0 100644
--- a/shopify/_cwLIVE3/layout/theme.liquid
+++ b/shopify/_cwLIVE3/layout/theme.liquid
@@ -514,6 +514,55 @@
 
 <!-- /DW -->
 
+{% if template contains 'product' %}
+<!-- DW: variant option buttons — replace native dropdown with side-by-side name-only buttons (2026-06-21) -->
+<style>
+  .dw-variant-btns{display:flex;gap:10px;margin:10px 0 4px;flex-wrap:wrap}
+  .dw-variant-btns button{flex:1 1 0;min-width:120px;padding:12px 14px;border:1px solid #111;
+    background:#fff;color:#111;font:inherit;letter-spacing:.04em;text-transform:uppercase;
+    font-size:12px;cursor:pointer;border-radius:2px;transition:background .12s,color .12s}
+  .dw-variant-btns button:hover{background:#f2f2f2}
+  .dw-variant-btns button[aria-pressed="true"],
+  .dw-variant-btns button[aria-pressed="true"]:hover{background:#111;color:#fff}
+  .dw-hide-native{display:none !important}
+</style>
+<script>
+(function(){
+  function build(){
+    var sels=document.querySelectorAll('.single-option-selector,[id^="single-option-"]');
+    Array.prototype.forEach.call(sels,function(sel){
+      if(sel.dataset.dwBtnDone) return;
+      if(!sel.options||sel.options.length<2){ sel.dataset.dwBtnDone='1'; return; }
+      sel.dataset.dwBtnDone='1';
+      var wrap=document.createElement('div'); wrap.className='dw-variant-btns';
+      Array.prototype.forEach.call(sel.options,function(opt){
+        var b=document.createElement('button');
+        b.type='button';
+        b.textContent=(opt.text||'').trim();          /* NAME ONLY, dynamic per product */
+        b.setAttribute('data-value',opt.value);
+        b.setAttribute('aria-pressed', opt.selected?'true':'false');
+        b.addEventListener('click',function(){
+          sel.value=opt.value;
+          sel.dispatchEvent(new Event('change',{bubbles:true}));
+          Array.prototype.forEach.call(wrap.querySelectorAll('button'),function(x){
+            x.setAttribute('aria-pressed', x===b?'true':'false');
+          });
+        });
+        wrap.appendChild(b);
+      });
+      var host=sel.closest('.select-wrapper')||sel.closest('.selector-wrapper')||sel.parentElement;
+      host.classList.add('dw-hide-native');
+      host.parentElement.insertBefore(wrap,host);
+    });
+  }
+  function init(){ build(); setTimeout(build,400); setTimeout(build,1200); }
+  if(document.readyState!=='loading') init();
+  else document.addEventListener('DOMContentLoaded',init);
+})();
+</script>
+<!-- /DW variant buttons -->
+{% endif %}
+
 {% comment %} DW: ItemList structured data for the Shop-by-Brand page (script tags are stripped from page body_html, so injected here) {% endcomment %}
 {% if page.handle == 'brands' %}{% render 'brands-jsonld' %}{% endif %}
 
diff --git a/shopify/_cwVERIFY/layout/theme.liquid b/shopify/_cwVERIFY/layout/theme.liquid
index 9e672734..24b6cb4a 100644
--- a/shopify/_cwVERIFY/layout/theme.liquid
+++ b/shopify/_cwVERIFY/layout/theme.liquid
@@ -514,6 +514,55 @@
 
 <!-- /DW -->
 
+{% if template contains 'product' %}
+<!-- DW: variant option buttons — replace native dropdown with side-by-side name-only buttons (2026-06-21) -->
+<style>
+  .dw-variant-btns{display:flex;gap:10px;margin:10px 0 4px;flex-wrap:wrap}
+  .dw-variant-btns button{flex:1 1 0;min-width:120px;padding:12px 14px;border:1px solid #111;
+    background:#fff;color:#111;font:inherit;letter-spacing:.04em;text-transform:uppercase;
+    font-size:12px;cursor:pointer;border-radius:2px;transition:background .12s,color .12s}
+  .dw-variant-btns button:hover{background:#f2f2f2}
+  .dw-variant-btns button[aria-pressed="true"],
+  .dw-variant-btns button[aria-pressed="true"]:hover{background:#111;color:#fff}
+  .dw-hide-native{display:none !important}
+</style>
+<script>
+(function(){
+  function build(){
+    var sels=document.querySelectorAll('.single-option-selector,[id^="single-option-"]');
+    Array.prototype.forEach.call(sels,function(sel){
+      if(sel.dataset.dwBtnDone) return;
+      if(!sel.options||sel.options.length<2){ sel.dataset.dwBtnDone='1'; return; }
+      sel.dataset.dwBtnDone='1';
+      var wrap=document.createElement('div'); wrap.className='dw-variant-btns';
+      Array.prototype.forEach.call(sel.options,function(opt){
+        var b=document.createElement('button');
+        b.type='button';
+        b.textContent=(opt.text||'').trim();          /* NAME ONLY, dynamic per product */
+        b.setAttribute('data-value',opt.value);
+        b.setAttribute('aria-pressed', opt.selected?'true':'false');
+        b.addEventListener('click',function(){
+          sel.value=opt.value;
+          sel.dispatchEvent(new Event('change',{bubbles:true}));
+          Array.prototype.forEach.call(wrap.querySelectorAll('button'),function(x){
+            x.setAttribute('aria-pressed', x===b?'true':'false');
+          });
+        });
+        wrap.appendChild(b);
+      });
+      var host=sel.closest('.select-wrapper')||sel.closest('.selector-wrapper')||sel.parentElement;
+      host.classList.add('dw-hide-native');
+      host.parentElement.insertBefore(wrap,host);
+    });
+  }
+  function init(){ build(); setTimeout(build,400); setTimeout(build,1200); }
+  if(document.readyState!=='loading') init();
+  else document.addEventListener('DOMContentLoaded',init);
+})();
+</script>
+<!-- /DW variant buttons -->
+{% endif %}
+
 {% comment %} DW: ItemList structured data for the Shop-by-Brand page (script tags are stripped from page body_html, so injected here) {% endcomment %}
 {% if page.handle == 'brands' %}{% render 'brands-jsonld' %}{% endif %}
 

← 195e6068 Harden Boost price hide/restore CSS: grid-scope hide + theme  ·  back to Designer Wallcoverings  ·  rename inventory sweep to .mjs to silence MODULE_TYPELESS_PA 43eef3c8 →