← back to Dw Theme Hamburger

snippets/colorway-siblings.liquid

118 lines

{% comment %}
  Colorway Siblings — shows other colors of the same pattern as clickable thumbnails
  Uses dwc.pattern_name metafield or parses from title
{% endcomment %}

{%- assign pattern_name = product.metafields.custom.pattern_name.value | default: product.metafields.dwc.pattern_name.value | default: product.metafields.custom.design_name.value -%}

{%- unless pattern_name != blank -%}
  {%- assign pattern_parts = product.title | split: " - " -%}
  {%- if pattern_parts.size >= 2 -%}
    {%- assign pattern_name = pattern_parts[0] | strip -%}
  {%- else -%}
    {%- assign pattern_parts = product.title | split: " – " -%}
    {%- if pattern_parts.size >= 2 -%}
      {%- assign pattern_name = pattern_parts[0] | strip -%}
    {%- else -%}
      {%- assign pipe_parts = product.title | split: " | " -%}
      {%- if pipe_parts.size >= 2 -%}
        {%- assign pattern_name = pipe_parts[0] | strip -%}
      {%- endif -%}
    {%- endif -%}
  {%- endif -%}
{%- endunless -%}

{%- if pattern_name != blank and pattern_name.size > 2 -%}
  <div id="dw-colorway-siblings" style="display:none;padding:14px 0 8px;text-align:center;">
    <p style="font-family:Lora,serif;font-size:15px;font-weight:500;color:#3D4246;margin:0 0 10px;letter-spacing:-0.01em;">
      Other Colorways
    </p>
    <div id="dw-colorway-thumbs" style="display:flex;gap:8px;justify-content:center;flex-wrap:wrap;max-width:600px;margin:0 auto;"></div>
  </div>

  <script>
  (function() {
    var currentHandle = {{ product.handle | json }};
    var currentVendor = {{ product.vendor | json }};
    var searchTerm = {{ pattern_name | json }};
    if (!searchTerm || searchTerm.length < 3) return;

    fetch('/search/suggest.json?q=' + encodeURIComponent(searchTerm) + '&resources[type]=product&resources[limit]=24', { credentials: 'same-origin' })
      .then(function(r) { return r.ok ? r.json() : null; })
      .then(function(data) {
        if (!data || !data.resources || !data.resources.results) return;
        var products = data.resources.results.products || [];
        var matchLower = searchTerm.toLowerCase();
        var container = document.getElementById('dw-colorway-thumbs');
        var section = document.getElementById('dw-colorway-siblings');
        if (!container || !section) return;

        var siblings = [];
        for (var i = 0; i < products.length; i++) {
          var p = products[i];
          /* Skip current product */
          if (p.handle === currentHandle) continue;
          /* Must match pattern name in title */
          if ((p.title || '').toLowerCase().indexOf(matchLower) < 0) continue;
          /* Must match vendor to avoid cross-vendor contamination */
          if (currentVendor && (p.vendor || '').toLowerCase() !== currentVendor.toLowerCase()) continue;
          /* Must have an image */
          if (!p.image && !(p.featured_image && p.featured_image.url)) continue;

          var imgUrl = (p.featured_image && p.featured_image.url) ? p.featured_image.url : p.image;

          /* Extract color: remove pattern name and vendor */
          var label = (p.title || '');
          var pipeIdx = label.indexOf(' | ');
          if (pipeIdx > 0) label = label.substring(0, pipeIdx);
          var dashIdx = label.indexOf(' - ');
          if (dashIdx > 0) {
            label = label.substring(dashIdx + 3).trim();
          } else {
            var pLower = label.toLowerCase().indexOf(matchLower);
            if (pLower === 0) label = label.substring(searchTerm.length).trim();
          }
          label = label.replace(/\s*(Wallcoverings?|Fabrics?|Murals?|Commercial)\s*/gi, '').trim();
          if (!label) label = 'View';

          siblings.push({ color: label, image: imgUrl, url: p.url || ('/products/' + p.handle) });
        }

        if (siblings.length === 0) return;
        siblings.sort(function(a, b) { return a.color.localeCompare(b.color); });

        for (var j = 0; j < siblings.length; j++) {
          var s = siblings[j];
          var a = document.createElement('a');
          a.href = s.url;
          a.title = s.color;
          a.style.cssText = 'display:flex;flex-direction:column;align-items:center;gap:4px;text-decoration:none;width:72px;';

          var wrap = document.createElement('div');
          wrap.style.cssText = 'width:64px;height:64px;border-radius:8px;overflow:hidden;border:2px solid #e5e2dc;transition:border-color 0.15s,box-shadow 0.15s;';
          a.onmouseover = function() { this.firstChild.style.borderColor = '#3D4246'; this.firstChild.style.boxShadow = '0 2px 8px rgba(0,0,0,0.1)'; };
          a.onmouseout = function() { this.firstChild.style.borderColor = '#e5e2dc'; this.firstChild.style.boxShadow = 'none'; };

          var img = document.createElement('img');
          img.src = s.image;
          img.alt = s.color;
          img.loading = 'lazy';
          img.style.cssText = 'width:100%;height:100%;object-fit:cover;';
          wrap.appendChild(img);
          a.appendChild(wrap);

          var nameSpan = document.createElement('span');
          nameSpan.textContent = s.color;
          nameSpan.style.cssText = 'font-size:10px;color:#666;line-height:1.2;max-width:72px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;text-align:center;';
          a.appendChild(nameSpan);

          container.appendChild(a);
        }

        section.style.display = '';
      })
      .catch(function() {});
  })();
  </script>
{%- endif -%}