Skip to content

Instantly share code, notes, and snippets.

@isbaek
Created October 6, 2023 13:47
Show Gist options
  • Save isbaek/92f999b619752298cb1c5c0e7ca1cba1 to your computer and use it in GitHub Desktop.
Save isbaek/92f999b619752298cb1c5c0e7ca1cba1 to your computer and use it in GitHub Desktop.
diff --git a/legacy/assets/custom-product-variants.js b/legacy/assets/custom-product-variants.js
new file mode 100644
index 0000000..a620200
--- /dev/null
+++ b/legacy/assets/custom-product-variants.js
@@ -0,0 +1,149 @@
+/*
+Custom product variant logic to switch the main image
+Must have Hulk Product Options App installed
+App: https://apps.shopify.com/product-options-by-hulkapps-1
+Enable by turning on settings > custom features > variant image features
+*/
+function waitForElms(e) {
+ return new Promise((t) => {
+ if (document.querySelectorAll(e).length)
+ return t(document.querySelectorAll(e));
+ const r = new MutationObserver((o) => {
+ document.querySelectorAll(e).length &&
+ (t(document.querySelectorAll(e)), r.disconnect());
+ });
+ r.observe(document.body, { childList: !0, subtree: !0 });
+ });
+}
+
+/**
+ * String combination to compare image alt text
+ * @param {string} finish - Selected finish option
+ * @param {string} cloth - Selected cloth option
+ */
+function getCurrentVariantString(finish, cloth) {
+ return `FINISH-` + finish + "-CLOTH-" + cloth;
+}
+
+document.addEventListener("DOMContentLoaded", () => {
+ /**
+ * Get default media image
+ * @returns {Product['media']} Product media https://shopify.dev/docs/api/liquid/objects/product#product-media
+ */
+ function getDefaultMedia() {
+ const media = {
+ id: "default-custom-variant-product-image", // Constant consistent with snippets/custom-product-image.liquid
+ };
+ return media;
+ }
+ /**
+ * Get maxed similar media type
+ * @returns {Product['media']} Product media https://shopify.dev/docs/api/liquid/objects/product#product-media
+ * @param {string} finish - Selected finish option
+ * @param {string} cloth - Selected cloth option
+ */
+ function getSelectedMedia(finish, cloth) {
+ const productMediaJSON = JSON.parse(
+ document.querySelector('product-form #media[type="application/json"]')
+ .textContent
+ );
+ const finishClothVariant = getCurrentVariantString(finish, cloth);
+
+ let maxedProductMedia = 0;
+ let maxedSimilarity = 0;
+ for (let productMedia of productMediaJSON) {
+ if (productMedia.alt?.length) {
+ // Compare two strings' similarity using Dice algorithm
+ const similarity = stringSimilarity.compareTwoStrings(
+ productMedia.alt,
+ finishClothVariant
+ );
+ if (similarity > maxedSimilarity) {
+ maxedProductMedia = productMedia;
+ maxedSimilarity = similarity;
+ }
+ }
+ }
+
+ // If it's not that similar we can assume it's not an exact match
+ if (maxedSimilarity < 0.6) return getDefaultMedia();
+ return maxedProductMedia;
+ }
+
+ /**
+ * Change product image based on selected media. Refer to assets/global.js > line 1369
+ * @returns {void}
+ * @param {Product['media']} Product media https://shopify.dev/docs/api/liquid/objects/product#product-media
+ */
+ function updateMedia(featuredMedia) {
+ const featuredMediaId = featuredMedia.id;
+ const dataSection = document
+ .querySelector("[data-section]")
+ .getAttribute("data-section");
+ const newMedia = document.querySelector(
+ `[data-media-id="${dataSection}-${featuredMediaId}"]`
+ );
+ if (!newMedia) return;
+ const mediaGallery = document.getElementById(`MediaGallery-${dataSection}`);
+ const thumbnailContent = document.querySelector(
+ `#ProductThumbnails-${dataSection}`
+ );
+ const modalContent = document.querySelector(
+ `#ProductModal-${dataSection} .product-media-modal__content`
+ );
+
+ const parent = newMedia.parentElement;
+ if (parent.firstChild == newMedia) return;
+ parent.prepend(newMedia);
+ parent.classList.add("product__media-no-animate");
+
+ if (mediaGallery) {
+ mediaGallery.setActiveMedia(
+ `${dataSection}-${featuredMediaId}`,
+ true,
+ false
+ );
+ }
+
+ if (modalContent) {
+ const newMediaModal = modalContent.querySelector(
+ `[data-media-id="${featuredMediaId}"]`
+ );
+ modalContent.prepend(newMediaModal);
+ }
+
+ if (thumbnailContent) {
+ const newMediaThumbnail = thumbnailContent.querySelector(
+ `[data-media-id="${featuredMediaId}"]`
+ );
+ thumbnailContent.prepend(newMediaThumbnail);
+ }
+ }
+ // Wait for hulk product options app
+ waitForElms(".hulkapps_product_options .hulk_po_radio").then((elements) => {
+ elements.forEach((element) => {
+ element.querySelector("input").addEventListener("change", (e) => {
+ const finishOption = document.querySelector(
+ "variant-radios input:checked"
+ )?.value;
+ const clothOption = e.target?.value;
+ if (!clothOption || !finishOption) return;
+ const featuredMedia = getSelectedMedia(finishOption, clothOption);
+ updateMedia(featuredMedia);
+ });
+ });
+ // Once loaded, add event listener for variant change
+ document.addEventListener("variant:change", (e) => {
+ const finishOption = document.querySelector(
+ "variant-radios input:checked"
+ )?.value;
+ const clothOption = document.querySelector(
+ ".hulkapps_product_options .hulk_po_radio.swatch_selected input"
+ )?.value;
+ // If no cloth option selected then exit
+ if (!clothOption || !finishOption) return;
+ const featuredMedia = getSelectedMedia(finishOption, clothOption);
+ updateMedia(featuredMedia);
+ });
+ });
+});
diff --git a/legacy/config/settings_data.json b/legacy/config/settings_data.json
index 866c122..1f4a8ed 100644
--- a/legacy/config/settings_data.json
+++ b/legacy/config/settings_data.json
@@ -60,6 +60,10 @@
"social_pinterest_link": "https:\/\/pinterest.com\/shopify",
"social_instagram_link": "https:\/\/instagram.com\/shopify",
"gift_card_logo_height": 70,
+ "enable_custom_variant_image_change": true,
+ "custom_variant_image_tags": "pooltabletag2",
+ "custom_variant_image_default": "shopify:\/\/shop_images\/cat-image.jpg",
+ "hide_custom_variant_image_product_thumbnails": true,
"sections": {
"main-password-header": {
"type": "main-password-header",
diff --git a/legacy/config/settings_schema.json b/legacy/config/settings_schema.json
index 277ceaf..5787786 100644
--- a/legacy/config/settings_schema.json
+++ b/legacy/config/settings_schema.json
@@ -922,5 +922,38 @@
"label": "t:settings_schema.gift_card.settings.gift_card_logo_height.label"
}
]
+ },
+ {
+ "name": "Custom Features",
+ "settings": [
+ {
+ "type": "header",
+ "content": "Variant Image Feature"
+ },
+ {
+ "type": "checkbox",
+ "id": "enable_custom_variant_image_change",
+ "label": "Enable custom variant image feature",
+ "info": "This feature must have [Hulk product options app](https://apps.shopify.com/product-options-by-hulkapps-1) installed to work. The product images must have alt text filled."
+ },
+ {
+ "type": "text",
+ "id": "custom_variant_image_tags",
+ "label": "Product tags to target the feature",
+ "info": "Must have above checkbox enabled to work. If left empty, no products will be targeted. Separate tags with a comma."
+ },
+ {
+ "type": "image_picker",
+ "id": "custom_variant_image_default",
+ "label": "Default product image",
+ "info": "Must have above checkbox enabled to work. If no image is present, default image will not be shown if there is no alt text match."
+ },
+ {
+ "type": "checkbox",
+ "id": "hide_custom_variant_image_product_thumbnails",
+ "label": "Hide custom images on product thumbnail",
+ "info": "Must have above checkbox enabled and enable product thumbnails display on desktop to work."
+ }
+ ]
}
]
\ No newline at end of file
diff --git a/legacy/sections/main-product.liquid b/legacy/sections/main-product.liquid
index c896be3..79a7653 100644
--- a/legacy/sections/main-product.liquid
+++ b/legacy/sections/main-product.liquid
@@ -8,6 +8,21 @@
<link rel="stylesheet" href="{{ 'component-deferred-media.css' | asset_url }}" media="print" onload="this.media='all'">
<link rel="stylesheet" href="{{ 'component-product-review.css' | asset_url }}" media="print" onload="this.media='all'">
+{% if settings.enable_custom_variant_image_change %}
+ {% assign target_product_tags = settings.custom_variant_image_tags | split: ',' %}
+ {% assign custom_variant_image_enabled = false %}
+ {% for target_product_tag in target_product_tags %}
+ {% for product_tag in product.tags %}
+ {% if product_tag == target_product_tag %}
+ {% assign custom_variant_image_enabled = true %}
+ {% endif %}
+ {% endfor %}
+ {% endfor %}
+ {% if custom_variant_image_enabled %}
+ <script src="https://unpkg.com/string-similarity/umd/string-similarity.min.js" async="async"></script>
+ <script src="{{ 'custom-product-variants.js' | asset_url }}" defer="defer"></script>
+ {% endif %}
+{% endif %}
{%- style -%}
#shopify-section-{{ section.id }} {
@@ -43,11 +58,23 @@
}
{%- endstyle -%}
-{%- assign first_3d_model = product.media | where: "media_type", "model" | first -%}
+{%- assign first_3d_model = product.media | where: 'media_type', 'model' | first -%}
{%- if first_3d_model -%}
{{ 'component-product-model.css' | asset_url | stylesheet_tag }}
- <link id="ModelViewerStyle" rel="stylesheet" href="https://cdn.shopify.com/shopifycloud/model-viewer-ui/assets/v1.0/model-viewer-ui.css" media="print" onload="this.media='all'">
- <link id="ModelViewerOverride" rel="stylesheet" href="{{ 'component-model-viewer-ui.css' | asset_url }}" media="print" onload="this.media='all'">
+ <link
+ id="ModelViewerStyle"
+ rel="stylesheet"
+ href="https://cdn.shopify.com/shopifycloud/model-viewer-ui/assets/v1.0/model-viewer-ui.css"
+ media="print"
+ onload="this.media='all'"
+ >
+ <link
+ id="ModelViewerOverride"
+ rel="stylesheet"
+ href="{{ 'component-model-viewer-ui.css' | asset_url }}"
+ media="print"
+ onload="this.media='all'"
+ >
{%- endif -%}
<section class="page-width section--padding">
@@ -55,14 +82,23 @@
<product-recently-viewed data-product-id="{{ product.id }}" class="hidden"></product-recently-viewed>
<div class="grid__item product__media-wrapper">
<span id="ProductImages"></span>
- <media-gallery id="MediaGallery-{{ section.id }}" role="region"{% if section.settings.enable_sticky_info %} class="product__media-gallery"{% endif %} aria-label="{{ 'products.product.media.gallery_viewer' | t }}" data-desktop-layout="{{ section.settings.gallery_layout }}">
+ <media-gallery
+ id="MediaGallery-{{ section.id }}"
+ role="region"
+ {% if section.settings.enable_sticky_info %}
+ class="product__media-gallery"
+ {% endif %}
+ aria-label="{{ 'products.product.media.gallery_viewer' | t }}"
+ data-desktop-layout="{{ section.settings.gallery_layout }}"
+ >
<div id="GalleryStatus-{{ section.id }}" class="visually-hidden" role="status"></div>
<use-animate data-animate="zoom-fade">
<product-gallery id="GalleryViewer-{{ section.id }}" class="slider-mobile-gutter slider-mobile--overlay">
<a class="skip-to-content-link button visually-hidden" href="#ProductInfo-{{ section.id }}">
- {{ "accessibility.skip_to_product_info" | t }}
+ {{ 'accessibility.skip_to_product_info' | t }}
</a>
- <ul id="Slider-Gallery-{{ section.id }}"
+ <ul
+ id="Slider-Gallery-{{ section.id }}"
class="product__media-list grid grid--1-col grid--1-col-tablet slider slider--mobile"
role="list"
>
@@ -71,7 +107,7 @@
if section.settings.hide_variants and variant_images.size == product.media.size
assign single_media_visible = true
endif
-
+
assign media_count = product.media.size
if section.settings.hide_variants and media_count > 1
assign media_count = media_count | minus: variant_images.size | plus: 1
@@ -105,7 +141,7 @@
if gang_connect contains '_'
assign gang_exist = true
assign gang_option_name = gang_connect | split: '_' | first | handleize
-
+
for option_name in product.options
assign option_name_handlized = option_name | handleize | replace: '_', '-'
if option_name_handlized == gang_option_name
@@ -121,15 +157,30 @@
endif
endif
-%}
- <li id="Slide-{{ section.id }}-{{ featured_media.id }}"
+ <li
+ id="Slide-{{ section.id }}-{{ featured_media.id }}"
class="product__media-item is-active grid__item slider__slide{% if single_media_visible %} product__media-item--single{% endif %}{% if featured_media.media_type != 'image' %} product__media-item--full{% endif %}{% if section.settings.hide_variants and variant_images contains featured_media.src %} product__media-item--variant{% endif %}{% if gang_media_active == true %} gang__active{% endif %}"
data-media-id="{{ section.id }}-{{ featured_media.id }}"
data-media-position="{{ featured_media.position }}"
- {% if gang_exist == true %}data-gang-option="{{ gang_option_name }}" data-gang-connect="{{ gang_connect }}"{% endif %}
+ {% if gang_exist == true %}
+ data-gang-option="{{ gang_option_name }}" data-gang-connect="{{ gang_connect }}"
+ {% endif %}
>
- {% render 'product-image', media: featured_media, position: 'featured', zoom: section.settings.enable_image_zoom, loop: section.settings.enable_video_looping, modal_id: section.id, xr_button: true, media_width: media_width, image_ratio: image_ratio, mobile_image_ratio: mobile_image_ratio, lazy_load: false %}
+ {% render 'product-image',
+ media: featured_media,
+ position: 'featured',
+ zoom: section.settings.enable_image_zoom,
+ loop: section.settings.enable_video_looping,
+ modal_id: section.id,
+ xr_button: true,
+ media_width: media_width,
+ image_ratio: image_ratio,
+ mobile_image_ratio: mobile_image_ratio,
+ lazy_load: false
+ %}
</li>
{%- endif -%}
+
{%- for media in product.media -%}
{%- unless media.id == featured_media.id -%}
{%- liquid
@@ -141,7 +192,7 @@
if gang_connect contains '_'
assign gang_exist = true
assign gang_option_name = gang_connect | split: '_' | first | handleize
-
+
for option_name in product.options
assign option_name_handlized = option_name | handleize | replace: '_', '-'
if option_name_handlized == gang_option_name
@@ -157,16 +208,44 @@
endif
endif
-%}
- <li id="Slide-{{ section.id }}-{{ media.id }}"
+ <li
+ id="Slide-{{ section.id }}-{{ media.id }}"
class="product__media-item grid__item slider__slide{% if single_media_visible %} product__media-item--single{% endif %}{% if featured_media == null and forloop.first %} is-active{% endif %}{% if media.media_type != 'image' %} product__media-item--full{% endif %}{% if section.settings.hide_variants and variant_images contains media.src %} product__media-item--variant{% endif %}{% if gang_media_active == true %} gang__active{% endif %}"
data-media-id="{{ section.id }}-{{ media.id }}"
data-media-position="{{ media.position }}"
- {% if gang_exist == true %}data-gang-option="{{ gang_option_name }}" data-gang-connect="{{ gang_connect }}"{% endif %}
+ {% if gang_exist == true %}
+ data-gang-option="{{ gang_option_name }}" data-gang-connect="{{ gang_connect }}"
+ {% endif %}
>
- {% render 'product-image', media: media, position: forloop.index, zoom: section.settings.enable_image_zoom, loop: section.settings.enable_video_looping, modal_id: section.id, xr_button: true, media_width: media_width, image_ratio: image_ratio, mobile_image_ratio: mobile_image_ratio %}
+ {% render 'product-image',
+ media: media,
+ position: forloop.index,
+ zoom: section.settings.enable_image_zoom,
+ loop: section.settings.enable_video_looping,
+ modal_id: section.id,
+ xr_button: true,
+ media_width: media_width,
+ image_ratio: image_ratio,
+ mobile_image_ratio: mobile_image_ratio
+ %}
</li>
{%- endunless -%}
{%- endfor -%}
+
+ {% if custom_variant_image_enabled and settings.custom_variant_image_default != blank %}
+ {%
+ render 'custom-product-image',
+ position: forloop.index,
+ zoom: section.settings.enable_image_zoom,
+ loop: section.settings.enable_video_looping,
+ modal_id: section.id,
+ xr_button: true,
+ media_width: media_width,
+ image_ratio: image_ratio,
+ mobile_image_ratio: mobile_image_ratio
+ section: section,
+ %}
+ {% endif %}
</ul>
<div class="slider-buttons no-js-hidden{% if media_count < 2 or section.settings.show_mobile_thumbnails %} small-hide{% endif %}">
<div class="slider-counter caption">
@@ -175,10 +254,20 @@
<span class="visually-hidden">{{ 'general.slider.of' | t }}</span>
<span class="slider-counter--total">{{ media_count }}</span>
</div>
- <button type="button" class="slider-button slider-button--prev" name="previous" aria-label="{{ 'general.slider.previous_slide' | t }}">
+ <button
+ type="button"
+ class="slider-button slider-button--prev"
+ name="previous"
+ aria-label="{{ 'general.slider.previous_slide' | t }}"
+ >
{% render 'icon', icon: 'arrow' %}
</button>
- <button type="button" class="slider-button slider-button--next" name="next" aria-label="{{ 'general.slider.next_slide' | t }}">
+ <button
+ type="button"
+ class="slider-button slider-button--next"
+ name="next"
+ aria-label="{{ 'general.slider.next_slide' | t }}"
+ >
{% render 'icon', icon: 'arrow' %}
</button>
</div>
@@ -205,11 +294,17 @@
</button>
{%- endif -%}
- {%- if product.media.size > 1 and media_count > 1 and section.settings.gallery_layout == 'thumbnail_slider' or section.settings.show_mobile_thumbnails -%}
- <thumbnail-slider id="GalleryThumbnails-{{ section.id }}"
+ {%- if product.media.size > 1
+ and media_count > 1
+ and section.settings.gallery_layout == 'thumbnail_slider'
+ or section.settings.show_mobile_thumbnails
+ -%}
+ <thumbnail-slider
+ id="GalleryThumbnails-{{ section.id }}"
class="thumbnail-slider slider-mobile-gutter{% unless section.settings.show_mobile_thumbnails %} small-hide{% endunless %}{% if media_count <= 3 %} thumbnail-slider--no-slide{% endif %}"
>
- <ul id="Slider-Thumbnails-{{ section.id }}"
+ <ul
+ id="Slider-Thumbnails-{{ section.id }}"
class="thumbnail-list list-unstyled slider slider--mobile{% if section.settings.gallery_layout == 'thumbnail_slider' %} slider--tablet-up{% endif %}"
data-media-count="{{ product.media.size }}"
>
@@ -235,7 +330,7 @@
if gang_connect contains '_'
assign gang_exist = true
assign gang_option_name = gang_connect | split: '_' | first | handleize
-
+
for option_name in product.options
assign option_name_handlized = option_name | handleize | replace: '_', '-'
if option_name_handlized == gang_option_name
@@ -251,13 +346,17 @@
endif
endif
-%}
- <li id="Slide-Thumbnails-{{ section.id }}-0"
+ <li
+ id="Slide-Thumbnails-{{ section.id }}-0"
class="thumbnail-list__item slider__slide{% if section.settings.hide_variants and variant_images contains featured_media.src %} thumbnail-list_item--variant{% endif %} is-active media-wrapper media-wrapper--small{% if gang_media_active == true %} gang__active{% endif %}"
data-target="{{ section.id }}-{{ featured_media.id }}"
data-media-position="{{ media_index }}"
- {% if gang_exist == true %}data-gang-option="{{ gang_option_name }}" data-gang-connect="{{ gang_connect }}"{% endif %}
+ {% if gang_exist == true %}
+ data-gang-option="{{ gang_option_name }}" data-gang-connect="{{ gang_connect }}"
+ {% endif %}
>
- <button class="thumbnail media media--square"
+ <button
+ class="thumbnail media media--square"
aria-label="{%- if featured_media.media_type == 'image' -%}{{ 'products.product.media.load_image' | t: index: media_index }}{%- elsif featured_media.media_type == 'model' -%}{{ 'products.product.media.load_model' | t: index: media_index }}{%- elsif featured_media.media_type == 'video' or featured_media.media_type == 'external_video' -%}{{ 'products.product.media.load_video' | t: index: media_index }}{%- endif -%}"
aria-current="true"
aria-controls="GalleryViewer-{{ section.id }}"
@@ -272,88 +371,126 @@
</button>
</li>
{%- endif -%}
+
+ {% assign custom_variant_feature_enabled = false %}
+ {% if custom_variant_image_enabled and settings.hide_custom_variant_image_product_thumbnails %}
+ {% assign custom_variant_feature_enabled = true %}
+ {% endif %}
+
{%- for media in product.media -%}
- {%- unless media.id == featured_media.id -%}
- {%- liquid
- capture media_index
- if media.media_type == 'model'
- increment model_index
- elsif media.media_type == 'video' or media.media_type == 'external_video'
- increment video_index
- elsif media.media_type == 'image'
- increment image_index
- endif
- endcapture
-
- assign media_index = media_index | plus: 1
+ {% assign media_alt = media.alt | upcase %}
+ {% if custom_variant_feature_enabled and media_alt contains 'FINISH' or media_alt contains 'CLOTH' %}
+ {% continue %}
+ {% else %}
+ {%- unless media.id == featured_media.id -%}
+ {%- liquid
+ capture media_index
+ if media.media_type == 'model'
+ increment model_index
+ elsif media.media_type == 'video' or media.media_type == 'external_video'
+ increment video_index
+ elsif media.media_type == 'image'
+ increment image_index
+ endif
+ endcapture
- assign gang_option_name = ''
- assign gang_media_active = false
- assign gang_connect = ''
- if media.alt contains '#' and section.settings.hide_variants == false
- assign gang_connect = media.alt | split: '#' | last
- if gang_connect contains '_'
- assign gang_exist = true
- assign gang_option_name = gang_connect | split: '_' | first | handleize
-
- for option_name in product.options
- assign option_name_handlized = option_name | handleize | replace: '_', '-'
- if option_name_handlized == gang_option_name
- assign option_key = 'option' | append: forloop.index
- assign current_option_value = product.selected_or_first_available_variant[option_key] | handleize
- assign current_connect = option_name_handlized | append: '_' | append: current_option_value
- if gang_connect == current_connect
- assign gang_media_active = true
+ assign media_index = media_index | plus: 1
+
+ assign gang_option_name = ''
+ assign gang_media_active = false
+ assign gang_connect = ''
+ if media.alt contains '#' and section.settings.hide_variants == false
+ assign gang_connect = media.alt | split: '#' | last
+ if gang_connect contains '_'
+ assign gang_exist = true
+ assign gang_option_name = gang_connect | split: '_' | first | handleize
+
+ for option_name in product.options
+ assign option_name_handlized = option_name | handleize | replace: '_', '-'
+ if option_name_handlized == gang_option_name
+ assign option_key = 'option' | append: forloop.index
+ assign current_option_value = product.selected_or_first_available_variant[option_key] | handleize
+ assign current_connect = option_name_handlized | append: '_' | append: current_option_value
+ if gang_connect == current_connect
+ assign gang_media_active = true
+ endif
+ break
endif
- break
- endif
- endfor
+ endfor
+ endif
endif
- endif
- -%}
- <li id="Slide-Thumbnails-{{ section.id }}-{{ forloop.index }}"
- class="thumbnail-list__item slider__slide{% if section.settings.hide_variants and variant_images contains media.src %} thumbnail-list_item--variant{% endif %}{% if media == featured_media or featured_media == null and forloop.first %} is-active{% endif %} media-wrapper media-wrapper--small{% if gang_media_active == true %} gang__active{% endif %}"
- data-target="{{ section.id }}-{{ media.id }}"
- data-media-position="{{ media_index }}"
- {% if gang_exist == true %}data-gang-option="{{ gang_option_name }}" data-gang-connect="{{ gang_connect }}"{% endif %}
- >
- {%- if media.media_type != 'image' -%}
- <span class="deferred-media__poster-button motion-reduce">
- {%- if media.media_type == 'model' -%}
- <span class="visually-hidden">{{ 'products.product.media.play_model' | t }}</span>
- {%- render 'icon', icon: '3d-model' -%}
- {%- else -%}
- <span class="visually-hidden">{{ 'products.product.media.play_video' | t }}</span>
- {%- render 'icon', icon: 'play' -%}
- {%- endif -%}
- </span>
- {%- endif -%}
-
- <button class="thumbnail media media--square"
- aria-label="{%- if media.media_type == 'image' -%}{{ 'products.product.media.load_image' | t: index: media_index }}{%- elsif media.media_type == 'model' -%}{{ 'products.product.media.load_model' | t: index: media_index }}{%- elsif media.media_type == 'video' or media.media_type == 'external_video' -%}{{ 'products.product.media.load_video' | t: index: media_index }}{%- endif -%}"
- {% if media == featured_media or featured_media == null and forloop.first %} aria-current="true"{% endif %}
- aria-controls="GalleryViewer-{{ section.id }}"
- aria-describedby="Thumbnail-{{ section.id }}-{{ forloop.index }}"
+ -%}
+ <li
+ id="Slide-Thumbnails-{{ section.id }}-{{ forloop.index }}"
+ class="thumbnail-list__item slider__slide{% if section.settings.hide_variants and variant_images contains media.src %} thumbnail-list_item--variant{% endif %}{% if media == featured_media or featured_media == null and forloop.first %} is-active{% endif %} media-wrapper media-wrapper--small{% if gang_media_active == true %} gang__active{% endif %}"
+ data-target="{{ section.id }}-{{ media.id }}"
+ data-media-position="{{ media_index }}"
+ {% if gang_exist == true %}
+ data-gang-option="{{ gang_option_name }}" data-gang-connect="{{ gang_connect }}"
+ {% endif %}
>
- {%- capture sizes -%}(min-width: {{ settings.page_width }}px) calc(({{ settings.page_width | minus: 100 | times: media_width | round }} - 4rem) / 4), (min-width: 990px) calc(({{ media_width | times: 100 }}vw - 4rem) / 4), (min-width: 750px) calc((100vw - 15rem) / 8), calc((100vw - 14rem) / 3){%- endcapture -%}
- {%- liquid
- assign image_id = 'Thumbnail-' | append: section.id | append: '-' | append: forloop.index
- assign alt = media.alt | escape | split: '#' | first
- echo media.preview_image | image_url: width: 416 | image_tag: loading: 'lazy', id: image_id, sizes: sizes, widths: '54, 74, 162, 208, 324, 416', alt: alt
- -%}
- </button>
- </li>
- {%- endunless -%}
+ {%- if media.media_type != 'image' -%}
+ <span class="deferred-media__poster-button motion-reduce">
+ {%- if media.media_type == 'model' -%}
+ <span class="visually-hidden">{{ 'products.product.media.play_model' | t }}</span>
+ {%- render 'icon', icon: '3d-model' -%}
+ {%- else -%}
+ <span class="visually-hidden">{{ 'products.product.media.play_video' | t }}</span>
+ {%- render 'icon', icon: 'play' -%}
+ {%- endif -%}
+ </span>
+ {%- endif -%}
+
+ <button
+ class="thumbnail media media--square"
+ aria-label="{%- if media.media_type == 'image' -%}{{ 'products.product.media.load_image' | t: index: media_index }}{%- elsif media.media_type == 'model' -%}{{ 'products.product.media.load_model' | t: index: media_index }}{%- elsif media.media_type == 'video' or media.media_type == 'external_video' -%}{{ 'products.product.media.load_video' | t: index: media_index }}{%- endif -%}"
+ {% if media == featured_media or featured_media == null and forloop.first %}
+ aria-current="true"
+ {% endif %}
+ aria-controls="GalleryViewer-{{ section.id }}"
+ aria-describedby="Thumbnail-{{ section.id }}-{{ forloop.index }}"
+ >
+ {%- capture sizes -%}(min-width: {{ settings.page_width }}px) calc(({{ settings.page_width | minus: 100 | times: media_width | round }} - 4rem) / 4), (min-width: 990px) calc(({{ media_width | times: 100 }}vw - 4rem) / 4), (min-width: 750px) calc((100vw - 15rem) / 8), calc((100vw - 14rem) / 3){%- endcapture -%}
+ {%- liquid
+ assign image_id = 'Thumbnail-' | append: section.id | append: '-' | append: forloop.index
+ assign alt = media.alt | escape | split: '#' | first
+ echo media.preview_image | image_url: width: 416 | image_tag: loading: 'lazy', id: image_id, sizes: sizes, widths: '54, 74, 162, 208, 324, 416', alt: alt
+ -%}
+ </button>
+ </li>
+ {%- endunless -%}
+ {% endif %}
{%- endfor -%}
</ul>
<div class="slider-buttons{% if media_count <= 3 %} small-hide{% endif %}{% if media_count <= 4 %} medium-hide large-up-hide{% endif %}">
- <button type="button" class="slider-button slider-button--prev" name="previous" aria-label="{{ 'general.slider.previous_slide' | t }}" aria-controls="GalleryThumbnails-{{ section.id }}" data-step="3">{% render 'icon', icon: 'caret' %}</button>
- <button type="button" class="slider-button slider-button--next" name="next" aria-label="{{ 'general.slider.next_slide' | t }}" aria-controls="GalleryThumbnails-{{ section.id }}" data-step="3">{% render 'icon', icon: 'caret' %}</button>
+ <button
+ type="button"
+ class="slider-button slider-button--prev"
+ name="previous"
+ aria-label="{{ 'general.slider.previous_slide' | t }}"
+ aria-controls="GalleryThumbnails-{{ section.id }}"
+ data-step="3"
+ >
+ {% render 'icon', icon: 'caret' %}
+ </button>
+ <button
+ type="button"
+ class="slider-button slider-button--next"
+ name="next"
+ aria-label="{{ 'general.slider.next_slide' | t }}"
+ aria-controls="GalleryThumbnails-{{ section.id }}"
+ data-step="3"
+ >
+ {% render 'icon', icon: 'caret' %}
+ </button>
</div>
</thumbnail-slider>
{%- endif -%}
- {%- if section.settings.gallery_layout == 'stacked' and section.settings.show_thumbnails and product.media.size > 1 -%}
+ {%- if section.settings.gallery_layout == 'stacked'
+ and section.settings.show_thumbnails
+ and product.media.size > 1
+ -%}
<div class="product__thumbnails-wrapper">
<product-thumbnails id="ProductThumbnails-{{ section.id }}" class="product__thumbnails">
{%- if featured_media != null -%}
@@ -372,7 +509,7 @@
if gang_connect contains '_'
assign gang_exist = true
assign gang_option_name = gang_connect | split: '_' | first | handleize
-
+
for option_name in product.options
assign option_name_handlized = option_name | handleize | replace: '_', '-'
if option_name_handlized == gang_option_name
@@ -388,22 +525,28 @@
endif
endif
-%}
- <div data-section="{{ section.id }}" data-media-id="{{ featured_media.id }}"
+ <div
+ data-section="{{ section.id }}"
+ data-media-id="{{ featured_media.id }}"
class="product__thumbnail media-wrapper media-wrapper--small{% if variant_image %} product__media-item--variant{% endif %} is-active {% if gang_media_active == true %} gang__active{% endif %}"
data-thumbnail-position="{{ featured_media.position }}"
- {% if gang_exist == true %}data-gang-option="{{ gang_option_name }}" data-gang-connect="{{ gang_connect }}"{% endif %}
+ {% if gang_exist == true %}
+ data-gang-option="{{ gang_option_name }}" data-gang-connect="{{ gang_connect }}"
+ {% endif %}
>
- <div class="media media--adapt"
+ <div
+ class="media media--adapt"
style="--image-ratio-percent: {{ 1 | divided_by: featured_media.preview_image.aspect_ratio | times: 100 }}%;"
>
- <img srcset="{{ featured_media.preview_image | image_url: width: 165 }} 1x, {{ featured_media.preview_image | image_url: width: 330 }} 2x"
+ <img
+ srcset="{{ featured_media.preview_image | image_url: width: 165 }} 1x, {{ featured_media.preview_image | image_url: width: 330 }} 2x"
src="{{ featured_media.preview_image | image_url: width: 165 }}"
loading="lazy"
width="{{ featured_media.preview_image.width }}"
height="{{ featured_media.preview_image.height }}"
alt="{{ featured_media.preview_image.alt | escape | split: '#' | first }}"
is="lazy-image"
- />
+ >
</div>
{%- if featured_media.media_type != 'image' -%}
<span class="deferred-media__poster-button motion-reduce">
@@ -436,7 +579,7 @@
if gang_connect contains '_'
assign gang_exist = true
assign gang_option_name = gang_connect | split: '_' | first | handleize
-
+
for option_name in product.options
assign option_name_handlized = option_name | handleize | replace: '_', '-'
if option_name_handlized == gang_option_name
@@ -452,22 +595,28 @@
endif
endif
-%}
- <div data-section="{{ section.id }}" data-media-id="{{ media.id }}"
+ <div
+ data-section="{{ section.id }}"
+ data-media-id="{{ media.id }}"
class="product__thumbnail media-wrapper media-wrapper--small{% if variant_image %} product__media-item--variant{% endif %}{% if media == featured_media or featured_media == null and forloop.first %} is-active{% endif %}{% if gang_media_active == true %} gang__active{% endif %}"
data-thumbnail-position="{{ media.position }}"
- {% if gang_exist == true %}data-gang-option="{{ gang_option_name }}" data-gang-connect="{{ gang_connect }}"{% endif %}
+ {% if gang_exist == true %}
+ data-gang-option="{{ gang_option_name }}" data-gang-connect="{{ gang_connect }}"
+ {% endif %}
>
- <div class="media media--adapt"
+ <div
+ class="media media--adapt"
style="--image-ratio-percent: {{ 1 | divided_by: media.preview_image.aspect_ratio | times: 100 }}%;"
>
- <img srcset="{{ media.preview_image | image_url: width: 165 }} 1x, {{ media.preview_image | image_url: width: 330 }} 2x"
+ <img
+ srcset="{{ media.preview_image | image_url: width: 165 }} 1x, {{ media.preview_image | image_url: width: 330 }} 2x"
src="{{ media.preview_image | image_url: width: 165 }}"
loading="lazy"
width="{{ media.preview_image.width }}"
height="{{ media.preview_image.height }}"
alt="{{ media.preview_image.alt | escape | split: '#' | first }}"
is="lazy-image"
- />
+ >
</div>
{%- if media.media_type != 'image' -%}
<span class="deferred-media__poster-button motion-reduce">
@@ -492,121 +641,119 @@
{%- liquid
assign product_form_id = 'product-form-' | append: section.id
-
- assign titleBlock = section.blocks | where: "type", "title" | first
+
+ assign titleBlock = section.blocks | where: 'type', 'title' | first
assign titleBlockPrice = false
if titleBlock.settings.show_price == true
assign titleBlockPrice = true
endif
-%}
<div class="product__info-wrapper grid__item">
- <div id="ProductInfo-{{ section.id }}" class="product__info-container{% if section.settings.enable_sticky_info %} product__info-container--sticky{% endif %}">
+ <div
+ id="ProductInfo-{{ section.id }}"
+ class="product__info-container{% if section.settings.enable_sticky_info %} product__info-container--sticky{% endif %}"
+ >
{%- for block in section.blocks -%}
{%- case block.type -%}
- {%- when '@app' -%}
- {% render block %}
- {%- when 'text' -%}
- {%- if block.settings.text != blank -%}
- <p class="product__text{% if block.settings.text_style == 'uppercase' %} caption-with-letter-spacing{% elsif block.settings.text_style == 'subtitle' %} subtitle{% endif %}" {{ block.shopify_attributes }}>
- {%- liquid
- if block.settings.text != product.vendor
- render 'icon-accordion', icon: block.settings.icon
- echo block.settings.text
- else
- echo product.vendor | link_to_vendor : class: "link"
- endif
- -%}
+ {%- when '@app' -%}
+ {% render block %}
+ {%- when 'text' -%}
+ {%- if block.settings.text != blank -%}
+ <p
+ class="product__text{% if block.settings.text_style == 'uppercase' %} caption-with-letter-spacing{% elsif block.settings.text_style == 'subtitle' %} subtitle{% endif %}"
+ {{ block.shopify_attributes }}
+ >
+ {%- liquid
+ if block.settings.text != product.vendor
+ render 'icon-accordion', icon: block.settings.icon
+ echo block.settings.text
+ else
+ echo product.vendor | link_to_vendor: class: 'link'
+ endif
+ -%}
+ </p>
+ {%- endif -%}
+ {%- when 'sku' -%}
+ <p
+ class="product__sku{% if block.settings.sku_style == 'uppercase' %} caption-with-letter-spacing{% elsif block.settings.sku_style == 'subtitle' %} subtitle{% endif %}"
+ id="sku-{{ section.id }}"
+ {{ block.shopify_attributes }}
+ >
+ {{- product.selected_or_first_available_variant.sku -}}
</p>
- {%- endif -%}
- {%- when 'sku' -%}
- <p class="product__sku{% if block.settings.sku_style == 'uppercase' %} caption-with-letter-spacing{% elsif block.settings.sku_style == 'subtitle' %} subtitle{% endif %}" id="sku-{{ section.id }}" {{ block.shopify_attributes }}>
- {{- product.selected_or_first_available_variant.sku -}}
- </p>
- {%- when 'title' -%}
- <div class="product__title" {{ block.shopify_attributes }}>
- <h1 class="product__heading {{ block.settings.title_size }}">
- {{ product.title | escape }}
- </h1>
+ {%- when 'title' -%}
+ <div class="product__title" {{ block.shopify_attributes }}>
+ <h1 class="product__heading {{ block.settings.title_size }}">
+ {{ product.title | escape }}
+ </h1>
+ {%- if block.settings.show_price -%}
+ <div class="no-js-hidden" id="price-{{ section.id }}">
+ {%- liquid
+ assign price_class = 'price--' | append: block.settings.price_size
+ render 'price', product: product, use_variant: true, show_badges: false, price_class: price_class
+ -%}
+ </div>
+ {%- endif -%}
+ </div>
{%- if block.settings.show_price -%}
- <div class="no-js-hidden" id="price-{{ section.id }}">
+ {%- if shop.taxes_included or shop.shipping_policy.body != blank -%}
+ <div class="product__tax caption rte">
+ {%- if shop.taxes_included -%}
+ {{ 'products.product.include_taxes' | t }}
+ {%- endif -%}
+ {%- if shop.shipping_policy.body != blank -%}
+ {{ 'products.product.shipping_policy_html' | t: link: shop.shipping_policy.url }}
+ {%- endif -%}
+ </div>
+ {%- endif -%}
+ <div {{ block.shopify_attributes }}>
+ {%- assign product_form_installment_id = 'product-form-installment-' | append: section.id -%}
+ {%- form 'product', product, id: product_form_installment_id, class: 'installment caption-large' -%}
+ <input type="hidden" name="id" value="{{ product.selected_or_first_available_variant.id }}">
+ {{ form | payment_terms }}
+ {%- endform -%}
+ </div>
+ {%- endif -%}
+ {%- when 'price' -%}
+ {%- if titleBlockPrice == false -%}
+ <div class="no-js-hidden" id="price-{{ section.id }}" {{ block.shopify_attributes }}>
{%- liquid
+ assign show_badges = block.settings.show_badges
assign price_class = 'price--' | append: block.settings.price_size
- render 'price', product: product, use_variant: true, show_badges: false, price_class: price_class
+ render 'price', product: product, use_variant: true, show_badges: show_badges, price_class: price_class, sale_badge_basis: block.settings.sale_badge_basis
-%}
</div>
- {%- endif -%}
- </div>
- {%- if block.settings.show_price -%}
- {%- if shop.taxes_included or shop.shipping_policy.body != blank -%}
- <div class="product__tax caption rte">
- {%- if shop.taxes_included -%}
- {{ 'products.product.include_taxes' | t }}
- {%- endif -%}
- {%- if shop.shipping_policy.body != blank -%}
- {{ 'products.product.shipping_policy_html' | t: link: shop.shipping_policy.url }}
- {%- endif -%}
- </div>
- {%- endif -%}
- <div {{ block.shopify_attributes }}>
- {%- assign product_form_installment_id = 'product-form-installment-' | append: section.id -%}
- {%- form 'product', product, id: product_form_installment_id, class: 'installment caption-large' -%}
- <input type="hidden" name="id" value="{{ product.selected_or_first_available_variant.id }}">
- {{ form | payment_terms }}
- {%- endform -%}
- </div>
- {%- endif -%}
- {%- when 'price' -%}
- {%- if titleBlockPrice == false -%}
- <div class="no-js-hidden" id="price-{{ section.id }}" {{ block.shopify_attributes }}>
- {%- liquid
- assign show_badges = block.settings.show_badges
- assign price_class = 'price--' | append: block.settings.price_size
- render 'price', product: product, use_variant: true, show_badges: show_badges, price_class: price_class, sale_badge_basis: block.settings.sale_badge_basis
- -%}
- </div>
- {%- if shop.taxes_included or shop.shipping_policy.body != blank -%}
- <div class="product__tax caption rte">
- {%- if shop.taxes_included -%}
- {{ 'products.product.include_taxes' | t }}
- {%- endif -%}
- {%- if shop.shipping_policy.body != blank -%}
- {{ 'products.product.shipping_policy_html' | t: link: shop.shipping_policy.url }}
- {%- endif -%}
+ {%- if shop.taxes_included or shop.shipping_policy.body != blank -%}
+ <div class="product__tax caption rte">
+ {%- if shop.taxes_included -%}
+ {{ 'products.product.include_taxes' | t }}
+ {%- endif -%}
+ {%- if shop.shipping_policy.body != blank -%}
+ {{ 'products.product.shipping_policy_html' | t: link: shop.shipping_policy.url }}
+ {%- endif -%}
+ </div>
+ {%- endif -%}
+ <div {{ block.shopify_attributes }}>
+ {%- assign product_form_installment_id = 'product-form-installment-' | append: section.id -%}
+ {%- form 'product', product, id: product_form_installment_id, class: 'installment caption-large' -%}
+ <input type="hidden" name="id" value="{{ product.selected_or_first_available_variant.id }}">
+ {{ form | payment_terms }}
+ {%- endform -%}
</div>
{%- endif -%}
- <div {{ block.shopify_attributes }}>
- {%- assign product_form_installment_id = 'product-form-installment-' | append: section.id -%}
- {%- form 'product', product, id: product_form_installment_id, class: 'installment caption-large' -%}
- <input type="hidden" name="id" value="{{ product.selected_or_first_available_variant.id }}">
- {{ form | payment_terms }}
- {%- endform -%}
+ {%- when 'description' -%}
+ <div class="product__description rte" {{ block.shopify_attributes }}>{{ product.description }}</div>
+ {%- when 'custom_liquid' -%}
+ <div class="custom__liquid custom__liquid-{{ section.id }}" {{ block.shopify_attributes }}>
+ {{ block.settings.custom_liquid }}
</div>
- {%- endif -%}
- {%- when 'description' -%}
- <div class="product__description rte" {{ block.shopify_attributes }}>{{ product.description }}</div>
- {%- when 'custom_liquid' -%}
- <div class="custom__liquid custom__liquid-{{ section.id }}" {{ block.shopify_attributes }}>{{ block.settings.custom_liquid }}</div>
- {%- when 'collapsible_description' -%}
- <accordion-tab class="product__accordion accordion" {{ block.shopify_attributes }}>
- <details{% if block.settings.keep_open %} open{% endif %}>
- <summary>
- <span class="summary__title">
- {% render 'icon-accordion', icon: block.settings.icon %}
- <span class="accordion__title">
- {{ block.settings.heading | default: block.settings.page.title | escape }}
- </span>
- </span>
- {% render 'icon', icon: 'caret' %}
- </summary>
- <div class="accordion__content rte">
- {{ product.description }}
- </div>
- </details>
- </accordion-tab>
- {%- when 'collapsible_tab' -%}
- {%- if block.settings.content != blank or block.settings.page.content != blank or block.settings.custom_liquid != blank -%}
+ {%- when 'collapsible_description' -%}
<accordion-tab class="product__accordion accordion" {{ block.shopify_attributes }}>
- <details{% if block.settings.keep_open %} open{% endif %}>
+ <details
+ {% if block.settings.keep_open %}
+ open
+ {% endif %}
+ >
<summary>
<span class="summary__title">
{% render 'icon-accordion', icon: block.settings.icon %}
@@ -616,132 +763,179 @@
</span>
{% render 'icon', icon: 'caret' %}
</summary>
- <div class="accordion__content custom__liquid-{{ section.id }} rte">
- {{ block.settings.content }}
- {{ block.settings.page.content }}
- {{ block.settings.custom_liquid }}
+ <div class="accordion__content rte">
+ {{ product.description }}
</div>
</details>
</accordion-tab>
- {%- endif -%}
- {%- when 'popup' -%}
- <modal-opener class="product-popup-modal__opener no-js-hidden" data-modal="#PopupModal-{{ block.id }}" {{ block.shopify_attributes }}>
- <button id="ProductPopup-{{ block.id }}" class="product-popup-modal__button link link-with-icon" type="button" aria-haspopup="dialog">
+ {%- when 'collapsible_tab' -%}
+ {%- if block.settings.content != blank
+ or block.settings.page.content != blank
+ or block.settings.custom_liquid != blank
+ -%}
+ <accordion-tab class="product__accordion accordion" {{ block.shopify_attributes }}>
+ <details
+ {% if block.settings.keep_open %}
+ open
+ {% endif %}
+ >
+ <summary>
+ <span class="summary__title">
+ {% render 'icon-accordion', icon: block.settings.icon %}
+ <span class="accordion__title">
+ {{ block.settings.heading | default: block.settings.page.title | escape }}
+ </span>
+ </span>
+ {% render 'icon', icon: 'caret' %}
+ </summary>
+ <div class="accordion__content custom__liquid-{{ section.id }} rte">
+ {{ block.settings.content }}
+ {{ block.settings.page.content }}
+ {{ block.settings.custom_liquid }}
+ </div>
+ </details>
+ </accordion-tab>
+ {%- endif -%}
+ {%- when 'popup' -%}
+ <modal-opener
+ class="product-popup-modal__opener no-js-hidden"
+ data-modal="#PopupModal-{{ block.id }}"
+ {{ block.shopify_attributes }}
+ >
+ <button
+ id="ProductPopup-{{ block.id }}"
+ class="product-popup-modal__button link link-with-icon"
+ type="button"
+ aria-haspopup="dialog"
+ >
+ {% render 'icon-accordion', icon: block.settings.icon %}
+ <span class="label">{{ block.settings.link_label | default: block.settings.page.title }}</span>
+ </button>
+ </modal-opener>
+ <a href="{{ block.settings.page.url }}" class="product-popup-modal__button link link-with-icon no-js">
{% render 'icon-accordion', icon: block.settings.icon %}
<span class="label">{{ block.settings.link_label | default: block.settings.page.title }}</span>
- </button>
- </modal-opener>
- <a href="{{ block.settings.page.url }}" class="product-popup-modal__button link link-with-icon no-js">
- {% render 'icon-accordion', icon: block.settings.icon %}
- <span class="label">{{ block.settings.link_label | default: block.settings.page.title }}</span>
- </a>
- {%- when 'share' -%}
- {%- liquid
- assign share_url = product.selected_variant.url | default: product.url | prepend: request.origin
- assign share_image = product.selected_or_first_available_variant.featured_media.preview_image | default: product.featured_media.preview_image
- render 'share-button', block: block, share_link: share_url, share_image: share_image, share_title: product.title
- -%}
- {%- when 'inventory_status' -%}
- <ul class="product__inventory list-unstyled" id="inventory-{{ section.id }}" {{ block.shopify_attributes }}>
+ </a>
+ {%- when 'share' -%}
{%- liquid
- assign inventory_visible = false
- if product.selected_or_first_available_variant.inventory_management == 'shopify'
- if product.selected_or_first_available_variant.inventory_quantity <= block.settings.inventory_threshold and product.selected_or_first_available_variant.inventory_quantity >= 0
- assign inventory_visible = true
+ assign share_url = product.selected_variant.url | default: product.url | prepend: request.origin
+ assign share_image = product.selected_or_first_available_variant.featured_media.preview_image | default: product.featured_media.preview_image
+ render 'share-button', block: block, share_link: share_url, share_image: share_image, share_title: product.title
+ -%}
+ {%- when 'inventory_status' -%}
+ <ul
+ class="product__inventory list-unstyled"
+ id="inventory-{{ section.id }}"
+ {{ block.shopify_attributes }}
+ >
+ {%- liquid
+ assign inventory_visible = false
+ if product.selected_or_first_available_variant.inventory_management == 'shopify'
+ if product.selected_or_first_available_variant.inventory_quantity <= block.settings.inventory_threshold and product.selected_or_first_available_variant.inventory_quantity >= 0
+ assign inventory_visible = true
+ endif
endif
- endif
- if product.selected_or_first_available_variant.inventory_quantity == 0 or product.selected_or_first_available_variant.inventory_policy == 'continue'
- assign inventory_visible = false
- endif
+ if product.selected_or_first_available_variant.inventory_quantity == 0 or product.selected_or_first_available_variant.inventory_policy == 'continue'
+ assign inventory_visible = false
+ endif
- assign show_incoming = false
- if product.selected_or_first_available_variant.incoming and inventory_visible == false and product.selected_or_first_available_variant.inventory_quantity <= block.settings.inventory_threshold
- assign show_incoming = true
- endif
- -%}
- {%- if product.selected_or_first_available_variant.available and inventory_visible -%}
- <li class="product__inventory-item">
- {{ 'products.product.inventory.stock_label_html' | t: count: product.selected_or_first_available_variant.inventory_quantity }}
- <progress-bar class="{{ block.settings.color_scheme }}" data-quantity="{{ product.selected_or_first_available_variant.inventory_quantity }}"></progress-bar>
- </li>
- {%- endif -%}
- {%- if block.settings.show_inventory_transfer and show_incoming -%}
- <li class="product__inventory-item">
- <span class="icon-and-text">
- <span class="icon icon--inventory"></span>
- <span class="js-incoming-text">
- {%- liquid
- if product.selected_or_first_available_variant.next_incoming_date
- assign date = product.selected_or_first_available_variant.next_incoming_date | date: format: 'date'
- if product.selected_or_first_available_variant.available
- echo 'products.product.inventory.will_not_ship_until' | t: date: date
+ assign show_incoming = false
+ if product.selected_or_first_available_variant.incoming and inventory_visible == false and product.selected_or_first_available_variant.inventory_quantity <= block.settings.inventory_threshold
+ assign show_incoming = true
+ endif
+ -%}
+ {%- if product.selected_or_first_available_variant.available and inventory_visible -%}
+ <li class="product__inventory-item">
+ {{
+ 'products.product.inventory.stock_label_html'
+ | t: count: product.selected_or_first_available_variant.inventory_quantity
+ }}
+ <progress-bar
+ class="{{ block.settings.color_scheme }}"
+ data-quantity="{{ product.selected_or_first_available_variant.inventory_quantity }}"
+ ></progress-bar>
+ </li>
+ {%- endif -%}
+ {%- if block.settings.show_inventory_transfer and show_incoming -%}
+ <li class="product__inventory-item">
+ <span class="icon-and-text">
+ <span class="icon icon--inventory"></span>
+ <span class="js-incoming-text">
+ {%- liquid
+ if product.selected_or_first_available_variant.next_incoming_date
+ assign date = product.selected_or_first_available_variant.next_incoming_date | date: format: 'date'
+ if product.selected_or_first_available_variant.available
+ echo 'products.product.inventory.will_not_ship_until' | t: date: date
+ else
+ echo 'products.product.inventory.will_be_in_stock_after' | t: date: date
+ endif
else
- echo 'products.product.inventory.will_be_in_stock_after' | t: date: date
+ echo 'products.product.inventory.waiting_for_stock' | t
endif
- else
- echo 'products.product.inventory.waiting_for_stock' | t
- endif
- -%}
+ -%}
+ </span>
</span>
- </span>
- </li>
- {%- endif -%}
- </ul>
- {{ 'component-product-inventory.css' | asset_url | stylesheet_tag }}
- {%- when 'variant_picker' -%}
- {% render 'product-variant-picker', block: block, product: product %}
- {%- when 'buy_buttons' -%}
- {% render 'buy-buttons', block: block, product: product, product_form_id: product_form_id, show_pickup_availability: true %}
- {%- when 'rating' -%}
- {%- if product.metafields.reviews.rating.value != blank -%}
- {% liquid
- assign rating_decimal = 0
- assign decimal = product.metafields.reviews.rating.value.rating | modulo: 1
- if decimal >= 0.3 and decimal <= 0.7
- assign rating_decimal = 0.5
- elsif decimal > 0.7
- assign rating_decimal = 1
- endif
+ </li>
+ {%- endif -%}
+ </ul>
+ {{ 'component-product-inventory.css' | asset_url | stylesheet_tag }}
+ {%- when 'variant_picker' -%}
+ {% render 'product-variant-picker', block: block, product: product %}
+ {%- when 'buy_buttons' -%}
+ {% render 'buy-buttons',
+ block: block,
+ product: product,
+ product_form_id: product_form_id,
+ show_pickup_availability: true
%}
- <div class="rating" role="img" aria-label="{{ 'accessibility.star_reviews_info' | t: rating_value: product.metafields.reviews.rating.value, rating_max: product.metafields.reviews.rating.value.scale_max }}">
- <span aria-hidden="true" class="rating-star" style="--rating: {{ product.metafields.reviews.rating.value.rating | floor }}; --rating-max: {{ product.metafields.reviews.rating.value.scale_max }}; --rating-decimal: {{ rating_decimal }};"></span>
- </div>
- <p class="rating-text caption">
- <span aria-hidden="true">{{ product.metafields.reviews.rating.value }} / {{ product.metafields.reviews.rating.value.scale_max }}</span>
- </p>
- <p class="rating-count caption">
- <span aria-hidden="true">({{ product.metafields.reviews.rating_count }})</span>
- <span class="visually-hidden">{{ product.metafields.reviews.rating_count }} {{ "accessibility.total_reviews" | t }}</span>
- </p>
- {%- endif -%}
- {%- when 'related_buttons' -%}
- <div class="product-link__button product__accordion accordion small-hide" {{ block.shopify_attributes }}>
- <related-buttons data-scrollto="#ProductDetails">
- <a href="#ProductDetails">
- <span class="summary__title">
- {%- liquid
- if block.settings.show_icons
- render 'icon', icon: 'info'
- endif
- -%}
- <span class="accordion__title">{{ 'products.product.view_info' | t }}</span>
+ {%- when 'rating' -%}
+ {%- if product.metafields.reviews.rating.value != blank -%}
+ {% liquid
+ assign rating_decimal = 0
+ assign decimal = product.metafields.reviews.rating.value.rating | modulo: 1
+ if decimal >= 0.3 and decimal <= 0.7
+ assign rating_decimal = 0.5
+ elsif decimal > 0.7
+ assign rating_decimal = 1
+ endif
+ %}
+ <div
+ class="rating"
+ role="img"
+ aria-label="{{ 'accessibility.star_reviews_info' | t: rating_value: product.metafields.reviews.rating.value, rating_max: product.metafields.reviews.rating.value.scale_max }}"
+ >
+ <span
+ aria-hidden="true"
+ class="rating-star"
+ style="--rating: {{ product.metafields.reviews.rating.value.rating | floor }}; --rating-max: {{ product.metafields.reviews.rating.value.scale_max }}; --rating-decimal: {{ rating_decimal }};"
+ ></span>
+ </div>
+ <p class="rating-text caption">
+ <span aria-hidden="true">
+ {{- product.metafields.reviews.rating.value }} /
+ {{ product.metafields.reviews.rating.value.scale_max -}}
</span>
- {%- liquid
- unless block.settings.show_icons
- render 'icon', icon: 'caret'
- endunless
- -%}
- </a>
- {%- if product.media.size > 0 -%}
- <a href="#ProductImages">
+ </p>
+ <p class="rating-count caption">
+ <span aria-hidden="true">({{ product.metafields.reviews.rating_count }})</span>
+ <span class="visually-hidden">
+ {{- product.metafields.reviews.rating_count }}
+ {{ 'accessibility.total_reviews' | t -}}
+ </span>
+ </p>
+ {%- endif -%}
+ {%- when 'related_buttons' -%}
+ <div class="product-link__button product__accordion accordion small-hide" {{ block.shopify_attributes }}>
+ <related-buttons data-scrollto="#ProductDetails">
+ <a href="#ProductDetails">
<span class="summary__title">
{%- liquid
if block.settings.show_icons
- render 'icon', icon: 'images'
+ render 'icon', icon: 'info'
endif
-%}
- <span class="accordion__title">{{ 'products.product.view_images' | t }}</span>
+ <span class="accordion__title">{{ 'products.product.view_info' | t }}</span>
</span>
{%- liquid
unless block.settings.show_icons
@@ -749,15 +943,31 @@
endunless
-%}
</a>
- {%- endif -%}
- </related-buttons>
- </div>
- {%- when 'image' -%}
- {%- if block.settings.image != blank -%}
- <div class="product-link__image" {{ block.shopify_attributes }}>
- {%- if block.settings.link != blank -%}
- <a href="{{ block.settings.link }}">
- {%- endif -%}
+ {%- if product.media.size > 0 -%}
+ <a href="#ProductImages">
+ <span class="summary__title">
+ {%- liquid
+ if block.settings.show_icons
+ render 'icon', icon: 'images'
+ endif
+ -%}
+ <span class="accordion__title">{{ 'products.product.view_images' | t }}</span>
+ </span>
+ {%- liquid
+ unless block.settings.show_icons
+ render 'icon', icon: 'caret'
+ endunless
+ -%}
+ </a>
+ {%- endif -%}
+ </related-buttons>
+ </div>
+ {%- when 'image' -%}
+ {%- if block.settings.image != blank -%}
+ <div class="product-link__image" {{ block.shopify_attributes }}>
+ {%- if block.settings.link != blank -%}
+ <a href="{{ block.settings.link }}">
+ {%- endif -%}
{%- liquid
assign image_height = block.settings.height
assign image_height_2x = block.settings.height | times: 2
@@ -770,52 +980,74 @@
width="{{ block.settings.image.width }}"
height="{{ block.settings.image.height }}"
loading="lazy"
- />
- {%- if block.settings.link != blank -%}
- </a>
- {%- endif -%}
- </div>
- {%- endif -%}
- {%- when 'countdown' -%}
- {%- if product.metafields.theme.countdown.value != blank -%}
- {%- liquid
- assign now_time = 'now' | date: '%s' | times: 1
- assign countdown_time = product.metafields.theme.countdown.value | date: '%s' | times: 1
- -%}
- {%- if countdown_time > now_time -%}
- <div id="countdown-{{ block.id }}" class="product-countdown product-countdown--{{ block.settings.number_size }}">
- {%- if block.settings.heading != blank -%}
- <p class="h4">
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path d="M381.2 172.8C377.1 164.9 368.9 160 360 160h-156.6l50.84-127.1c2.969-7.375 2.062-15.78-2.406-22.38S239.1 0 232 0h-176C43.97 0 33.81 8.906 32.22 20.84l-32 240C-.7179 267.7 1.376 274.6 5.938 279.8C10.5 285 17.09 288 24 288h146.3l-41.78 194.1c-2.406 11.22 3.469 22.56 14 27.09C145.6 511.4 148.8 512 152 512c7.719 0 15.22-3.75 19.81-10.44l208-304C384.8 190.2 385.4 180.7 381.2 172.8z"/></svg>
- {{- block.settings.heading | escape -}}
- </p>
+ >
+ {%- if block.settings.link != blank -%}
+ </a>
{%- endif -%}
- <countdown-timer class="countdown countdown--{{ block.settings.number_size }}" data-date="{{ product.metafields.theme.countdown.value | escape }}"{% if block.settings.number_size == 'compact' %} data-compact="true"{% endif %} {{ block.shopify_attributes }}></countdown-timer>
- {%- style -%}
- #countdown-{{ block.id }} {
- --color-background: {{ block.settings.colors_background.red }}, {{ block.settings.colors_background.green }}, {{ block.settings.colors_background.blue }};
- --color-foreground: {{ block.settings.colors_text.red }}, {{ block.settings.colors_text.green }}, {{ block.settings.colors_text.blue }};
- --color-heading: {{ block.settings.colors_heading.red }}, {{ block.settings.colors_heading.green }}, {{ block.settings.colors_heading.blue }};
- }
- {%- endstyle -%}
- {{ 'section-countdown-timer.css' | asset_url | stylesheet_tag }}
</div>
{%- endif -%}
- {%- endif -%}
- {%- when 'separator' -%}
- <div class="product-separator" {{ block.shopify_attributes }}>
- <hr/>
- </div>
- {%- when 'spacing' -%}
- <div class="spacing-section" style="--spacing-section-desktop: {{ block.settings.desktop_height }}px; --spacing-section-mobile: {{ block.settings.mobile_height }}px;" {{ block.shopify_attributes }}></div>
- {%- when 'breadcrumb' -%}
- <div class="breadcrumb-wrapper" {{ block.shopify_attributes }}>
- {% render 'breadcrumbs', text_style: block.settings.text_style, show_divider: block.settings.show_divider %}
- </div>
- {%- when 'complementary' -%}
- <product-recommendations class="complementary-products{% if block.settings.make_collapsible_row %} is-accordion{% endif %} no-js-hidden" data-url="{{ routes.product_recommendations_url }}?section_id={{ section.id }}&product_id={{ product.id }}&limit={{ block.settings.product_list_limit }}&intent=complementary">
- {%- if recommendations.performed and recommendations.products_count > 0 -%}
- {%- capture complementary_products -%}
+ {%- when 'countdown' -%}
+ {%- if product.metafields.theme.countdown.value != blank -%}
+ {%- liquid
+ assign now_time = 'now' | date: '%s' | times: 1
+ assign countdown_time = product.metafields.theme.countdown.value | date: '%s' | times: 1
+ -%}
+ {%- if countdown_time > now_time -%}
+ <div
+ id="countdown-{{ block.id }}"
+ class="product-countdown product-countdown--{{ block.settings.number_size }}"
+ >
+ {%- if block.settings.heading != blank -%}
+ <p class="h4">
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512">
+ <path d="M381.2 172.8C377.1 164.9 368.9 160 360 160h-156.6l50.84-127.1c2.969-7.375 2.062-15.78-2.406-22.38S239.1 0 232 0h-176C43.97 0 33.81 8.906 32.22 20.84l-32 240C-.7179 267.7 1.376 274.6 5.938 279.8C10.5 285 17.09 288 24 288h146.3l-41.78 194.1c-2.406 11.22 3.469 22.56 14 27.09C145.6 511.4 148.8 512 152 512c7.719 0 15.22-3.75 19.81-10.44l208-304C384.8 190.2 385.4 180.7 381.2 172.8z"/>
+ </svg>
+ {{- block.settings.heading | escape -}}
+ </p>
+ {%- endif -%}
+ <countdown-timer
+ class="countdown countdown--{{ block.settings.number_size }}"
+ data-date="{{ product.metafields.theme.countdown.value | escape }}"
+ {% if block.settings.number_size == 'compact' %}
+ data-compact="true"
+ {% endif %}
+ {{ block.shopify_attributes }}
+ ></countdown-timer>
+ {%- style -%}
+ #countdown-{{ block.id }} {
+ --color-background: {{ block.settings.colors_background.red }}, {{ block.settings.colors_background.green }}, {{ block.settings.colors_background.blue }};
+ --color-foreground: {{ block.settings.colors_text.red }}, {{ block.settings.colors_text.green }}, {{ block.settings.colors_text.blue }};
+ --color-heading: {{ block.settings.colors_heading.red }}, {{ block.settings.colors_heading.green }}, {{ block.settings.colors_heading.blue }};
+ }
+ {%- endstyle -%}
+ {{ 'section-countdown-timer.css' | asset_url | stylesheet_tag }}
+ </div>
+ {%- endif -%}
+ {%- endif -%}
+ {%- when 'separator' -%}
+ <div class="product-separator" {{ block.shopify_attributes }}>
+ <hr>
+ </div>
+ {%- when 'spacing' -%}
+ <div
+ class="spacing-section"
+ style="--spacing-section-desktop: {{ block.settings.desktop_height }}px; --spacing-section-mobile: {{ block.settings.mobile_height }}px;"
+ {{ block.shopify_attributes }}
+ ></div>
+ {%- when 'breadcrumb' -%}
+ <div class="breadcrumb-wrapper" {{ block.shopify_attributes }}>
+ {% render 'breadcrumbs',
+ text_style: block.settings.text_style,
+ show_divider: block.settings.show_divider
+ %}
+ </div>
+ {%- when 'complementary' -%}
+ <product-recommendations
+ class="complementary-products{% if block.settings.make_collapsible_row %} is-accordion{% endif %} no-js-hidden"
+ data-url="{{ routes.product_recommendations_url }}?section_id={{ section.id }}&product_id={{ product.id }}&limit={{ block.settings.product_list_limit }}&intent=complementary"
+ >
+ {%- if recommendations.performed and recommendations.products_count > 0 -%}
+ {%- capture complementary_products -%}
<ul class="list-unstyled" role="list" style="--image-position: {{ block.settings.image_position }}">
{%- for product in recommendations.products -%}
<li>
@@ -837,87 +1069,140 @@
{%- endfor -%}
</ul>
{%- endcapture -%}
- {%- if block.settings.make_collapsible_row -%}
- <accordion-tab class="product__accordion accordion" {{ block.shopify_attributes }}>
- <details open>
- <summary>
- <span class="summary__title">
- {% render 'icon-accordion', icon: block.settings.icon %}
- <span class="accordion__title">
- {{ block.settings.heading | escape }}
+ {%- if block.settings.make_collapsible_row -%}
+ <accordion-tab class="product__accordion accordion" {{ block.shopify_attributes }}>
+ <details open>
+ <summary>
+ <span class="summary__title">
+ {% render 'icon-accordion', icon: block.settings.icon %}
+ <span class="accordion__title">
+ {{ block.settings.heading | escape }}
+ </span>
</span>
+ {% render 'icon', icon: 'caret' %}
+ </summary>
+ <div class="accordion__content">
+ {{ complementary_products }}
+ </div>
+ </details>
+ </accordion-tab>
+ {%- else -%}
+ <div class="product__accordion accordion" {{ block.shopify_attributes }}>
+ <span class="summary__title">
+ {% render 'icon-accordion', icon: block.settings.icon %}
+ <span class="accordion__title">
+ {{ block.settings.heading | escape }}
</span>
- {% render 'icon', icon: 'caret' %}
- </summary>
+ </span>
<div class="accordion__content">
{{ complementary_products }}
</div>
- </details>
- </accordion-tab>
- {%- else -%}
- <div class="product__accordion accordion" {{ block.shopify_attributes }}>
- <span class="summary__title">
- {% render 'icon-accordion', icon: block.settings.icon %}
- <span class="accordion__title">
- {{ block.settings.heading | escape }}
- </span>
- </span>
- <div class="accordion__content">
- {{ complementary_products }}
</div>
- </div>
+ {%- endif -%}
{%- endif -%}
- {%- endif -%}
- {{ 'component-card.css' | asset_url | stylesheet_tag }}
- {{ 'section-product-recommendations.css' | asset_url | stylesheet_tag }}
- {{ 'component-complementary-products.css' | asset_url | stylesheet_tag }}
- </product-recommendations>
- {%- when 'line_item_property' -%}
- <div class="product-form__input" {{ block.shopify_attributes }}>
- {%- if block.settings.type == 'checkbox' -%}
- <label for="line-item-{{ section.id }}-{{ block.id }}" class="form__facet-checkbox">
- <input type="hidden" name="properties[{{ block.settings.label | escape }}]" value="{{ block.settings.unchecked_value | escape }}" form="{{ product_form_id }}" />
- <input id="line-item-{{ section.id }}-{{ block.id }}" type="checkbox" name="properties[{{ block.settings.label | escape }}]" value="{{ block.settings.checked_value | escape }}"{% if block.settings.required %} required{% endif %} form="{{ product_form_id }}" />
- {% render 'icon', icon: 'checkmark' %}
- {{ block.settings.label | escape }}
- </label>
- {%- else -%}
- <label class="form__label" for="line-item-{{ section.id }}-{{ block.id }}">{{ block.settings.label | escape }}</label>
- {%- case block.settings.type -%}
- {%- when 'text' -%}
- <input class="field__input" id="line-item-{{ section.id }}-{{ block.id }}" type="text" name="properties[{{ block.settings.label | escape }}]"{% if block.settings.required %} required{% endif %} form="{{ product_form_id }}" />
- {%- when 'textarea' -%}
- <textarea class="text-area field__input" id="line-item-{{ section.id }}-{{ block.id }}" name="properties[{{ block.settings.label | escape }}]"{% if block.settings.required %} required{% endif %} form="{{ product_form_id }}"></textarea>
- {%- when 'radio' -%}
- {%- assign options = block.settings.radio_options | split: ',' -%}
- {%- if options.size > 1 -%}
- <fieldset class="product-form__input">
- {%- for option in options -%}
- <label class="form__facet-radio" for="line-item-{{ section.id }}-{{ block.id }}-{{ forloop.index0 }}">
- <input id="line-item-{{ section.id }}-{{ block.id }}-{{ forloop.index0 }}" type="radio" name="properties[{{ block.settings.label | escape }}]" value="{{ option | strip | escape }}"{% if block.settings.required %} required{% endif %} form="{{ product_form_id }}" />
- <span class="icon"></span>
- {{ option | strip | escape }}
- </label>
- {%- endfor -%}
- </fieldset>
- {%- endif -%}
- {%- when 'select' -%}
- {%- assign options = block.settings.select_options | split: ',' -%}
- {%- if options.size > 1 -%}
- <select-wrapper class="select">
- <select class="select__select" id="line-item-{{ section.id }}-{{ block.id }}" name="properties[{{ block.settings.label | escape }}]"{% if block.settings.required %} required{% endif %} form="{{ product_form_id }}">
+ {{ 'component-card.css' | asset_url | stylesheet_tag }}
+ {{ 'section-product-recommendations.css' | asset_url | stylesheet_tag }}
+ {{ 'component-complementary-products.css' | asset_url | stylesheet_tag }}
+ </product-recommendations>
+ {%- when 'line_item_property' -%}
+ <div class="product-form__input" {{ block.shopify_attributes }}>
+ {%- if block.settings.type == 'checkbox' -%}
+ <label for="line-item-{{ section.id }}-{{ block.id }}" class="form__facet-checkbox">
+ <input
+ type="hidden"
+ name="properties[{{ block.settings.label | escape }}]"
+ value="{{ block.settings.unchecked_value | escape }}"
+ form="{{ product_form_id }}"
+ >
+ <input
+ id="line-item-{{ section.id }}-{{ block.id }}"
+ type="checkbox"
+ name="properties[{{ block.settings.label | escape }}]"
+ value="{{ block.settings.checked_value | escape }}"
+ {% if block.settings.required %}
+ required
+ {% endif %}
+ form="{{ product_form_id }}"
+ >
+ {% render 'icon', icon: 'checkmark' %}
+ {{ block.settings.label | escape }}
+ </label>
+ {%- else -%}
+ <label class="form__label" for="line-item-{{ section.id }}-{{ block.id }}">
+ {{- block.settings.label | escape -}}
+ </label>
+ {%- case block.settings.type -%}
+ {%- when 'text' -%}
+ <input
+ class="field__input"
+ id="line-item-{{ section.id }}-{{ block.id }}"
+ type="text"
+ name="properties[{{ block.settings.label | escape }}]"
+ {% if block.settings.required %}
+ required
+ {% endif %}
+ form="{{ product_form_id }}"
+ >
+ {%- when 'textarea' -%}
+ <textarea
+ class="text-area field__input"
+ id="line-item-{{ section.id }}-{{ block.id }}"
+ name="properties[{{ block.settings.label | escape }}]"
+ {% if block.settings.required %}
+ required
+ {% endif %}
+ form="{{ product_form_id }}"
+ ></textarea>
+ {%- when 'radio' -%}
+ {%- assign options = block.settings.radio_options | split: ',' -%}
+ {%- if options.size > 1 -%}
+ <fieldset class="product-form__input">
{%- for option in options -%}
- <option value="{{ option | strip | escape }}">
+ <label
+ class="form__facet-radio"
+ for="line-item-{{ section.id }}-{{ block.id }}-{{ forloop.index0 }}"
+ >
+ <input
+ id="line-item-{{ section.id }}-{{ block.id }}-{{ forloop.index0 }}"
+ type="radio"
+ name="properties[{{ block.settings.label | escape }}]"
+ value="{{ option | strip | escape }}"
+ {% if block.settings.required %}
+ required
+ {% endif %}
+ form="{{ product_form_id }}"
+ >
+ <span class="icon"></span>
{{ option | strip | escape }}
- </option>
+ </label>
{%- endfor -%}
- </select>
- {% render 'icon', icon: 'caret' %}
- </select-wrapper>
- {%- endif -%}
- {%- endcase-%}
- {%- endif -%}
- </div>
+ </fieldset>
+ {%- endif -%}
+ {%- when 'select' -%}
+ {%- assign options = block.settings.select_options | split: ',' -%}
+ {%- if options.size > 1 -%}
+ <select-wrapper class="select">
+ <select
+ class="select__select"
+ id="line-item-{{ section.id }}-{{ block.id }}"
+ name="properties[{{ block.settings.label | escape }}]"
+ {% if block.settings.required %}
+ required
+ {% endif %}
+ form="{{ product_form_id }}"
+ >
+ {%- for option in options -%}
+ <option value="{{ option | strip | escape }}">
+ {{ option | strip | escape }}
+ </option>
+ {%- endfor -%}
+ </select>
+ {% render 'icon', icon: 'caret' %}
+ </select-wrapper>
+ {%- endif -%}
+ {%- endcase -%}
+ {%- endif -%}
+ </div>
{%- endcase -%}
{%- endfor -%}
</div>
@@ -926,11 +1211,22 @@
{% render 'product-media-modal', product: product, variant_images: variant_images %}
- {%- assign popups = section.blocks | where: "type", "popup" -%}
+ {%- assign popups = section.blocks | where: 'type', 'popup' -%}
{%- for block in popups -%}
<modal-dialog id="PopupModal-{{ block.id }}" class="product-popup-modal">
- <div role="dialog" aria-label="{{ block.settings.link_label }}" aria-modal="true" class="product-popup-modal__content" tabindex="-1">
- <button id="ModalClose-{{ block.id }}" type="button" class="product-popup-modal__toggle" aria-label="{{ 'accessibility.close' | t }}">
+ <div
+ role="dialog"
+ aria-label="{{ block.settings.link_label }}"
+ aria-modal="true"
+ class="product-popup-modal__content"
+ tabindex="-1"
+ >
+ <button
+ id="ModalClose-{{ block.id }}"
+ type="button"
+ class="product-popup-modal__toggle"
+ aria-label="{{ 'accessibility.close' | t }}"
+ >
<span class="icon icon-plus-alt"></span>
</button>
<div class="product-popup-modal__content-info">
@@ -941,11 +1237,22 @@
</modal-dialog>
{%- endfor -%}
- {%- assign block_variant_picker = section.blocks | where: "type", "variant_picker" | first -%}
+ {%- assign block_variant_picker = section.blocks | where: 'type', 'variant_picker' | first -%}
{%- if block_variant_picker and block_variant_picker.settings.size_chart != blank -%}
<modal-dialog id="PopupModal-{{ block_variant_picker.id }}" class="product-popup-modal">
- <div role="dialog" aria-label="{{ block_variant_picker.settings.link_label }}" aria-modal="true" class="product-popup-modal__content" tabindex="-1">
- <button id="ModalClose-{{ block_variant_picker.id }}" type="button" class="product-popup-modal__toggle" aria-label="{{ 'accessibility.close' | t }}">
+ <div
+ role="dialog"
+ aria-label="{{ block_variant_picker.settings.link_label }}"
+ aria-modal="true"
+ class="product-popup-modal__content"
+ tabindex="-1"
+ >
+ <button
+ id="ModalClose-{{ block_variant_picker.id }}"
+ type="button"
+ class="product-popup-modal__toggle"
+ aria-label="{{ 'accessibility.close' | t }}"
+ >
<span class="icon icon-plus-alt"></span>
</button>
<div class="product-popup-modal__content-info">
@@ -956,9 +1263,14 @@
</modal-dialog>
{%- endif -%}
- {%- assign sticky_cart = section.blocks | where: "type", "sticky_cart" | first -%}
+ {%- assign sticky_cart = section.blocks | where: 'type', 'sticky_cart' | first -%}
{%- if sticky_cart -%}
- <link rel="stylesheet" href="{{ 'component-product-sticky-cart.css' | asset_url }}" media="print" onload="this.media='all'">
+ <link
+ rel="stylesheet"
+ href="{{ 'component-product-sticky-cart.css' | asset_url }}"
+ media="print"
+ onload="this.media='all'"
+ >
<animate-sticky class="sticky-cart-wrapper hidden">
<span class="sticky-cart-block" {{ sticky_cart.shopify_attributes }}></span>
<div class="product-sticky-cart" id="sticky-cart-{{ section.id }}">
@@ -968,14 +1280,15 @@
{%- assign block_image = featured_media | default: first_image -%}
{%- if block_image != null -%}
<div>
- <img srcset="{{ block_image.preview_image | image_url: width: 70 }} 1x, {{ block_image.preview_image | image_url: width: 140 }} 2x"
+ <img
+ srcset="{{ block_image.preview_image | image_url: width: 70 }} 1x, {{ block_image.preview_image | image_url: width: 140 }} 2x"
src="{{ block_image.preview_image | image_url: width: 70 }}"
alt="{{ block_image.preview_image.alt | escape | split: '#' | first }}"
loading="lazy"
width="70"
height="{{ 70 | divided_by: block_image.preview_image.aspect_ratio | ceil }}"
is="lazy-image"
- />
+ >
</div>
{%- endif -%}
</div>
@@ -986,44 +1299,71 @@
</div>
</div>
</div>
- <product-form class="sticky-cart__form">
+ <product-form
+ class="sticky-cart__form"
+ >
{%- assign sticky_cart_form_id = product_form_id | append: '--alt' -%}
- {%- form 'product', product, id: sticky_cart_form_id, novalidate: 'novalidate', data-type: 'add-to-cart-form' -%}
- <input type="hidden" name="id" value="{{ product.selected_or_first_available_variant.id }}" disabled="disabled">
+ {%- form 'product',
+ product,
+ id: sticky_cart_form_id,
+ novalidate: 'novalidate',
+ data-type: 'add-to-cart-form'
+ -%}
+ <input
+ type="hidden"
+ name="id"
+ value="{{ product.selected_or_first_available_variant.id }}"
+ disabled="disabled"
+ >
<div class="product-form__buttons">
{%- if sticky_cart.settings.show_quantity_selector -%}
<div class="product-form__quantity small-hide">
- <label for="Quantity-{{ sticky_cart.id }}" class="visually-hidden">{{ 'products.product.quantity.label' | t }}</label>
+ <label for="Quantity-{{ sticky_cart.id }}" class="visually-hidden">
+ {{- 'products.product.quantity.label' | t -}}
+ </label>
<quantity-input class="quantity">
- <input class="quantity__input"
+ <input
+ class="quantity__input"
type="number"
name="quantity"
id="Quantity-{{ sticky_cart.id }}"
min="1"
value="1"
form="{{ sticky_cart_form_id }}"
- />
+ >
</quantity-input>
</div>
{%- endif -%}
{%- unless product.has_only_default_variant -%}
- <variant-selects class="no-js-hidden small-hide" data-section="{{ section.id }}" data-url="{{ product.url }}" data-no-scroll>
+ <variant-selects
+ class="no-js-hidden small-hide"
+ data-section="{{ section.id }}"
+ data-url="{{ product.url }}"
+ data-no-scroll
+ >
{%- for option in product.options_with_values -%}
{%- assign option_idx = forloop.index -%}
- <div class="product-form__input variant-input-wrapper"
+ <div
+ class="product-form__input variant-input-wrapper"
data-option-index="option{{ option_idx }}"
data-option-slug="{{ option.name | handleize }}"
>
<select-wrapper class="select button--small">
- <select class="select__select"
+ <select
+ class="select__select"
name="{{ option.name | escape }}"
form="{{ sticky_cart_form_id }}"
data-variant="{{ variant.id }}-{{ option.option }}"
>
{%- for value in option.values -%}
- <option value="{{ value | escape }}" {% if option.selected_value == value %}selected="selected"{% endif %}>
+ <option
+ value="{{ value | escape }}"
+ {% if option.selected_value == value %}
+ selected="selected"
+ {% endif %}
+ >
{{ value }}
</option>
{%- endfor -%}
@@ -1032,7 +1372,7 @@
</select-wrapper>
</div>
{%- endfor -%}
-
+
<script type="application/json">
{{ product.variants | json }}
</script>
@@ -1043,8 +1383,12 @@
type="submit"
name="add"
class="product-form__submit button button--small"
- {%- if product.selected_or_first_available_variant.available == false %} disabled="disabled"{% endif -%}
- {%- if product.template_suffix == 'pre-order' %} data-pre-order="true"{% endif -%}
+ {%- if product.selected_or_first_available_variant.available == false %}
+ disabled="disabled"
+ {% endif -%}
+ {%- if product.template_suffix == 'pre-order' %}
+ data-pre-order="true"
+ {% endif -%}
>
{%- liquid
if product.selected_or_first_available_variant.available
@@ -1060,6 +1404,9 @@
</button>
</div>
{%- endform -%}
+ <script type="application/json" id="media">
+ {{ product.media | json }}
+ </script>
</product-form>
</div>
</div>
@@ -1073,23 +1420,27 @@
{%- endif -%}
<script>
- document.addEventListener('DOMContentLoaded', function() {
+ document.addEventListener('DOMContentLoaded', function () {
function isIE() {
const ua = window.navigator.userAgent;
const msie = ua.indexOf('MSIE ');
const trident = ua.indexOf('Trident/');
- return (msie > 0 || trident > 0);
+ return msie > 0 || trident > 0;
}
if (!isIE()) return;
const hiddenInput = document.querySelector('#{{ product_form_id }} input[name="id"]');
const noScriptInputWrapper = document.createElement('div');
- const variantSwitcher = document.querySelector('variant-radios[data-section="{{ section.id }}"]') || document.querySelector('variant-selects[data-section="{{ section.id }}"]');
- noScriptInputWrapper.innerHTML = document.querySelector('.product-form__noscript-wrapper-{{ section.id }}').textContent;
+ const variantSwitcher =
+ document.querySelector('variant-radios[data-section="{{ section.id }}"]') ||
+ document.querySelector('variant-selects[data-section="{{ section.id }}"]');
+ noScriptInputWrapper.innerHTML = document.querySelector(
+ '.product-form__noscript-wrapper-{{ section.id }}'
+ ).textContent;
variantSwitcher.outerHTML = noScriptInputWrapper.outerHTML;
- document.querySelector('#Variants-{{ section.id }}').addEventListener('change', function(event) {
+ document.querySelector('#Variants-{{ section.id }}').addEventListener('change', function (event) {
hiddenInput.value = event.currentTarget.value;
});
});
@@ -1368,7 +1719,7 @@
{
"value": "truck",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__43.label"
- },
+ },
{
"value": "washing",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__44.label"
@@ -2036,7 +2387,7 @@
{
"value": "truck",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__43.label"
- },
+ },
{
"value": "washing",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__44.label"
@@ -2239,7 +2590,7 @@
{
"value": "truck",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__43.label"
- },
+ },
{
"value": "washing",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__44.label"
@@ -2766,7 +3117,7 @@
{
"value": "truck",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__43.label"
- },
+ },
{
"value": "washing",
"label": "t:sections.main-product.blocks.collapsible_tab.settings.icon.options__44.label"
diff --git a/legacy/snippets/custom-product-image.liquid b/legacy/snippets/custom-product-image.liquid
new file mode 100644
index 0000000..e0f1ce2
--- /dev/null
+++ b/legacy/snippets/custom-product-image.liquid
@@ -0,0 +1,82 @@
+{% comment %}
+ Extension of 'product-image.liquid' to be used in conjunction with {{ settings.custom_variant_image }} feature
+ theme-check-disable ImgLazyLoading
+{% endcomment %}
+
+{%- capture sizes -%}(min-width: {{ settings.page_width }}px) {{ settings.page_width | minus: 100 | times: media_width | round }}px, (min-width: 990px) calc({{ media_width | times: 100 }}vw - 10rem), (min-width: 750px) calc((100vw - 10rem) / 2), calc(100vw - 3rem){%- endcapture -%}
+{%- liquid
+ assign image_loading = 'eager'
+ if lazy_load
+ assign image_loading = 'lazy'
+ endif
+
+ assign alt = 'default-custom-variant-product-image'
+ assign widths = '165, 360, 535, 750, 1100, 1500'
+ assign media_id = 'default-custom-variant-product-image'
+-%}
+<li
+ id="Slide-{{ section.id }}-{{ media_id }}"
+ class="product__media-item grid__item slider__slide{% if single_media_visible %} product__media-item--single{% endif %}{% if featured_media == null and forloop.first %} is-active{% endif %}{% if media.media_type != 'image' %} product__media-item--full{% endif %}{% if section.settings.hide_variants and variant_images contains media.src %} product__media-item--variant{% endif %}{% if gang_media_active == true %} gang__active{% endif %}"
+ data-media-id="{{ section.id }}-{{ media_id }}"
+ data-media-position="{{ position }}"
+ {% if gang_exist == true %}
+ data-gang-option="{{ gang_option_name }}" data-gang-connect="{{ gang_connect }}"
+ {% endif %}
+>
+ <noscript>
+ <div class="media-wrapper">
+ <div
+ class="product__media media media--{{ image_ratio }}{% if mobile_image_ratio %} media-mobile--{{ mobile_image_ratio }}{% endif %}"
+ {%- if image_ratio == 'adapt' or mobile_image_ratio == 'adapt' %}
+ style="--image-ratio-percent: {{ 1 | divided_by: media.preview_image.aspect_ratio | times: 100 }}%;"
+ {% endif -%}
+ >
+ {{
+ settings.custom_variant_image_default
+ | image_url: width: 1500
+ | image_tag: loading: image_loading, sizes: sizes, widths: widths, alt: alt, is: 'lazy-image'
+ }}
+ </div>
+ </div>
+ </noscript>
+
+ <modal-opener
+ class="product__modal-opener product__modal-opener--image no-js-hidden"
+ data-modal="#ProductModal-{{ modal_id }}"
+ >
+ {%- if zoom -%}
+ <span class="product__media-icon motion-reduce" aria-hidden="true">
+ {% render 'icon', icon: 'zoom' %}
+ </span>
+ {%- endif -%}
+
+ <use-animate
+ data-animate="{% if position == 'featured' %}zoom-fade-small{% else %}fade-up{% endif %}"
+ class="media-wrapper"
+ >
+ <div
+ class="product__media image-animate media media--{{ image_ratio }}{% if mobile_image_ratio %} media-mobile--{{ mobile_image_ratio }}{% endif %}"
+ {%- if image_ratio == 'adapt' or mobile_image_ratio == 'adapt' %}
+ style="--image-ratio-percent: {{ 1 | divided_by: settings.custom_variant_image_default.aspect_ratio | times: 100 }}%;"
+ {% endif -%}
+ >
+ {{
+ settings.custom_variant_image_default
+ | image_url: width: 1500
+ | image_tag: loading: image_loading, sizes: sizes, widths: widths, alt: alt, is: 'lazy-image'
+ }}
+ </div>
+ </use-animate>
+ {%- if zoom -%}
+ <button class="product__media-toggle" type="button" aria-haspopup="dialog" data-media-id="{{ media_id }}">
+ <span class="visually-hidden">
+ {%- if position == 'featured' %}
+ {{ 'products.product.media.open_media' | t }}
+ {%- else -%}
+ {{ 'products.product.media.open_media' | t: index: position }}
+ {%- endif -%}
+ </span>
+ </button>
+ {%- endif -%}
+ </modal-opener>
+</li>
diff --git a/legacy/templates/collection.json b/legacy/templates/collection.json
index 7b69ef3..3c16c19 100644
--- a/legacy/templates/collection.json
+++ b/legacy/templates/collection.json
@@ -44,7 +44,7 @@
"enable_sorting": true,
"enable_viewing": false,
"enable_filtering": true,
- "filter_type": "vertical",
+ "filter_type": "horizontal",
"enable_filtering_color_swatches": false,
"filtering_color_swatches_add_label": false,
"filtering_max_items": 6,
diff --git a/legacy/templates/product.json b/legacy/templates/product.json
index 5fa51d4..3d9fe41 100644
--- a/legacy/templates/product.json
+++ b/legacy/templates/product.json
@@ -319,7 +319,7 @@
"settings": {
"product_list_limit": 4,
"show_divider": false,
- "heading": "You May Also Like",
+ "heading": "Sold Together",
"heading_size": "h1",
"heading_alignment": "center",
"heading_tag": "h2",
diff --git a/legacy/templates/search.json b/legacy/templates/search.json
index a35025b..79dbb96 100644
--- a/legacy/templates/search.json
+++ b/legacy/templates/search.json
@@ -11,7 +11,7 @@
"enable_sorting": true,
"enable_viewing": false,
"enable_filtering": true,
- "filter_type": "vertical",
+ "filter_type": "horizontal",
"enable_filtering_color_swatches": false,
"filtering_color_swatches_add_label": false,
"filtering_max_items": 6,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment