← back to Dw Theme Compact Toolbar
snippets/section.flex-pdp.media-grid.liquid
124 lines
{% doc %}
Copyright © 2025 Archetype Themes LP. All rights reserved.
Renders a responsive media gallery for product images and videos.
This component displays all product media in a horizontal scrolling grid layout.
It supports images, videos, external videos, and 3D models. The variant image is
displayed first, followed by all other media. Images can be opened in a lightbox
overlay for better viewing.
@param {object} product - A product object
@param {string} [image_aspect_ratio] - The aspect ratio for media containers (default: '1/1')
@param {boolean} [autoplay] - Autoplay the video (default: false)
@param {boolean} [loop] - Loop the video (default: false)
@example
{% render 'section.flex-pdp.media-grid', image_aspect_ratio: '4/3', product: closest.product %}
{% enddoc %}
{% liquid
assign image_aspect_ratio = image_aspect_ratio | default: block.settings.image_aspect_ratio | default: '1/1'
assign autoplay = autoplay | default: block.settings.enable_video_autoplay, allow_false: true | default: false, allow_false: true
assign loop = loop | default: block.settings.enable_video_looping, allow_false: true | default: false, allow_false: true
if image_aspect_ratio == '1/1'
assign video_aspect_ratio = 'square'
elsif image_aspect_ratio == '16/9'
assign video_aspect_ratio = 'landscape'
elsif image_aspect_ratio == '9/16'
assign video_aspect_ratio = 'portrait'
else
assign video_aspect_ratio = 'landscape'
endif
%}
{%- capture id -%}{% render 'utility.id', prefix: 'media-gallery' %}{%- endcapture -%}
{% capture product_images %}
{% if product.selected_or_first_available_variant.image != blank %}
{% capture image_content %}
{{ product.selected_or_first_available_variant.image | image_url: width: 2400 | image_tag }}
{% endcapture %}
<div class="media-grid__container media-grid__container--image">
{%- assign group = 'product-gallery-' | append: id -%}
{% render 'overlay.lightbox', slot: image_content, group: group %}
</div>
{% endif %}
{% for media in product.media %}
{% case media.media_type %}
{% when 'image' %}
{% unless media == product.selected_or_first_available_variant.image %}
{% capture image_content %}
{{ media | image_url: width: 2400 | image_tag }}
{% endcapture %}
<div class="media-grid__container media-grid__container--image">
{%- assign group = 'product-gallery-' | append: id -%}
{% render 'overlay.lightbox', slot: image_content, group: group %}
</div>
{% endunless %}
{% when 'video' %}
<div class="media-grid__container media-grid__container--video">
{% render 'element.video', video: media, media_crop: video_aspect_ratio, autoplay: autoplay, loop: loop %}
</div>
{% when 'external_video' %}
<div class="media-grid__container media-grid__container--video">
{% render 'element.video', external_video: media, media_crop: video_aspect_ratio, autoplay: autoplay, loop: loop %}
</div>
{% when 'model' %}
<div class="media-grid__container media-grid__container--model">
{% render 'element.model', media: media, autoplay: autoplay %}
</div>
{% endcase %}
{% endfor %}
{% endcapture %}
<div class="media-grid" id="{{ id }}">
{% render 'layout.stack', horizontal: true, gap: '2xs', wrap_xs: 'nowrap', wrap_sm: 'wrap', slot: product_images %}
</div>
{% stylesheet %}
.media-grid {
overflow-x: auto;
overflow-y: hidden;
}
.media-grid__container {
min-width: 350px;
flex: 1 1 300px;
& img:not(.overlay-lightbox__overlay img) {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.media-grid .shopify-model-viewer-ui,
.media-grid .shopify-model-viewer-ui model-viewer {
width: 100%;
height: 100%;
}
{% endstylesheet %}
{% style %}
#{{ id }} {
& .media-grid__container {
aspect-ratio: {{ image_aspect_ratio }};
}
}
@media ({% render 'utility.breakpoint', size: 'sm' %}) {
#{{ id }} {
& .media-grid__container {
flex: 1 1 420px;
min-width: 250px;
}
}
}
{% endstyle %}