← back to Dw Theme Hamburger

snippets/product-gallery.liquid

227 lines

{% comment %}Updated: 2026-03-23T19:12:17.978750{% endcomment %}
{% comment %}
@param images_layout
  Image layout setting - masonry, slideshow or list
@param use_masonry
@param product
@param variant
@param selected_media
@param enable_zoom
{% endcomment %}

<div
  class="
    product-images
    product-gallery
    {% if images_layout == 'masonry' %}
      product-images-masonry
      product-images-masonry-{{ product.media.size }}
    {% endif %}
    "
  {% if images_layout == 'masonry' and product.media.size > 1 %}
    data-masonry-gallery
  {% endif %}
  data-product-gallery
  data-product-gallery-layout="{{ images_layout }}"
  {% if enable_zoom %}data-product-gallery-image-zoom{% endif %}
>
  {% if images_layout == 'masonry' and product.media.size > 1 %}
    <div class="product-image-masonry-sizer" data-masonry-image-sizer></div>
  {% endif %}
    <div
      class="
        product-gallery--viewport
        {% if images_layout == 'slideshow' and product.media.size > 1 %}product-gallery--viewport--has-navigation{% endif %}
      "
      data-product-gallery-viewport
    >
      {% assign models = product.media | where: 'media_type', 'model' %}
      {%- if models.size > 0 -%}
        <script>
          window.ShopifyXR=window.ShopifyXR||function(){(ShopifyXR.q=ShopifyXR.q||[]).push(arguments)}
          ShopifyXR('addModels', {{ models | json }});
        </script>
      {%- endif -%}
      {% assign first_model = models | first %}
      {% for media in product.media %}

        {% assign use_large_image = false %}
        {% if product.media.size == 2 %}
          {% assign use_large_image = true %}
        {% elsif forloop.first and use_masonry %}
          {% assign use_large_image = true %}
        {% endif %}

        {% if media.media_type == 'model' %}
          {% assign model = media %}
        {% else %}
          {% assign model = first_model %}
        {% endif %}

        {% if model %}
          {% capture model_view_button %}
            <button
              class="product-gallery--viewinyourspace"
              data-shopify-xr
              data-shopify-model3d-id="{{ model.id }}"
              data-shopify-title="{{ product.title }}"
              data-shopify-xr-hidden
              data-viewinyourspace
            >
              {% render 'icons', id: 'ar' %}
              {{ 'products.media.view_in_your_space' | t }}
            </button>
          {% endcapture %}
        {% endif %}

        <figure
          class="product-gallery--viewport--figure {% if use_large_image %}product-image-wide{% endif %}"
          tabindex="-1"
          {% if images_layout != 'list' %}
            {% if selected_media.id != media.id %}
              aria-hidden="true"
            {% else %}
              aria-hidden="false"
            {% endif %}
          {% endif %}
          data-product-gallery-figure="{{ forloop.index0 }}"
          {% if images_layout == 'slideshow' %}
            data-product-gallery-selected="{%- if selected_media.id == media.id -%}true{%- else -%}false{%- endif -%}"
          {% endif %}
          data-media="{{ media.id }}"
          data-media-type="{{ media.media_type }}"
          >
          <div class="product-gallery--media-wrapper">
            {% case media.media_type %}
            {% when 'image' %}
              {%- capture data_attr -%}
                {% if enable_zoom %}data-image-zoom="{{ media.id }}"{% endif %}
              {%- endcapture -%}
              {%
                render 'rimg'
                img: media.preview_image,
                size: '1024x1024',
                attr: data_attr,
                lazy: true,
              %}
              {% if enable_zoom %}
                <div class="product-zoom" data-product-zoom-id="{{ media.id }}"></div>
              {% endif %}
            {% when 'model' %}
              {{ media | model_viewer_tag: image_size: '1024x', reveal: 'interaction' , toggleable: true, interaction-prompt-threshold: 0 }}
            {% when 'video' %}
              {{ media | media_tag: image_size: '1024x' }}
            {% when 'external_video' %}
              {{ media | media_tag: image_size: '1024x' }}
            {% else %}
              {{ media | media_tag }}
            {% endcase %}
          </div>
          {% if images_layout == 'slideshow' %}
            {{ model_view_button }}
          {% endif %}
        </figure>
        {% if images_layout == 'list' %}
            {{ model_view_button }}
        {% endif %}
      {% else %}
        <figure
          class="product-gallery--viewport--figure"
          data-product-gallery-selected="true"
        >
          {{ 'product-1' | placeholder_svg_tag: 'placeholder-svg' }}
        </figure>
      {% endfor %}

    </div>

    {% comment %} Colors In This Pattern — big swatch cards w/ % (replaces color-dots). Sits between the product images and Other Colorways. {% endcomment %}
    {% render 'color-palette' %}
    {% render 'colorway-siblings' %}

    {% if images_layout == 'slideshow' and product.media.size > 1 %}
      <div class="product-gallery-navigation-outer-wrapper">
        {% if product.media.size > 4 %}
          <span class="product-thumbnails-navigation-previous">&#xe601;</span>
        {% endif %}
        <div class="product-gallery--navigation-wrapper">
          <div
             class="product-gallery--navigation {% if product.media.size > 4 %}has-side-scroll{% endif %}"
            data-product-gallery-navigation
          >
            {% for media in product.media %}
              <button
                class="
                  product-gallery--media-thumbnail
                  product-gallery--{{ media.media_type }}-thumbnail
                "
                type="button"
                tab-index="0"
                aria-label="{{ media.alt }} {{ 'general.accessibility.nav_product_thumbnail' | t }}"
                data-product-gallery-thumbnail="{{ forloop.index0 }}"
                data-product-gallery-selected="{%- if selected_media.id == media.id -%}true{%- else -%}false{%- endif -%}"
                data-media="{{ media.id }}"
                data-media-type="{{ media.media_type }}"
              >
                {%
                  render 'rimg'
                  img: media.preview_image,
                  size: '100x100',
                  lazy: true
                %}
                {% case media.media_type %}
                {% when 'model' %}
                  {% render 'icons', id:'model-thumb' %}
                {% when 'video' %}
                  {% render 'icons', id: 'play-thumb' %}
                {% when 'external_video' %}
                  {% render 'icons', id: 'play-thumb' %}
                {% endcase %}
              </button>
            {% endfor %}
          </div>
        </div>
        {% if product.media.size > 4 %}
          <span class="product-thumbnails-navigation-next">&#xe600;</span>
        {% endif %}
      </div>
    {% endif %}
    <div class="product__social" {{ block.shopify_attributes }}>
      {% render 'share-buttons' %}
    </div>
    <div class="product-content__desktop">
      <h4 style="margin-bottom: 0.25em;"><strong>Pattern Description:</strong></h4>

      {% if product != blank and product.description != blank %}
        <div class="product-description rte" itemprop="description" style="margin-top: 0;">
          {{ product.description }}
        </div>
      {% elsif product == blank %}
        <div class="product-description rte" itemprop="description" style="margin-top: 0;">
          {{ 'products.product.onboarding.description' | t }}
        </div>
      {% endif %}
   </div>
</div>
{% if images_layout == 'masonry' and product.media.size > 1 %}
  <div class="mobile-slider-nav-wrapper">
    {{ model_view_button }}
    <div data-mobile-slider-navigation>
      <button class="mobile-slider-prev-next" data-mobile-slider-button="prev">
        {% render 'icons', id: 'prev-button' %}
      </button>
      <ol data-mobile-slider-dots>
        {% for media in product.media %}
          <li class='dot' aria-label="Page dot {{ forloop.index0 }}" data-mobile-slider-dot data-slide-dot-index="{{ forloop.index0 }}"></li>
        {% endfor %}
      </ol>
      <button class="mobile-slider-prev-next" data-mobile-slider-button="next">
        {% render 'icons', id: 'next-button' %}
      </button>
    </div>
  </div>
{% endif %}


{% render 'full-monte-express' %}