initial commit

This commit is contained in:
Gerhard Scheikl
2026-08-24 21:41:12 +02:00
commit 5c952a25b1
367 changed files with 134961 additions and 0 deletions
+155
View File
@@ -0,0 +1,155 @@
{% comment %}
Renders an article card for a given blog with settings to either show the image or not.
Accepts:
- blog: {Object} Blog object
- article: {Object} Article object
- media_aspect_ratio: {String} The setting changes the aspect ratio of the article image, if shown
- media_height: {String} The setting changes the height of the article image. Overrides media_aspect_ratio.
- show_image: {String} The setting either show the article image or not. If it's not included it will show the image by default
- show_date: {String} The setting either show the article date or not. If it's not included it will not show the image by default
- show_author: {String} The setting either show the article author or not. If it's not included it will not show the author by default
- show_badge: {String} The setting either show the blog badge or not.
- lazy_load: {Boolean} Image should be lazy loaded. Default: true (optional)
Usage:
{% render 'article-card' blog: blog, article: article, show_image: section.settings.show_image %}
{% endcomment %}
{%- if article and article != empty -%}
{%- liquid
assign ratio = 1
if media_aspect_ratio != null
assign ratio = media_aspect_ratio
endif
-%}
<div class="article-card-wrapper card-wrapper underline-links-hover">
{% comment %} <article aria-labelledby="Article-{{ article.id }}"> {% endcomment %}
<div
class="
card article-card
card--{{ settings.blog_card_style }}
{% if media_height and media_height != 'adapt' %} article-card__image--{{ media_height }}{% endif %}
{% if article.image and show_image %} card--media{% else %} card--text{% endif %}
{% if settings.blog_card_style == 'card' %} color-{{ settings.blog_card_color_scheme }} gradient{% endif %}
{% if settings.blog_card_style == 'card' and media_height == nil and article.image == empty or show_image == false %} ratio{% endif %}
"
style="--ratio-percent: {{ 1 | divided_by: ratio | times: 100 }}%;"
>
<div
class="card__inner {% if settings.blog_card_style == 'standard' %} color-{{ settings.blog_card_color_scheme }} gradient{% endif %}{% if article.image and show_image or settings.blog_card_style == 'standard' %} ratio{% endif %}"
style="--ratio-percent: {{ 1 | divided_by: ratio | times: 100 }}%;"
>
{%- if show_image == true and article.image -%}
<div class="article-card__image-wrapper card__media">
<div
class="article-card__image media media--hover-effect"
{% if section.settings.media_height == 'adapt' %}
style="padding-bottom: {{ 1 | divided_by: article.image.aspect_ratio | times: 100 }}%;"
{% endif %}
>
{% comment %}theme-check-disable ImgLazyLoading{% endcomment %}
<img
srcset="
{%- if article.image.src.width >= 165 -%}{{ article.image.src | image_url: width: 165 }} 165w,{%- endif -%}
{%- if article.image.src.width >= 360 -%}{{ article.image.src | image_url: width: 360 }} 360w,{%- endif -%}
{%- if article.image.src.width >= 533 -%}{{ article.image.src | image_url: width: 533 }} 533w,{%- endif -%}
{%- if article.image.src.width >= 720 -%}{{ article.image.src | image_url: width: 720 }} 720w,{%- endif -%}
{%- if article.image.src.width >= 1000 -%}{{ article.image.src | image_url: width: 1000 }} 1000w,{%- endif -%}
{%- if article.image.src.width >= 1500 -%}{{ article.image.src | image_url: width: 1500 }} 1500w,{%- endif -%}
{{ article.image.src | image_url }} {{ article.image.src.width }}w
"
src="{{ article.image.src | image_url: width: 533 }}"
sizes="(min-width: {{ settings.page_width }}px) {{ settings.page_width | minus: 100 | divided_by: 2 }}px, (min-width: 750px) calc((100vw - 130px) / 2), calc((100vw - 50px) / 2)"
alt="{{ article.image.src.alt | escape }}"
class="motion-reduce"
{% unless lazy_load == false %}
loading="lazy"
{% endunless %}
width="{{ article.image.width }}"
height="{{ article.image.height }}"
>
{% comment %}theme-check-enable ImgLazyLoading{% endcomment %}
</div>
</div>
{%- endif -%}
<div class="card__content">
<div class="card__information">
<h3 class="card__heading{% if show_excerpt %} h2{% endif %}">
<a href="{{ article.url }}" class="full-unstyled-link">
{{ article.title | truncate: 50 | escape }}
</a>
</h3>
<div class="article-card__info caption-with-letter-spacing h5">
{%- if show_date -%}
<span class="circle-divider">{{ article.published_at | time_tag: format: 'date' }}</span>
{%- endif -%}
{%- if show_author -%}
<span>{{ article.author }}</span>
{%- endif -%}
</div>
{%- if show_excerpt -%}
{%- if article.excerpt.size > 0 or article.content.size > 0 -%}
<p class="article-card__excerpt rte-width">
{%- if article.excerpt.size > 0 -%}
{{ article.excerpt | strip_html | truncatewords: 30 }}
{%- else -%}
{{ article.content | strip_html | truncatewords: 30 }}
{%- endif -%}
</p>
{%- endif -%}
<div class="article-card__footer">
{%- if article.comments_count > 0 and blog.comments_enabled? -%}
<span>{{ 'blogs.article.comments' | t: count: article.comments_count }}</span>
{%- endif -%}
</div>
{%- endif -%}
</div>
{%- if show_badge -%}
<div class="card__badge {{ settings.badge_position }}">
<span class="badge color-{{ settings.color_schemes | first }}">{{ 'blogs.article.blog' | t }}</span>
</div>
{%- endif -%}
</div>
</div>
<div class="card__content">
<div class="card__information">
<h3 class="card__heading{% if show_excerpt %} h2{% endif %}">
<a href="{{ article.url }}" class="full-unstyled-link">
{{ article.title | truncate: 50 | escape }}
</a>
</h3>
<div class="article-card__info caption-with-letter-spacing h5">
{%- if show_date -%}
<span class="circle-divider">{{ article.published_at | time_tag: format: 'date' }}</span>
{%- endif -%}
{%- if show_author -%}
<span>{{ article.author }}</span>
{%- endif -%}
</div>
{%- if show_excerpt -%}
{%- if article.excerpt.size > 0 or article.content.size > 0 -%}
<p class="article-card__excerpt rte-width">
{%- if article.excerpt.size > 0 -%}
{{ article.excerpt | strip_html | truncatewords: 30 }}
{%- else -%}
{{ article.content | strip_html | truncatewords: 30 }}
{%- endif -%}
</p>
{%- endif -%}
<div class="article-card__footer">
{%- if article.comments_count > 0 and blog.comments_enabled? -%}
<span>{{ 'blogs.article.comments' | t: count: article.comments_count }}</span>
{%- endif -%}
</div>
{%- endif -%}
</div>
{%- if show_badge -%}
<div class="card__badge {{ settings.badge_position }}">
<span class="badge color-{{ settings.color_schemes | first }}">{{ 'blogs.article.blog' | t }}</span>
</div>
{%- endif -%}
</div>
</div>
</div>
{%- endif -%}
+151
View File
@@ -0,0 +1,151 @@
{% comment %}
Renders product buy-buttons.
Accepts:
- product: {Object} product object.
- block: {Object} passing the block information.
- product_form_id: {String} product form id.
- section_id: {String} id of section to which this snippet belongs.
- show_pickup_availability: {Boolean} for the pickup availability. If true the pickup availability is rendered, false - not rendered (optional).
Usage:
{% render 'buy-buttons', block: block, product: product, product_form_id: product_form_id, section_id: section.id, show_pickup_availability: true %}
{% endcomment %}
<div {{ block.shopify_attributes }}>
{%- if product != blank -%}
{%- liquid
assign gift_card_recipient_feature_active = false
if block.settings.show_gift_card_recipient and product.gift_card?
assign gift_card_recipient_feature_active = true
endif
assign show_dynamic_checkout = false
if block.settings.show_dynamic_checkout and gift_card_recipient_feature_active == false
assign show_dynamic_checkout = true
endif
-%}
<product-form
class="product-form"
data-hide-errors="{{ gift_card_recipient_feature_active }}"
data-section-id="{{ section.id }}"
>
<div class="product-form__error-message-wrapper" role="alert" hidden>
<span class="svg-wrapper">
{{- 'icon-error.svg' | inline_asset_content -}}
</span>
<span class="product-form__error-message"></span>
</div>
{%- form 'product',
product,
id: product_form_id,
class: 'form',
novalidate: 'novalidate',
data-type: 'add-to-cart-form'
-%}
<input
type="hidden"
name="id"
value="{{ product.selected_or_first_available_variant.id }}"
{% if product.selected_or_first_available_variant.available == false
or quantity_rule_soldout
or product.selected_or_first_available_variant == null
%}
disabled
{% endif %}
class="product-variant-id"
>
{%- if gift_card_recipient_feature_active -%}
{%- render 'gift-card-recipient-form', product: product, form: form, section: section -%}
{%- endif -%}
<div class="product-form__buttons">
{%- liquid
assign check_against_inventory = true
if product.selected_or_first_available_variant.inventory_management != 'shopify' or product.selected_or_first_available_variant.inventory_policy == 'continue'
assign check_against_inventory = false
endif
if product.selected_or_first_available_variant.quantity_rule.min > product.selected_or_first_available_variant.inventory_quantity and check_against_inventory
assign quantity_rule_soldout = true
endif
-%}
<button
id="ProductSubmitButton-{{ section_id }}"
type="submit"
name="add"
class="product-form__submit button button--full-width {% if show_dynamic_checkout %}button--secondary{% else %}button--primary{% endif %}"
{% if product.selected_or_first_available_variant.available == false
or quantity_rule_soldout
or product.selected_or_first_available_variant == null
%}
disabled
{% endif %}
>
<span>
{%- if product.selected_or_first_available_variant == null -%}
{{ 'products.product.unavailable' | t }}
{%- elsif product.selected_or_first_available_variant.available == false or quantity_rule_soldout -%}
{{ 'products.product.sold_out' | t }}
{%- else -%}
{{ 'products.product.add_to_cart' | t }}
{%- endif -%}
</span>
{%- render 'loading-spinner' -%}
</button>
{%- if show_dynamic_checkout -%}
{{ form | payment_button }}
{%- endif -%}
</div>
{%- endform -%}
</product-form>
{%- else -%}
<div class="product-form">
<div class="product-form__buttons form">
<button
type="submit"
name="add"
class="product-form__submit button button--full-width button--primary"
disabled
>
{{ 'products.product.sold_out' | t }}
</button>
</div>
</div>
{%- endif -%}
{%- if show_pickup_availability -%}
{{ 'component-pickup-availability.css' | asset_url | stylesheet_tag }}
{%- assign pick_up_availabilities = product.selected_or_first_available_variant.store_availabilities
| where: 'pick_up_enabled', true
-%}
<pickup-availability
class="product__pickup-availabilities quick-add-hidden"
{% if product.selected_or_first_available_variant.available and pick_up_availabilities.size > 0 %}
available
{% endif %}
data-root-url="{{ routes.root_url }}"
data-variant-id="{{ product.selected_or_first_available_variant.id }}"
data-has-only-default-variant="{{ product.has_only_default_variant }}"
data-product-page-color-scheme="gradient color-{{ section.settings.color_scheme }}"
>
<template>
<pickup-availability-preview class="pickup-availability-preview">
<span class="svg-wrapper">
{{- 'icon-unavailable.svg' | inline_asset_content -}}
</span>
<div class="pickup-availability-info">
<p class="caption-large">{{ 'products.product.pickup_availability.unavailable' | t }}</p>
<button class="pickup-availability-button link link--text underlined-link">
{{ 'products.product.pickup_availability.refresh' | t }}
</button>
</div>
</pickup-availability-preview>
</template>
</pickup-availability>
<script src="{{ 'pickup-availability.js' | asset_url }}" defer="defer"></script>
{%- endif -%}
</div>
+169
View File
@@ -0,0 +1,169 @@
{% comment %}
Renders a collection card
Accepts:
- card_collection: {Object} Collection Liquid object
- media_aspect_ratio: {String} Size of the product image card. Values are "square" and "portrait". Default is "square" (optional)
- columns: {Number}
- extend_height: {Boolean} Card height extends to available container space. Default: false (optional)
- wrapper_class: {String} Wrapper class for card (optional)
- placeholder_image: {String} Placeholder image when collection is empty (optional)
Usage:
{% render 'card-collection' %}
{% endcomment %}
{%- liquid
assign ratio = 1
if card_collection.featured_image and media_aspect_ratio == 'portrait'
assign ratio = 0.8
elsif card_collection.featured_image and media_aspect_ratio == 'adapt'
assign ratio = card_collection.featured_image.aspect_ratio
endif
if ratio == 0 or ratio == null
assign ratio = 1
endif
assign card_color_scheme = settings.card_color_scheme
assign card_style = settings.card_style
if wrapper_class == null or wrapper_class == 'none'
assign card_color_scheme = settings.collection_card_color_scheme
assign card_style = settings.collection_card_style
endif
-%}
<div class="card-wrapper animate-arrow {% if wrapper_class and wrapper_class != 'none' %}{{ wrapper_class }}{% else %}collection-card-wrapper{% endif %}">
<div
class="
card
card--{{ card_style }}
{% if card_collection.featured_image %} card--media{% else %} card--text{% endif %}
{% if card_style == 'card' %} color-{{ card_color_scheme }} gradient{% endif %}
{% if extend_height %} card--extend-height{% endif %}
{% if card_collection.featured_image == nil and card_style == 'card' %} ratio{% endif %}
"
style="--ratio-percent: {{ 1 | divided_by: ratio | times: 100 }}%;"
>
<div
class="card__inner {% if card_style == 'standard' %}color-{{ card_color_scheme }} gradient{% endif %}{% if card_collection.featured_image or card_style == 'standard' %} ratio{% endif %}"
style="--ratio-percent: {{ 1 | divided_by: ratio | times: 100 }}%;"
>
{%- if card_collection.featured_image -%}
<div class="card__media">
<div class="media media--transparent media--hover-effect">
<img
srcset="
{%- if card_collection.featured_image.width >= 165 -%}{{ card_collection.featured_image | image_url: width: 165 }} 165w,{%- endif -%}
{%- if card_collection.featured_image.width >= 330 -%}{{ card_collection.featured_image | image_url: width: 330 }} 330w,{%- endif -%}
{%- if card_collection.featured_image.width >= 535 -%}{{ card_collection.featured_image | image_url: width: 535 }} 535w,{%- endif -%}
{%- if card_collection.featured_image.width >= 750 -%}{{ card_collection.featured_image | image_url: width: 750 }} 750w,{%- endif -%}
{%- if card_collection.featured_image.width >= 1000 -%}{{ card_collection.featured_image | image_url: width: 1000 }} 1000w,{%- endif -%}
{%- if card_collection.featured_image.width >= 1500 -%}{{ card_collection.featured_image | image_url: width: 1500 }} 1500w,{%- endif -%}
{%- if card_collection.featured_image.width >= 3000 -%}{{ card_collection.featured_image | image_url: width: 3000 }} 3000w,{%- endif -%}
{{ card_collection.featured_image | image_url }} {{ card_collection.featured_image.width }}w
"
src="{{ card_collection.featured_image | image_url: width: 1500 }}"
sizes="
(min-width: {{ settings.page_width }}px) {{ settings.page_width | minus: 100 | divided_by: columns }}px,
(min-width: 750px) {% if columns > 1 %}calc((100vw - 10rem) / 2){% else %}calc(100vw - 10rem){% endif %},
calc(100vw - 3rem)
"
alt="{{ card_collection.featured_image.alt | escape }}"
height="{{ card_collection.featured_image.height }}"
width="{{ card_collection.featured_image.width }}"
loading="lazy"
class="motion-reduce"
>
</div>
</div>
{%- endif -%}
{%- if card_collection == blank -%}
<div class="card__media">
{{ placeholder_image | placeholder_svg_tag: 'placeholder-svg' }}
</div>
{%- else -%}
<div class="card__content">
<div class="card__information">
<h3 class="card__heading">
<a
{% if card_collection == blank %}
role="link" aria-disabled="true"
{% else %}
href="{{ card_collection.url }}"
{% endif %}
class="full-unstyled-link"
>
{%- if card_collection.title != blank -%}
{{- card_collection.title | escape -}}
{%- else -%}
{{ 'onboarding.collection_title' | t }}
{%- endif -%}
{%- if card_collection.description == blank -%}
<span class="icon-wrap">
{{- 'icon-arrow.svg' | inline_asset_content -}}
</span>
{%- endif %}
</a>
</h3>
{%- if card_collection.description != blank -%}
<p class="card__caption">
{{- card_collection.description | strip_html | truncatewords: 12 -}}
<span class="icon-wrap">
{{- 'icon-arrow.svg' | inline_asset_content -}}
</span>
</p>
{%- endif -%}
</div>
</div>
{%- endif -%}
</div>
{%- if card_collection != blank and card_style == 'card' or card_collection.featured_image -%}
<div class="card__content">
<div class="card__information">
<h3 class="card__heading">
<a
{% if card_collection == blank %}
role="link" aria-disabled="true"
{% else %}
href="{{ card_collection.url }}"
{% endif %}
class="full-unstyled-link"
>
{%- if card_collection.title != blank -%}
{{- card_collection.title | escape -}}
{%- else -%}
{{ 'onboarding.collection_title' | t }}
{%- endif -%}
{%- if card_collection.featured_image or card_collection.description == blank -%}
<span class="icon-wrap">
{{- 'icon-arrow.svg' | inline_asset_content -}}
</span>
{%- endif %}
</a>
</h3>
{%- if card_collection.featured_image == null and card_collection.description != blank -%}
<p class="card__caption">
{{- card_collection.description | strip_html | truncatewords: 12 -}}
<span class="icon-wrap">
{{- 'icon-arrow.svg' | inline_asset_content -}}
</span>
</p>
{%- endif -%}
</div>
</div>
{%- endif -%}
{%- if card_collection == blank -%}
<div class="card__content">
<div class="card__information">
<h3 class="card__heading card__heading--placeholder">
<a role="link" aria-disabled="true" class="full-unstyled-link">
{{ 'onboarding.collection_title' | t }}
<span class="icon-wrap">
{{- 'icon-arrow.svg' | inline_asset_content -}}
</span>
</a>
</h3>
</div>
</div>
{%- endif -%}
</div>
</div>
+627
View File
@@ -0,0 +1,627 @@
{% comment %}
Renders a product card
Accepts:
- card_product: {Object} Product Liquid object (optional)
- media_aspect_ratio: {String} Size of the product image card. Values are "square" and "portrait". Default is "square" (optional)
- image_shape: {String} Image mask to apply to the product image card. Values are "arch", "blob", "chevronleft", "chevronright", "diamond", "parallelogram", and "round". (optional)
- show_secondary_image: {Boolean} Show the secondary image on hover. Default: false (optional)
- show_vendor: {Boolean} Show the product vendor. Default: false
- show_rating: {Boolean} Show the product rating. Default: false
- extend_height: {Boolean} Card height extends to available container space. Default: true (optional)
- lazy_load: {Boolean} Image should be lazy loaded. Default: true (optional)
- skip_styles: {Boolean} Don't include component styles. Useful when rendering multiple product cards in a loop. Default: false (optional)
- quick_add: {Boolean} Show the quick add button.
- section_id: {String} The ID of the section that contains this card.
- horizontal_class: {Boolean} Add a card--horizontal class if set to true. Default: false (optional)
- horizontal_quick_add: {Boolean} Changes the quick add button styles when set to true. Default: false (optional)
- placeholder_image: {String} The placeholder image to use when no product exists. Default: 'product-apparel-2' (optional)
Usage:
{% render 'card-product', show_vendor: section.settings.show_vendor %}
{% endcomment %}
{%- unless skip_styles -%}
{{ 'component-rating.css' | asset_url | stylesheet_tag }}
{{ 'component-volume-pricing.css' | asset_url | stylesheet_tag }}
{{ 'component-price.css' | asset_url | stylesheet_tag }}
{{ 'quick-order-list.css' | asset_url | stylesheet_tag }}
{{ 'quantity-popover.css' | asset_url | stylesheet_tag }}
{%- endunless -%}
{%- if card_product and card_product != empty -%}
{%- liquid
assign ratio = 1
if card_product.featured_media and media_aspect_ratio == 'portrait'
assign ratio = 0.8
elsif card_product.featured_media and media_aspect_ratio == 'adapt'
assign ratio = card_product.featured_media.aspect_ratio
endif
if ratio == 0 or ratio == null
assign ratio = 1
endif
-%}
<product-component view-event-payload="{{ card_product | standard_event_data: 'view', context: product_view_context | escape }}">
<div class="card-wrapper product-card-wrapper underline-links-hover">
<div
class="
card card--{{ settings.card_style }}
{% if card_product.featured_media %} card--media{% else %} card--text{% endif %}
{% if settings.card_style == 'card' %} color-{{ settings.card_color_scheme }} gradient{% endif %}
{% if image_shape and image_shape != 'default' %} card--shape{% endif %}
{% if extend_height %} card--extend-height{% endif %}
{% if card_product.featured_media == nil and settings.card_style == 'card' %} ratio{% endif %}
{% if horizontal_class %} card--horizontal{% endif %}
"
style="--ratio-percent: {{ 1 | divided_by: ratio | times: 100 }}%;"
>
<div
class="card__inner {% if settings.card_style == 'standard' %}color-{{ settings.card_color_scheme }} gradient{% endif %}{% if card_product.featured_media or settings.card_style == 'standard' %} ratio{% endif %}"
style="--ratio-percent: {{ 1 | divided_by: ratio | times: 100 }}%;"
>
{%- if card_product.featured_media -%}
<div class="card__media{% if image_shape and image_shape != 'default' %} shape--{{ image_shape }} color-{{ settings.card_color_scheme }} gradient{% endif %}">
<div class="media media--transparent media--hover-effect">
{% comment %}theme-check-disable ImgLazyLoading{% endcomment %}
<img
srcset="
{%- if card_product.featured_media.width >= 165 -%}{{ card_product.featured_media | image_url: width: 165 }} 165w,{%- endif -%}
{%- if card_product.featured_media.width >= 360 -%}{{ card_product.featured_media | image_url: width: 360 }} 360w,{%- endif -%}
{%- if card_product.featured_media.width >= 533 -%}{{ card_product.featured_media | image_url: width: 533 }} 533w,{%- endif -%}
{%- if card_product.featured_media.width >= 720 -%}{{ card_product.featured_media | image_url: width: 720 }} 720w,{%- endif -%}
{%- if card_product.featured_media.width >= 940 -%}{{ card_product.featured_media | image_url: width: 940 }} 940w,{%- endif -%}
{%- if card_product.featured_media.width >= 1066 -%}{{ card_product.featured_media | image_url: width: 1066 }} 1066w,{%- endif -%}
{{ card_product.featured_media | image_url }} {{ card_product.featured_media.width }}w
"
src="{{ card_product.featured_media | image_url: width: 533 }}"
sizes="(min-width: {{ settings.page_width }}px) {{ settings.page_width | minus: 130 | divided_by: 4 }}px, (min-width: 990px) calc((100vw - 130px) / 4), (min-width: 750px) calc((100vw - 120px) / 3), calc((100vw - 35px) / 2)"
alt="{{ card_product.featured_media.alt | escape }}"
class="motion-reduce"
{% unless lazy_load == false %}
loading="lazy"
{% endunless %}
width="{{ card_product.featured_media.width }}"
height="{{ card_product.featured_media.height }}"
>
{% comment %}theme-check-enable ImgLazyLoading{% endcomment %}
{%- if card_product.media[1] != null and show_secondary_image -%}
<img
srcset="
{%- if card_product.media[1].width >= 165 -%}{{ card_product.media[1] | image_url: width: 165 }} 165w,{%- endif -%}
{%- if card_product.media[1].width >= 360 -%}{{ card_product.media[1] | image_url: width: 360 }} 360w,{%- endif -%}
{%- if card_product.media[1].width >= 533 -%}{{ card_product.media[1] | image_url: width: 533 }} 533w,{%- endif -%}
{%- if card_product.media[1].width >= 720 -%}{{ card_product.media[1] | image_url: width: 720 }} 720w,{%- endif -%}
{%- if card_product.media[1].width >= 940 -%}{{ card_product.media[1] | image_url: width: 940 }} 940w,{%- endif -%}
{%- if card_product.media[1].width >= 1066 -%}{{ card_product.media[1] | image_url: width: 1066 }} 1066w,{%- endif -%}
{{ card_product.media[1] | image_url }} {{ card_product.media[1].width }}w
"
src="{{ card_product.media[1] | image_url: width: 533 }}"
sizes="(min-width: {{ settings.page_width }}px) {{ settings.page_width | minus: 130 | divided_by: 4 }}px, (min-width: 990px) calc((100vw - 130px) / 4), (min-width: 750px) calc((100vw - 120px) / 3), calc((100vw - 35px) / 2)"
alt="{{ card_product.media[1].alt | escape }}"
class="motion-reduce"
loading="lazy"
width="{{ card_product.media[1].width }}"
height="{{ card_product.media[1].height }}"
>
{%- endif -%}
</div>
</div>
{%- endif -%}
<div class="card__content">
<div class="card__information">
<h3
class="card__heading"
{% if card_product.featured_media == null and settings.card_style == 'standard' %}
id="title-{{ section_id }}-{{ card_product.id }}"
{% endif %}
>
<a
href="{{ card_product.url }}"
id="StandardCardNoMediaLink-{{ section_id }}-{{ card_product.id }}"
class="full-unstyled-link"
aria-labelledby="StandardCardNoMediaLink-{{ section_id }}-{{ card_product.id }}{% if card_product.available == false or card_product.compare_at_price > card_product.price %} NoMediaStandardBadge-{{ section_id }}-{{ card_product.id }}{% endif %}"
>
{{ card_product.title | escape }}
</a>
</h3>
</div>
<div class="card__badge {{ settings.badge_position }}">
{%- if card_product.available == false -%}
<span
id="NoMediaStandardBadge-{{ section_id }}-{{ card_product.id }}"
class="badge badge--bottom-left color-{{ settings.sold_out_badge_color_scheme }}"
>
{{- 'products.product.sold_out' | t -}}
</span>
{%- elsif card_product.compare_at_price > card_product.price and card_product.available -%}
<span
id="NoMediaStandardBadge-{{ section_id }}-{{ card_product.id }}"
class="badge badge--bottom-left color-{{ settings.sale_badge_color_scheme }}"
>
{{- 'products.product.on_sale' | t -}}
</span>
{%- endif -%}
</div>
</div>
</div>
<div class="card__content">
<div class="card__information">
<h3
class="card__heading{% if card_product.featured_media or settings.card_style == 'standard' %} h5{% endif %}"
{% if card_product.featured_media or settings.card_style == 'card' %}
id="title-{{ section_id }}-{{ card_product.id }}"
{% endif %}
>
<a
href="{{ card_product.url }}"
id="CardLink-{{ section_id }}-{{ card_product.id }}"
class="full-unstyled-link"
aria-labelledby="CardLink-{{ section_id }}-{{ card_product.id }}{% if card_product.available == false or card_product.compare_at_price > card_product.price %} Badge-{{ section_id }}-{{ card_product.id }}{% endif %}"
>
{{ card_product.title | escape }}
</a>
</h3>
<div class="card-information">
{%- if show_vendor -%}
<span class="visually-hidden">{{ 'accessibility.vendor' | t }}</span>
<div class="caption-with-letter-spacing light">{{ card_product.vendor }}</div>
{%- endif -%}
<span class="caption-large light">{{ block.settings.description | escape }}</span>
{%- if show_rating and card_product.metafields.reviews.rating.value != blank -%}
{% liquid
assign rating_decimal = 0
assign decimal = card_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: card_product.metafields.reviews.rating.value, rating_max: card_product.metafields.reviews.rating.value.scale_max }}"
>
<span
aria-hidden="true"
class="rating-star"
style="--rating: {{ card_product.metafields.reviews.rating.value.rating | floor }}; --rating-max: {{ card_product.metafields.reviews.rating.value.scale_max }}; --rating-decimal: {{ rating_decimal }};"
></span>
</div>
<p class="rating-text caption">
<span aria-hidden="true">
{{- card_product.metafields.reviews.rating.value }} /
{{ card_product.metafields.reviews.rating.value.scale_max -}}
</span>
</p>
<p class="rating-count caption">
<span aria-hidden="true">({{ card_product.metafields.reviews.rating_count }})</span>
<span class="visually-hidden">
{{- card_product.metafields.reviews.rating_count }}
{{ 'accessibility.total_reviews' | t -}}
</span>
</p>
{%- endif -%}
{% render 'price', product: card_product, price_class: '', show_compare_at_price: true %}
{%- if card_product.quantity_price_breaks_configured? -%}
{% if card_product.variants_count == 1 and quick_add == 'bulk' %}
{% liquid
assign quantity_rule = card_product.selected_or_first_available_variant.quantity_rule
assign has_qty_rules = false
if quantity_rule.increment > 1 or quantity_rule.min > 1 or quantity_rule.max != null
assign has_qty_rules = true
endif
%}
<quantity-popover>
<button class="card__information-volume-pricing-note card__information-volume-pricing-note--button card__information-volume-pricing-note--button-{{ settings.card_text_alignment }} quantity-popover__info-button--icon-only button button button--tertiary medium-hide small-hide">
<span class="caption">{{ 'products.product.volume_pricing.note' | t }}</span>
</button>
<button class="card__information-volume-pricing-note card__information-volume-pricing-note--button card__information-volume-pricing-note--button-{{ settings.card_text_alignment }} quantity-popover__info-button--icon-with-label button button--tertiary large-up-hide">
<span class="caption">{{ 'products.product.volume_pricing.note' | t }}</span>
</button>
{% else %}
<div class="card__information-volume-pricing-note">
<span class="caption">{{ 'products.product.volume_pricing.note' | t }}</span>
</div>
{% endif %}
{% if card_product.variants_count == 1 and quick_add == 'bulk' %}
<div
class="global-settings-popup quantity-popover__info"
tabindex="-1"
hidden
id="quantity-popover-info-{{ card_product.selected_or_first_available_variant.id }}"
>
{%- if has_qty_rules -%}
<div class="quantity__rules caption no-js-hidden">
{%- if quantity_rule.increment > 1 -%}
<span class="divider">
{{- 'products.product.quantity.multiples_of' | t: quantity: quantity_rule.increment -}}
</span>
{%- endif -%}
{%- if quantity_rule.min > 1 -%}
<span class="divider">
{{- 'products.product.quantity.min_of' | t: quantity: quantity_rule.min -}}
</span>
{%- endif -%}
{%- if quantity_rule.max != null -%}
<span class="divider">
{{- 'products.product.quantity.max_of' | t: quantity: quantity_rule.max -}}
</span>
{%- endif -%}
</div>
{%- endif -%}
<button
class="button-close button button--tertiary large-up-hide"
type="button"
aria-label="{{ 'accessibility.close' | t }}"
>
{{- 'icon-close.svg' | inline_asset_content -}}
</button>
{%- if card_product.selected_or_first_available_variant.quantity_price_breaks.size > 0 -%}
<volume-pricing class="parent-display">
<ul class="list-unstyled">
<li>
<span>{{ card_product.selected_or_first_available_variant.quantity_rule.min }}+</span>
{%- assign price = card_product.selected_or_first_available_variant.price
| money_with_currency
-%}
<span>{{ 'sections.quick_order_list.each' | t: money: price }}</span>
</li>
{%- for price_break in card_product.selected_or_first_available_variant.quantity_price_breaks -%}
<li>
<span>
{{- price_break.minimum_quantity -}}
<span aria-hidden="true">+</span></span
>
{%- assign price = price_break.price | money_with_currency -%}
<span> {{ 'sections.quick_order_list.each' | t: money: price }}</span>
</li>
{%- endfor -%}
</ul>
</volume-pricing>
{%- endif -%}
</div>
</quantity-popover>
{% endif %}
{%- endif -%}
</div>
</div>
{% assign product_form_id = 'quick-add-' | append: section_id | append: card_product.id %}
{% if quick_add == 'standard' %}
<div class="quick-add no-js-hidden">
{%- liquid
assign qty_rules = false
if card_product.selected_or_first_available_variant.quantity_rule.min > 1 or card_product.selected_or_first_available_variant.quantity_rule.max != null or card_product.selected_or_first_available_variant.quantity_rule.increment > 1
assign qty_rules = true
endif
-%}
{%- if card_product.variants_count > 1 or qty_rules -%}
<modal-opener data-modal="#QuickAdd-{{ card_product.id }}">
<button
id="{{ product_form_id }}-submit"
type="submit"
name="add"
class="quick-add__submit button button--full-width button--secondary{% if horizontal_quick_add %} card--horizontal__quick-add animate-arrow{% endif %}"
aria-haspopup="dialog"
aria-labelledby="{{ product_form_id }}-submit title-{{ section_id }}-{{ card_product.id }}"
data-product-url="{{ card_product.url }}"
>
{{ 'products.product.choose_options' | t }}
{%- if horizontal_quick_add -%}
<span class="icon-wrap">
{{- 'icon-arrow.svg' | inline_asset_content -}}
</span>
{%- endif -%}
{%- render 'loading-spinner' -%}
</button>
</modal-opener>
<quick-add-modal id="QuickAdd-{{ card_product.id }}" class="quick-add-modal">
<div
role="dialog"
aria-label="{{ 'products.product.choose_product_options' | t: product_name: card_product.title | escape }}"
aria-modal="true"
class="quick-add-modal__content global-settings-popup"
tabindex="-1"
>
<button
id="ModalClose-{{ card_product.id }}"
type="button"
class="quick-add-modal__toggle"
aria-label="{{ 'accessibility.close' | t }}"
>
{{- 'icon-close.svg' | inline_asset_content -}}
</button>
<div id="QuickAddInfo-{{ card_product.id }}" class="quick-add-modal__content-info"></div>
</div>
</quick-add-modal>
{%- else -%}
<product-form data-section-id="{{ section.id }}">
{%- form 'product',
card_product,
id: product_form_id,
class: 'form',
novalidate: 'novalidate',
data-type: 'add-to-cart-form'
-%}
<input
type="hidden"
name="id"
value="{{ card_product.selected_or_first_available_variant.id }}"
class="product-variant-id"
{% if card_product.selected_or_first_available_variant.available == false %}
disabled
{% endif %}
>
<button
id="{{ product_form_id }}-submit"
type="submit"
name="add"
class="quick-add__submit button button--full-width button--secondary{% if horizontal_quick_add %} card--horizontal__quick-add{% endif %}"
aria-haspopup="dialog"
aria-labelledby="{{ product_form_id }}-submit title-{{ section_id }}-{{ card_product.id }}"
aria-live="polite"
data-sold-out-message="true"
{% if card_product.selected_or_first_available_variant.available == false %}
disabled
{% endif %}
>
<span>
{%- if card_product.selected_or_first_available_variant.available -%}
{{ 'products.product.add_to_cart' | t }}
{%- else -%}
{{ 'products.product.sold_out' | t }}
{%- endif -%}
</span>
<span class="sold-out-message hidden">
{{ 'products.product.sold_out' | t }}
</span>
{%- if horizontal_quick_add -%}
<span class="icon-wrap">
{{- 'icon-plus.svg' | inline_asset_content -}}
</span>
{%- endif -%}
{%- render 'loading-spinner' -%}
</button>
{%- endform -%}
</product-form>
{%- endif -%}
</div>
{% elsif quick_add == 'bulk' %}
{% if card_product.variants_count == 1 %}
<quick-add-bulk
data-min="{{ card_product.selected_or_first_available_variant.quantity_rule.min }}"
id="quick-add-bulk-{{ card_product.selected_or_first_available_variant.id }}-{{ section.id }}"
class="quick-add-bulk"
data-index="{{ card_product.selected_or_first_available_variant.id }}"
>
{% if card_product.selected_or_first_available_variant.available == false %}
<button
id="{{ product_form_id }}-submit"
type="submit"
name="add"
class="quick-add__submit button button--full-width button--secondary"
aria-labelledby="{{ product_form_id }}-submit title-{{ section_id }}-{{ card_product.id }}"
data-sold-out-message="true"
disabled
>
<span>{{ 'products.product.sold_out' | t }}</span>
<span class="sold-out-message hidden">
{{ 'products.product.sold_out' | t }}
</span>
</button>
{% else %}
{% render 'quantity-input', variant: card_product.selected_or_first_available_variant, min: 0 %}
{% endif %}
</quick-add-bulk>
{% else %}
<div class="quick-add no-js-hidden">
{%- liquid
assign product_form_id = 'quick-add-' | append: section_id | append: card_product.id
assign qty_rules = false
if card_product.selected_or_first_available_variant.quantity_rule.min > 1 or card_product.selected_or_first_available_variant.quantity_rule.max != null or card_product.selected_or_first_available_variant.quantity_rule.increment > 1
assign qty_rules = true
endif
-%}
<modal-opener
id="QuickBulk-{{ card_product.id }}-{{ section_id }}"
data-modal="#QuickAddBulk-{{ card_product.id }}-{{ section.id }}"
>
<button
id="{{ product_form_id }}-submit"
type="submit"
name="add"
class="quick-add__submit button button--full-width button--secondary"
aria-haspopup="dialog"
aria-labelledby="{{ product_form_id }}-submit title-{{ section_id }}-{{ card_product.id }}"
data-product-url="{{ card_product.url }}"
>
{{ 'products.product.choose_options' | t }}
{%- render 'loading-spinner' -%}
</button>
</modal-opener>
<modal-dialog
id="QuickAddBulk-{{ card_product.id }}-{{ section_id }}"
class="quick-add-modal color-{{ section.settings.color_scheme }}"
>
<div
role="dialog"
aria-label="{{ 'products.product.choose_product_options' | t: product_name: card_product.title | escape }}"
aria-modal="true"
class="quick-add-modal__content quick-add-modal__content--bulk global-settings-popup"
tabindex="-1"
>
<button
id="ModalClose-{{ card_product.id }}"
type="button"
class="quick-add-modal__toggle"
aria-label="{{ 'accessibility.close' | t }}"
>
{{- 'icon-close.svg' | inline_asset_content -}}
</button>
<div
id="QuickAddInfo-{{ card_product.id }}"
class="quick-add-modal__content-info quick-add-modal__content-info--bulk"
>
<div class="quick-add__content-info__media">
<div class="quick-add__info">
{%- if card_product.featured_media -%}
<div
class="quick-add__product-media"
>
<div class="quick-add__product-container global-media-settings">
{% comment %}theme-check-disable ImgLazyLoading{% endcomment %}
<img
srcset="
{%- if card_product.featured_media.width >= 165 -%}{{ card_product.featured_media | image_url: width: 165 }} 165w,{%- endif -%}
{%- if card_product.featured_media.width >= 360 -%}{{ card_product.featured_media | image_url: width: 360 }} 360w,{%- endif -%}
{%- if card_product.featured_media.width >= 533 -%}{{ card_product.featured_media | image_url: width: 533 }} 533w,{%- endif -%}
{%- if card_product.featured_media.width >= 720 -%}{{ card_product.featured_media | image_url: width: 720 }} 720w,{%- endif -%}
{%- if card_product.featured_media.width >= 940 -%}{{ card_product.featured_media | image_url: width: 940 }} 940w,{%- endif -%}
{%- if card_product.featured_media.width >= 1066 -%}{{ card_product.featured_media | image_url: width: 1066 }} 1066w,{%- endif -%}
{{ card_product.featured_media | image_url }} {{ card_product.featured_media.width }}w
"
src="{{ card_product.featured_media | image_url: width: 533 }}"
sizes="(min-width: {{ settings.page_width }}px) {{ settings.page_width | minus: 130 | divided_by: 4 }}px, (min-width: 990px) calc((100vw - 130px) / 4), (min-width: 750px) calc((100vw - 120px) / 3), calc((100vw - 35px) / 2)"
alt="{{ card_product.featured_media.alt | escape }}"
class="motion-reduce"
{% unless lazy_load == false %}
loading="lazy"
{% endunless %}
width="{{ card_product.featured_media.width }}"
height="{{ card_product.featured_media.height }}"
>
{% comment %}theme-check-enable ImgLazyLoading{% endcomment %}
</div>
</div>
{%- endif -%}
<a
{% if card_product == blank %}
role="link" aria-disabled="true"
{% else %}
href="{{ card_product.url }}"
{% endif %}
class="link product__view-details animate-arrow small-hide medium-hide"
>
{{ 'products.product.view_full_details' | t -}}
{{- 'icon-arrow.svg' | inline_asset_content -}}
</a>
</div>
<div class="quick-add-modal__content-info--bulk-details large-up-hide">
<a href="{{ card_product.url }}" class="full-unstyled-link">
<h3>{{ card_product.title | escape }}</h3>
</a>
{% render 'price', product: card_product, price_class: '', show_compare_at_price: true %}
{%- if card_product.quantity_price_breaks_configured? -%}
<div class="card__information-volume-pricing-note">
<span class="caption">{{ 'products.product.volume_pricing.note' | t }}</span>
</div>
{%- endif -%}
</div>
</div>
<div>
<div class="quick-add-modal__content-info--bulk-details small-hide medium-hide">
<a href="{{ card_product.url }}" class="full-unstyled-link">
<h3 class="h2">
{{ card_product.title | escape }}
</h3>
</a>
{% render 'price', product: card_product, price_class: '', show_compare_at_price: true %}
{%- if card_product.quantity_price_breaks_configured? -%}
<div class="card__information-volume-pricing-note">
<span class="caption">{{ 'products.product.volume_pricing.note' | t }}</span>
</div>
{%- endif -%}
</div>
<bulk-modal
id="QuickBulkModal-{{ card_product.id }}-{{ section_id }}"
data-url="{{ card_product.url }}"
data-section-id="{{ section_id }}"
data-product-id="{{ card_product.id }}"
>
</bulk-modal>
</div>
</div>
</div>
</modal-dialog>
</div>
{% endif %}
{% endif %}
<div class="card__badge {{ settings.badge_position }}">
{%- if card_product.available == false -%}
<span
id="Badge-{{ section_id }}-{{ card_product.id }}"
class="badge badge--bottom-left color-{{ settings.sold_out_badge_color_scheme }}"
>
{{- 'products.product.sold_out' | t -}}
</span>
{%- elsif card_product.compare_at_price > card_product.price and card_product.available -%}
<span
id="Badge-{{ section_id }}-{{ card_product.id }}"
class="badge badge--bottom-left color-{{ settings.sale_badge_color_scheme }}"
>
{{- 'products.product.on_sale' | t -}}
</span>
{%- endif -%}
</div>
</div>
</div>
</div>
</product-component>
{%- else -%}
{%- liquid
assign ratio = 1
assign placeholder = true
if media_aspect_ratio == 'portrait'
assign ratio = 0.8
endif
-%}
<div class="card-wrapper product-card-wrapper underline-links-hover">
<div
class="
card card--{{ settings.card_style }}
{% if extend_height %} card--extend-height{% endif %}
{% if image_shape and image_shape != 'default' %} card--shape{% endif %}
{% if settings.card_style == 'card' %} color-{{ settings.card_color_scheme }} gradient{% endif %}
"
style="--ratio-percent: {{ 1 | divided_by: ratio | times: 100 }}%;"
>
<div
class="card__inner{% if settings.card_style == 'standard' %} color-{{ settings.card_color_scheme }} gradient{% endif %} ratio"
>
<div
class="card__media {% if image_shape and image_shape != 'default' %} shape--{{ image_shape }} color-{{ settings.card_color_scheme }} gradient{% endif %}"
>
<div
class="media media--transparent"
>
{%- if placeholder_image -%}
{{ placeholder_image | placeholder_svg_tag: 'placeholder-svg' }}
{%- else -%}
{{ 'product-apparel-2' | placeholder_svg_tag: 'placeholder-svg' }}
{% endif %}
</div>
</div>
</div>
<div class="card__content">
<div class="card__information">
<h3 class="card__heading card__heading--placeholder{% if settings.card_style == 'standard' %} h5{% endif %}">
<a role="link" aria-disabled="true" class="full-unstyled-link">
{{ 'onboarding.product_title' | t }}
</a>
</h3>
<div class="card-information">
{%- if show_vendor -%}
<span class="visually-hidden">{{ 'accessibility.vendor' | t }}</span>
<div class="caption-with-letter-spacing light">{{ 'products.product.vendor' | t }}</div>
{%- endif -%}
{% render 'price', placeholder: placeholder, show_compare_at_price: true %}
</div>
</div>
</div>
</div>
</div>
{%- endif -%}
+128
View File
@@ -0,0 +1,128 @@
{% comment %}
Renders a cart disclosure indicator when the product has a disclosure configured for the cart surface.
Accepts:
- product: {Object} Product object
- modal_id: {String} Unique modal id for this cart line
{% endcomment %}
{%- liquid
assign disclosures = product.metafields.shopify.disclosure.value
assign cart_disclosures_count = 0
if disclosures != blank
for disclosure in disclosures
assign surfaces = disclosure.display_preferences.value.surfaces
if surfaces contains 'cart'
assign cart_disclosures_count = cart_disclosures_count | plus: 1
endif
endfor
endif
-%}
{%- if cart_disclosures_count > 0 and modal_id != blank -%}
{%- capture cart_disclosure_rows -%}
{%- for disclosure in disclosures -%}
{%- assign surfaces = disclosure.display_preferences.value.surfaces -%}
{%- if surfaces contains 'cart' -%}
{%- assign title = disclosure.title.value -%}
{%- assign symbol = disclosure.symbol.value -%}
<span class="cart-item__disclosure-tooltip-row">
<span class="cart-item__disclosure-tooltip-symbol-slot">
{%- if symbol != blank -%}
<img
src="{{ symbol | image_url: width: 32 }}"
alt=""
class="cart-item__disclosure-tooltip-symbol"
width="40"
height="31"
loading="lazy"
>
{%- endif -%}
</span>
<span class="cart-item__disclosure-tooltip-title">
{{- title | escape -}}
</span>
</span>
{%- endif -%}
{%- endfor -%}
{%- endcapture -%}
<button
type="button"
class="cart-item__disclosure"
aria-controls="{{ modal_id }}-dialog"
aria-expanded="false"
aria-haspopup="dialog"
aria-label="{{ 'sections.cart.product_disclosure' | t }}"
>
<span class="cart-item__disclosure-indicator svg-wrapper" aria-hidden="true">
{{- 'icon-warning.svg' | inline_asset_content -}}
</span>
<span class="cart-item__disclosure-tooltip" aria-hidden="true">
{{- cart_disclosure_rows -}}
</span>
</button>
<cart-disclosure-modal id="{{ modal_id }}" class="cart-disclosure-modal">
<div
id="{{ modal_id }}-dialog"
role="dialog"
aria-modal="true"
aria-labelledby="{{ modal_id }}-title"
class="cart-disclosure-modal__content"
tabindex="-1"
>
<button
type="button"
class="cart-disclosure-modal__close"
data-cart-disclosure-close
aria-label="{{ 'accessibility.close' | t }}"
>
{{- 'icon-close.svg' | inline_asset_content -}}
</button>
<h2 id="{{ modal_id }}-title" class="cart-disclosure-modal__title">
{{- 'sections.cart.product_disclosures' | t -}}
</h2>
<div class="cart-disclosure-modal__items">
{%- for disclosure in disclosures -%}
{%- assign surfaces = disclosure.display_preferences.value.surfaces -%}
{%- if surfaces contains 'cart' -%}
{%- assign title = disclosure.title.value -%}
{%- assign symbol = disclosure.symbol.value -%}
{%- assign content = disclosure.content -%}
<div class="cart-disclosure-modal__item">
{%- if title != blank or symbol != blank -%}
<div class="cart-disclosure-modal__item-header">
<span class="cart-disclosure-modal__symbol-slot">
{%- if symbol != blank -%}
<img
src="{{ symbol | image_url: width: 40 }}"
alt=""
class="cart-disclosure-modal__symbol"
width="40"
height="31"
loading="lazy"
>
{%- endif -%}
</span>
{%- if title != blank -%}
<h3 class="cart-disclosure-modal__item-title">{{ title | escape }}</h3>
{%- endif -%}
</div>
{%- endif -%}
<div class="cart-disclosure-modal__item-content">
{{ content | metafield_tag }}
</div>
</div>
{%- endif -%}
{%- endfor -%}
</div>
</div>
</cart-disclosure-modal>
{%- endif -%}
+594
View File
@@ -0,0 +1,594 @@
{% comment %}
Renders cart drawer
Usage:
{% render 'cart-drawer' %}
{% endcomment %}
{{ 'quantity-popover.css' | asset_url | stylesheet_tag }}
{{ 'component-card.css' | asset_url | stylesheet_tag }}
<script src="{{ 'cart.js' | asset_url }}" defer="defer"></script>
<script src="{{ 'quantity-popover.js' | asset_url }}" defer="defer"></script>
<style>
.drawer {
visibility: hidden;
}
</style>
<cart-drawer class="drawer{% if cart == empty %} is-empty{% endif %}">
<div id="CartDrawer" class="cart-drawer">
<div id="CartDrawer-Overlay" class="cart-drawer__overlay"></div>
<div
class="drawer__inner gradient color-{{ settings.cart_color_scheme }}"
role="dialog"
aria-modal="true"
aria-label="{{ 'sections.cart.title' | t }}"
tabindex="-1"
>
{%- if cart == empty -%}
<div class="drawer__inner-empty">
<div class="cart-drawer__warnings center{% if settings.cart_drawer_collection != blank %} cart-drawer__warnings--has-collection{% endif %}">
<div class="cart-drawer__empty-content">
<h2 class="cart__empty-text">{{ 'sections.cart.empty' | t }}</h2>
<button
class="drawer__close"
type="button"
onclick="this.closest('cart-drawer').close()"
aria-label="{{ 'accessibility.close' | t }}"
>
<span class="svg-wrapper">
{{- 'icon-close.svg' | inline_asset_content -}}
</span>
</button>
<a href="{{ routes.all_products_collection_url }}" class="button">
{{ 'general.continue_shopping' | t }}
</a>
{%- if shop.customer_accounts_enabled and customer == null -%}
<p class="cart__login-title h3">{{ 'sections.cart.login.title' | t }}</p>
<p class="cart__login-paragraph">
{{ 'sections.cart.login.paragraph_html' | t: link: routes.account_login_url }}
</p>
{%- endif -%}
</div>
</div>
{%- if settings.cart_drawer_collection != blank -%}
<div class="cart-drawer__collection">
{% render 'card-collection', card_collection: settings.cart_drawer_collection, columns: 1 %}
</div>
{%- endif -%}
</div>
{%- endif -%}
<div class="drawer__header">
<h2 class="drawer__heading">{{ 'sections.cart.title' | t }}</h2>
<button
class="drawer__close"
type="button"
onclick="this.closest('cart-drawer').close()"
aria-label="{{ 'accessibility.close' | t }}"
>
<span class="svg-wrapper">
{{- 'icon-close.svg' | inline_asset_content -}}
</span>
</button>
</div>
<cart-drawer-items
view-event-payload="{{ cart | standard_event_data: 'view', context: 'dialog' | escape }}"
view-event-trigger="manual"
{% if cart == empty %}
class=" is-empty"
{% endif %}
>
<form
action="{{ routes.cart_url }}"
id="CartDrawer-Form"
class="cart__contents cart-drawer__form"
method="post"
>
<div id="CartDrawer-CartItems" class="drawer__contents js-contents">
{%- if cart != empty -%}
<div class="drawer__cart-items-wrapper">
<table class="cart-items" role="table">
<thead role="rowgroup">
<tr role="row">
<th id="CartDrawer-ColumnProductImage" role="columnheader">
<span class="visually-hidden">{{ 'sections.cart.headings.image' | t }}</span>
</th>
<th
id="CartDrawer-ColumnProduct"
class="caption-with-letter-spacing"
scope="col"
role="columnheader"
>
{{ 'sections.cart.headings.product' | t }}
</th>
<th
id="CartDrawer-ColumnTotal"
class="right caption-with-letter-spacing"
scope="col"
role="columnheader"
>
{{ 'sections.cart.headings.total' | t }}
</th>
<th id="CartDrawer-ColumnQuantity" role="columnheader">
<span class="visually-hidden">{{ 'sections.cart.headings.quantity' | t }}</span>
</th>
</tr>
</thead>
<tbody role="rowgroup">
{%- for item in cart.items -%}
<tr
id="CartDrawer-Item-{{ item.index | plus: 1 }}"
class="cart-item{% if item.parent_relationship.parent != null %} cart-item__nested-line{% endif %}"
role="row"
{% if item.parent_relationship.parent != null %}
aria-label="{{- 'products.product.nested_label' | t: title: item.product.title, parent_title: item.parent_relationship.parent.title | escape -}}"
{% endif %}
>
<td
class="cart-item__media"
role="cell"
headers="CartDrawer-ColumnProductImage"
>
{% if item.image %}
{% comment %} Leave empty space due to a:empty CSS display: none rule {% endcomment %}
<a href="{{ item.url }}" class="cart-item__link" tabindex="-1" aria-hidden="true"> </a>
<img
class="cart-item__image"
src="{{ item.image | image_url: width: 300 }}"
alt="{{ item.image.alt | escape }}"
loading="lazy"
width="150"
height="{{ 150 | divided_by: item.image.aspect_ratio | ceil }}"
>
{% endif %}
</td>
<td class="cart-item__details" role="cell" headers="CartDrawer-ColumnProduct">
{%- if settings.show_vendor -%}
<p class="caption-with-letter-spacing light">{{ item.product.vendor }}</p>
{%- endif -%}
<div class="cart-item__title">
<a href="{{ item.url }}" class="cart-item__name h4 break">
{{- item.product.title | escape -}}
</a>
{%- assign cart_disclosure_modal_id = 'CartDisclosureModal-drawer-' | append: item.key | replace: ':', '-' -%}
{%- render 'cart-disclosure-indicator',
product: item.product,
modal_id: cart_disclosure_modal_id
-%}
</div>
{%- if item.original_price != item.final_price -%}
<div class="cart-item__discounted-prices">
<span class="visually-hidden">
{{ 'products.product.price.regular_price' | t }}
</span>
<s class="cart-item__old-price product-option">
{{- item.original_price | money -}}
</s>
<span class="visually-hidden">
{{ 'products.product.price.sale_price' | t }}
</span>
<strong class="cart-item__final-price product-option">
{{ item.final_price | money }}
</strong>
</div>
{%- else -%}
<div class="product-option">
{{ item.original_price | money }}
</div>
{%- endif -%}
{%- if item.product.has_only_default_variant == false
or item.properties.size != 0
or item.selling_plan_allocation != null
-%}
<dl>
{%- if item.product.has_only_default_variant == false -%}
{%- for option in item.options_with_values -%}
<div class="product-option">
<dt>{{ option.name }}:</dt>
<dd>
{{ option.value -}}
{%- unless forloop.last %}, {% endunless %}
</dd>
</div>
{%- endfor -%}
{%- endif -%}
{%- for property in item.properties -%}
{%- assign property_first_char = property.first | slice: 0 -%}
{%- if property.last != blank and property_first_char != '_' -%}
<div class="product-option">
<dt>{{ property.first }}:</dt>
<dd>
{%- if property.last contains '/uploads/' -%}
<a
href="{{ property.last }}"
class="link"
target="_blank"
aria-describedby="a11y-new-window-message"
>
{{ property.last | split: '/' | last }}
</a>
{%- else -%}
{{ property.last }}
{%- endif -%}
</dd>
</div>
{%- endif -%}
{%- endfor -%}
</dl>
<p class="product-option">{{ item.selling_plan_allocation.selling_plan.name }}</p>
{%- endif -%}
<ul
class="discounts list-unstyled"
role="list"
aria-label="{{ 'customer.order.discount' | t }}"
>
{%- for discount in item.line_level_discount_allocations -%}
<li class="discounts__discount">
{{- 'icon-discount.svg' | inline_asset_content -}}
{{ discount.discount_application.title }}
</li>
{%- endfor -%}
</ul>
</td>
<td class="cart-item__totals right" role="cell" headers="CartDrawer-ColumnTotal">
{%- render 'loading-spinner' -%}
<div class="cart-item__price-wrapper">
{%- if item.original_line_price != item.final_line_price -%}
<div class="cart-item__discounted-prices">
<span class="visually-hidden">
{{ 'products.product.price.regular_price' | t }}
</span>
<s class="cart-item__old-price price price--end">
{{ item.original_line_price | money }}
</s>
<span class="visually-hidden">
{{ 'products.product.price.sale_price' | t }}
</span>
<span class="price price--end">
{{ item.final_line_price | money }}
</span>
</div>
{%- else -%}
<span class="price price--end">
{{ item.original_line_price | money }}
</span>
{%- endif -%}
{%- if item.variant.available and item.unit_price_measurement -%}
{% render 'unit-price',
price: item.unit_price,
measurement: item.unit_price_measurement
%}
{%- endif -%}
</div>
</td>
{%- liquid
assign has_qty_rules = false
if item.variant.quantity_rule.increment > 1 or item.variant.quantity_rule.min > 1 or item.variant.quantity_rule.max != null
assign has_qty_rules = true
endif
assign has_vol_pricing = false
if item.variant.quantity_price_breaks.size > 0
assign has_vol_pricing = true
endif
-%}
<td
class="cart-item__quantity {% if has_qty_rules or has_vol_pricing %} cart-item__quantity--info{% endif %}"
role="cell"
headers="CartDrawer-ColumnQuantity"
>
<quantity-popover>
<div class="cart-item__quantity-wrapper quantity-popover-wrapper">
<div class="quantity-popover-container{% if has_qty_rules or has_vol_pricing %} quantity-popover-container--hover{% endif %}">
<quantity-input class="quantity cart-quantity">
<button
class="quantity__button"
name="minus"
type="button"
{% if item.instructions and item.instructions.can_update_quantity == false %}
disabled
{% endif %}
>
<span class="visually-hidden">
{{-
'products.product.quantity.decrease'
| t: product: item.product.title
| escape
-}}
</span>
<span class="svg-wrapper">
{{- 'icon-minus.svg' | inline_asset_content -}}
</span>
</button>
<input
class="quantity__input"
type="number"
data-quantity-variant-id="{{ item.variant.id }}"
data-quantity-line-key="{{ item.key }}"
name="updates[]"
value="{{ item.quantity }}"
{% # theme-check-disable %}
data-cart-quantity="{{ cart | item_count_for_variant: item.variant.id }}"
min="0"
data-min="{{ item.variant.quantity_rule.min }}"
{% if item.variant.quantity_rule.max != null %}
max="{{ item.variant.quantity_rule.max }}"
{% endif %}
step="{{ item.variant.quantity_rule.increment }}"
{% # theme-check-enable %}
aria-label="{{ 'products.product.quantity.input_label' | t: product: item.product.title | escape }}"
id="Drawer-quantity-{{ item.index | plus: 1 }}"
data-index="{{ item.index | plus: 1 }}"
{% if item.instructions and item.instructions.can_update_quantity == false %}
disabled
{% endif %}
>
<button
class="quantity__button"
name="plus"
type="button"
{% if item.instructions and item.instructions.can_update_quantity == false %}
disabled
{% endif %}
>
<span class="visually-hidden">
{{-
'products.product.quantity.increase'
| t: product: item.product.title
| escape
-}}
</span>
<span class="svg-wrapper">
{{- 'icon-plus.svg' | inline_asset_content -}}
</span>
</button>
</quantity-input>
</div>
<cart-remove-button
id="CartDrawer-Remove-{{ item.index | plus: 1 }}"
data-index="{{ item.index | plus: 1 }}"
>
<button
type="button"
class="button button--tertiary cart-remove-button"
aria-label="{{ 'sections.cart.remove_title' | t: title: item.title | escape }}"
data-variant-id="{{ item.variant.id }}"
{% if item.instructions and item.instructions.can_remove == false %}
class="hidden"
{% endif %}
>
<span class="svg-wrapper">
{{- 'icon-remove.svg' | inline_asset_content -}}
</span>
</button>
</cart-remove-button>
</div>
{%- if has_qty_rules or has_vol_pricing -%}
<button
type="button"
class="quantity-popover__info-button quantity-popover__info-button--icon-with-label button button--tertiary"
aria-expanded="false"
>
<span class="svg-wrapper">
{{- 'icon-info.svg' | inline_asset_content -}}
</span>
<span>
{%- if has_vol_pricing -%}
{{ 'products.product.volume_pricing.note' | t }}
{%- elsif has_qty_rules -%}
{{ 'products.product.quantity.note' | t }}
{%- endif -%}
</span>
</button>
{%- endif -%}
{%- if has_vol_pricing or has_qty_rules -%}
<div
class="cart-items__info global-settings-popup quantity-popover__info"
tabindex="-1"
hidden
>
{%- if has_qty_rules == false -%}
<span class="volume-pricing-label caption">
{{- 'products.product.volume_pricing.title' | t -}}
</span>
{%- endif -%}
<div class="quantity__rules caption">
{%- if item.variant.quantity_rule.increment > 1 -%}
<span class="divider">
{{-
'products.product.quantity.multiples_of'
| t: quantity: item.variant.quantity_rule.increment
-}}
</span>
{%- endif -%}
{%- if item.variant.quantity_rule.min > 1 -%}
<span class="divider">
{{-
'products.product.quantity.min_of'
| t: quantity: item.variant.quantity_rule.min
-}}
</span>
{%- endif -%}
{%- if item.variant.quantity_rule.max != null -%}
<span class="divider">
{{-
'products.product.quantity.max_of'
| t: quantity: item.variant.quantity_rule.max
-}}
</span>
{%- endif -%}
</div>
<button
class="button-close button button--tertiary"
type="button"
aria-label="{{ 'accessibility.close' | t }}"
>
<span class="svg-wrapper">
{{- 'icon-close.svg' | inline_asset_content -}}
</span>
</button>
{%- if item.variant.quantity_price_breaks.size > 0 -%}
<volume-pricing class="parent-display">
<ul class="list-unstyled">
<li>
<span>{{ item.variant.quantity_rule.min }}+</span>
<span>{{ item.variant.price | money_with_currency }}/ea</span>
</li>
{%- for price_break in item.variant.quantity_price_breaks -%}
<li>
<span>
{{- price_break.minimum_quantity -}}
<span aria-hidden="true">+</span></span
>
<span>{{ price_break.price | money_with_currency }}/ea</span>
</li>
{%- endfor -%}
</ul>
</volume-pricing>
{%- endif -%}
</div>
{%- endif -%}
<div
id="CartDrawer-LineItemError-{{ item.index | plus: 1 }}"
class="cart-item__error"
role="alert"
>
<small class="cart-item__error-text"></small>
<span class="svg-wrapper">
{{- 'icon-error.svg' | inline_asset_content -}}
</span>
</div>
</quantity-popover>
</td>
</tr>
{%- endfor -%}
</tbody>
</table>
</div>
{%- endif -%}
<p id="CartDrawer-LiveRegionText" class="visually-hidden" role="status"></p>
<p id="CartDrawer-LineItemStatus" class="visually-hidden" aria-hidden="true" role="status">
{{ 'accessibility.loading' | t }}
</p>
</div>
<div id="CartDrawer-CartErrors" role="alert"></div>
</form>
</cart-drawer-items>
<div class="drawer__footer">
{%- if settings.show_cart_note -%}
<details id="Details-CartDrawer">
<summary>
<span class="summary__title">
{{ 'sections.cart.note' | t }}
{{- 'icon-caret.svg' | inline_asset_content -}}
</span>
</summary>
<cart-note class="cart__note field">
<label class="visually-hidden" for="CartDrawer-Note">{{ 'sections.cart.note' | t }}</label>
<textarea
id="CartDrawer-Note"
class="text-area text-area--resize-vertical field__input"
name="note"
placeholder="{{ 'sections.cart.note' | t }}"
>{{ cart.note }}</textarea>
</cart-note>
</details>
{%- endif -%}
<!-- Start blocks -->
<!-- Subtotals -->
<div class="cart-drawer__footer" {{ block.shopify_attributes }}>
<div>
{%- if cart.cart_level_discount_applications.size > 0 -%}
<ul class="discounts list-unstyled" role="list" aria-label="{{ 'customer.order.discount' | t }}">
{%- for discount in cart.cart_level_discount_applications -%}
<li class="discounts__discount discounts__discount--end">
{{- 'icon-discount.svg' | inline_asset_content -}}
{{ discount.title | escape }}
(-{{ discount.total_allocated_amount | money }})
</li>
{%- endfor -%}
</ul>
{%- endif -%}
</div>
<div class="totals" role="status">
<h2 class="totals__total">{{ 'sections.cart.estimated_total' | t }}</h2>
<p class="totals__total-value">{{ cart.total_price | money_with_currency }}</p>
</div>
<small class="tax-note caption-large rte">
{%- if cart.duties_included and cart.taxes_included -%}
{%- if shop.shipping_policy.body == blank -%}
{{ 'sections.cart.duties_and_taxes_included_shipping_at_checkout_without_policy' | t }}
{%- else -%}
{{
'sections.cart.duties_and_taxes_included_shipping_at_checkout_with_policy_html'
| t: link: shop.shipping_policy.url
}}
{%- endif -%}
{%- elsif cart.duties_included == false and cart.taxes_included -%}
{%- if shop.shipping_policy.body == blank -%}
{{ 'sections.cart.taxes_included_shipping_at_checkout_without_policy' | t }}
{%- else -%}
{{
'sections.cart.taxes_included_shipping_at_checkout_with_policy_html'
| t: link: shop.shipping_policy.url
}}
{%- endif -%}
{%- elsif cart.duties_included and cart.taxes_included == false -%}
{%- if shop.shipping_policy.body == blank -%}
{{ 'sections.cart.duties_included_taxes_at_checkout_shipping_at_checkout_without_policy' | t }}
{%- else -%}
{{
'sections.cart.duties_included_taxes_at_checkout_shipping_at_checkout_with_policy_html'
| t: link: shop.shipping_policy.url
}}
{%- endif -%}
{%- elsif cart.duties_included == false and cart.taxes_included == false -%}
{%- if shop.shipping_policy.body == blank -%}
{{ 'sections.cart.taxes_at_checkout_shipping_at_checkout_without_policy' | t }}
{%- else -%}
{{
'sections.cart.taxes_at_checkout_shipping_at_checkout_with_policy_html'
| t: link: shop.shipping_policy.url
}}
{%- endif -%}
{%- endif -%}
</small>
</div>
<!-- CTAs -->
<div class="cart__ctas" {{ block.shopify_attributes }}>
<button
type="submit"
id="CartDrawer-Checkout"
class="cart__checkout-button button"
name="checkout"
form="CartDrawer-Form"
{% if cart == empty %}
disabled
{% endif %}
>
{{ 'sections.cart.checkout' | t }}
</button>
</div>
</div>
</div>
</div>
</cart-drawer>
+60
View File
@@ -0,0 +1,60 @@
{% comment %}
Renders cart notification
Accepts:
- color_scheme: {String} sets the color scheme of the notification (optional)
- desktop_menu_type: {String} passes the desktop menu type which allows us to use the right css class (optional)
Usage:
{% render 'cart-notification' %}
{% endcomment %}
<cart-notification>
<div class="cart-notification-wrapper{% if desktop_menu_type != 'drawer' %} page-width{% endif %}">
<div
id="cart-notification"
class="cart-notification focus-inset{% if color_scheme %} color-{{ color_scheme }} gradient{% endif %}"
aria-modal="true"
aria-label="{{ 'general.cart.item_added' | t }}"
role="dialog"
tabindex="-1"
>
<div class="cart-notification__header">
<h2 class="cart-notification__heading caption-large text-body">
{{- 'icon-checkmark.svg' | inline_asset_content -}}
{{ 'general.cart.item_added' | t }}
</h2>
<button
type="button"
class="cart-notification__close modal__close-button link link--text focus-inset"
aria-label="{{ 'accessibility.close' | t }}"
>
<span class="svg-wrapper">
{{- 'icon-close.svg' | inline_asset_content -}}
</span>
</button>
</div>
<div id="cart-notification-product" class="cart-notification-product"></div>
<div class="cart-notification__links">
<a
href="{{ routes.cart_url }}"
id="cart-notification-button"
class="button button--secondary button--full-width"
>
{{- 'general.cart.view_empty_cart' | t -}}
</a>
<form action="{{ routes.cart_url }}" method="post" id="cart-notification-form">
<button class="button button--primary button--full-width" name="checkout">
{{ 'sections.cart.checkout' | t }}
</button>
</form>
<button type="button" class="link button-label">{{ 'general.continue_shopping' | t }}</button>
</div>
</div>
</div>
</cart-notification>
{% style %}
.cart-notification {
display: none;
}
{% endstyle %}
+156
View File
@@ -0,0 +1,156 @@
{%- comment -%}
Renders the country picker for the localization form
Accepts:
- localPosition: pass in the position in which the form is coming up to create specific IDs
{%- endcomment -%}
{%- liquid
assign currencies = localization.available_countries | map: 'currency' | map: 'iso_code' | uniq
assign popular_countries = localization.available_countries | where: 'popular?' | sort: 'name'
assign show_country_filter = false
if localization.available_countries.size > 9
assign show_country_filter = true
endif
assign show_popular_countries = false
if localization.available_countries.size > 9 and popular_countries.size > 1
assign show_popular_countries = true
endif
assign show_currencies = false
if currencies.size > 1
assign show_currencies = true
endif
%}
<div class="disclosure">
<button
type="button"
class="disclosure__button localization-form__select localization-selector link link--text caption-large"
aria-expanded="false"
aria-controls="{{ localPosition }}-country-results"
aria-describedby="{{ localPosition }}Label"
>
<span>
{{- localization.country.name }} |
{{ localization.country.currency.iso_code }}
{{ localization.country.currency.symbol -}}
</span>
{{ 'icon-caret.svg' | inline_asset_content }}
</button>
<div class="disclosure__list-wrapper country-selector" hidden>
<div class="country-filter{% unless show_country_filter %} country-filter--no-padding{% endunless %}">
{% if show_country_filter %}
<div class="field">
<input
class="country-filter__input field__input"
id="country-filter-input"
type="search"
name="country_filter"
value=""
placeholder="{{ 'localization.search' | t }}"
role="combobox"
aria-owns="country-results"
aria-controls="country-results"
aria-haspopup="listbox"
aria-autocomplete="list"
autocorrect="off"
autocomplete="off"
autocapitalize="off"
spellcheck="false"
>
<label class="field__label" for="country-filter-input">{{ 'localization.search' | t }}</label>
<button
type="reset"
class="country-filter__reset-button field__button hidden"
aria-label="{{ 'general.search.reset' | t }}"
>
{{- 'icon-reset.svg' | inline_asset_content -}}
</button>
<div class="country-filter__search-icon field__button motion-reduce">
{{- 'icon-search.svg' | inline_asset_content -}}
</div>
</div>
{% endif %}
<button
class="country-selector__close-button button--small link"
type="button"
aria-label="{{ 'accessibility.close' | t }}"
>
{{- 'icon-close.svg' | inline_asset_content -}}
</button>
</div>
<div id="sr-country-search-results" class="visually-hidden" aria-live="polite"></div>
<div
class="disclosure__list country-selector__list{% if show_currencies %} country-selector__list--with-multiple-currencies{% endif %}"
id="{{ localPosition }}-country-results"
>
{% if show_popular_countries %}
<ul
role="list"
class="list-unstyled popular-countries"
aria-label="{{ 'localization.popular_countries_regions' | t }}"
>
{%- for country in popular_countries -%}
<li class="disclosure__item" tabindex="-1">
<a
class="link link--text disclosure__link caption-large focus-inset"
href="#"
{% if country.iso_code == localization.country.iso_code %}
aria-current="true"
{% endif %}
data-value="{{ country.iso_code }}"
id="{{ country.name }}"
>
<span
{% if country.iso_code != localization.country.iso_code %}
class="visibility-hidden"
{% endif %}
>
{{- 'icon-checkmark.svg' | inline_asset_content -}}
</span>
<span class="country">{{- country.name }}</span>
<span class="localization-form__currency motion-reduce{% unless show_currencies %} hidden{% endunless %}">
{{ country.currency.iso_code }}
{{ country.currency.symbol -}}
</span>
</a>
</li>
{%- endfor -%}
</ul>
{% endif %}
<ul role="list" class="list-unstyled countries">
{%- for country in localization.available_countries -%}
<li class="disclosure__item" tabindex="-1">
<a
class="link link--text disclosure__link caption-large focus-inset"
href="#"
{% if country.iso_code == localization.country.iso_code %}
aria-current="true"
{% endif %}
data-value="{{ country.iso_code }}"
id="{{ country.name }}"
>
<span
{% if country.iso_code != localization.country.iso_code %}
class="visibility-hidden"
{% endif %}
>
{{- 'icon-checkmark.svg' | inline_asset_content -}}
</span>
<span class="country">{{- country.name }}</span>
<span class="localization-form__currency motion-reduce{% unless show_currencies %} hidden{% endunless %}">
{{ country.currency.iso_code }}
{{ country.currency.symbol -}}
</span>
</a>
</li>
{%- endfor -%}
</ul>
</div>
</div>
<div class="country-selector__overlay"></div>
</div>
<input type="hidden" name="country_code" value="{{ localization.country.iso_code }}">
+946
View File
@@ -0,0 +1,946 @@
{% comment %}
Renders facets (filtering and sorting)
Accepts:
- results: {Object} Collection or Search object
- enable_filtering: {Boolean} Show filtering when true
- enable_sorting: {Boolean} Show sorting when true
- filter_type: {String} Type of filter
- paginate: {Object}
Usage:
{% render 'facets', results: collection, enable_filtering: true, enable_sorting: true, filter_type: 'vertical', paginate: paginate %}
{% endcomment %}
{{ 'component-show-more.css' | asset_url | stylesheet_tag }}
{{ 'component-swatch-input.css' | asset_url | stylesheet_tag }}
{{ 'component-swatch.css' | asset_url | stylesheet_tag }}
{%- liquid
assign sort_by = results.sort_by | default: results.default_sort_by
assign total_active_values = 0
assign default_presentation = 'text'
if results.url
assign results_url = results.url
else
assign terms = results.terms | escape
assign results_url = '?q=' | append: terms | append: '&options%5Bprefix%5D=last&sort_by=' | append: sort_by
endif
-%}
<div
class="facets-container{% if filter_type == 'drawer' %} facets-container-drawer{% endif %}{% if settings.animations_reveal_on_scroll %} scroll-trigger animate--fade-in{% endif %}"
data-collection-id="{{ results.id }}"
data-collection-handle="{{ results.handle }}"
data-template="{{ template.name }}"
>
{%- if filter_type == 'vertical' or filter_type == 'horizontal' -%}
<facet-filters-form class="facets small-hide">
<form
id="FacetFiltersForm"
class="{% if filter_type == 'horizontal' %}facets__form{% else %}facets__form-vertical{% endif %}"
>
{%- if results.terms -%}
<input type="hidden" name="q" value="{{ results.terms | escape }}">
<input name="options[prefix]" type="hidden" value="last">
{%- endif -%}
{% if enable_filtering %}
{% comment %} Heading is the first tabbable element on filter type horizontal {% endcomment %}
<div
id="FacetsWrapperDesktop"
{% if filter_type == 'horizontal' %}
class="facets__wrapper"
{% endif %}
>
{%- if filter_type == 'horizontal' and results.filters != empty -%}
<h2 class="facets__heading caption-large text-body" id="verticalTitle" tabindex="-1">
{{ 'products.facets.filter_by_label' | t }}
</h2>
{%- endif -%}
{% comment %} Pills are right below the title for filter type vertical {% endcomment %}
{%- if filter_type == 'vertical' -%}
<div class="active-facets active-facets-desktop">
<div class="active-facets-vertical-filter">
{%- unless results.filters == empty -%}
<h2
class="facets__heading facets__heading--vertical caption-large text-body"
id="verticalTitle"
tabindex="-1"
>
{{ 'products.facets.filter_by_label' | t }}
</h2>
{%- endunless -%}
<facet-remove class="active-facets__button-wrapper">
<a href="{{ results_url }}" class="active-facets__button-remove underlined-link">
<span>{{ 'products.facets.clear_all' | t }}</span>
</a>
</facet-remove>
</div>
{%- for filter in results.filters -%}
{%- for value in filter.active_values -%}
<facet-remove>
<a href="{{ value.url_to_remove }}" class="active-facets__button active-facets__button--light">
<span class="active-facets__button-inner button button--tertiary">
{{ filter.label | escape }}: {{ value.label | escape }}
<span class="svg-wrapper">
{{- 'icon-close-small.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'products.facets.clear_filter' | t }}</span>
</span>
</a>
</facet-remove>
{%- endfor -%}
{% if filter.type == 'price_range' %}
{% assign min = filter.min_value.value %}
{% assign max = filter.max_value.value %}
{%- if min != null or max != null -%}
<facet-remove>
<a href="{{ filter.url_to_remove }}" class="active-facets__button active-facets__button--light">
<span class="active-facets__button-inner button button--tertiary">
{{ min | default: 0 | money }} - {{ max | default: filter.range_max | money }}
<span class="svg-wrapper">
{{- 'icon-close-small.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'products.facets.clear_filter' | t }}</span>
</span>
</a>
</facet-remove>
{%- endif -%}
{% endif %}
{%- endfor -%}
</div>
{%- endif -%}
<script src="{{ 'show-more.js' | asset_url }}" defer="defer"></script>
{% comment %} Filters for both horizontal and vertical filter {% endcomment %}
{%- for filter in results.filters -%}
{% liquid
assign total_active_values = total_active_values | plus: filter.active_values.size
assign presentation = filter.presentation | default: default_presentation
if presentation == 'image'
assign show_more_number = 12
assign visual_layout_class = 'facets-layout facets-layout-grid facets-layout-grid--' | append: presentation
else
assign show_more_number = 10
assign visual_layout_class = 'facets-layout facets-layout-list facets-layout-list--' | append: presentation
endif
%}
{% case filter.type %}
{% when 'boolean', 'list' %}
<details
id="Details-{{ filter.param_name | escape }}-{{ section.id }}"
class="{% if filter_type == 'horizontal' %}disclosure-has-popup facets__disclosure{% else %} facets__disclosure-vertical{% endif %} js-filter"
data-index="{{ forloop.index }}"
{% if filter_type == 'vertical' and forloop.index == 1 %}
open
{% endif %}
>
<summary
class="facets__summary caption-large focus-offset"
aria-label="{{ filter.label | escape }} ({{ 'products.facets.filters_selected.one' | t: count: filter.active_values.size }})"
>
<div>
<span class="facets__summary-label">
{{- filter.label | escape }}
{%- if filter_type == 'vertical' -%}
<span class="facets__selected{% if filter.active_values.size == 0 %} hidden{% endif %}">
({{ filter.active_values.size }})</span
>
{%- endif -%}
</span>
{%- if filter_type == 'vertical' and filter.operator == 'AND' -%}
<span class="facets__and-helptext">
{{ 'products.facets.filter_and_operator_subtitle' | t }}
</span>
{%- endif -%}
{{- 'icon-caret.svg' | inline_asset_content -}}
</div>
</summary>
<div
id="Facet-{{ forloop.index }}-{{ section.id }}"
class="parent-display {% if filter_type == 'horizontal' %}facets__display{% else %}facets__display-vertical{% endif %}"
>
{%- if filter_type != 'vertical' -%}
<div class="facets__header">
<div>
<span class="facets__selected">
{{- 'products.facets.filters_selected' | t: count: filter.active_values.size -}}
</span>
{%- if filter.operator == 'AND' -%}
<span class="facets__and-helptext">
{{ 'products.facets.filter_and_operator_subtitle' | t }}
</span>
{%- endif -%}
</div>
<facet-remove>
<a href="{{ filter.url_to_remove }}" class="facets__reset link underlined-link">
{{ 'products.facets.reset' | t }}
</a>
</facet-remove>
</div>
{%- endif -%}
<fieldset class="facets-wrap parent-wrap {% if filter_type == 'vertical' %} facets-wrap-vertical{% endif %}">
<legend class="visually-hidden">{{ filter.label | escape }}</legend>
{%- liquid
assign sorted_values = filter.values
# Keep the selected values grouped together when operator is AND
if filter.operator == 'AND'
assign active_filter_values = filter.values | where: 'active', true
assign inactive_filter_values = filter.values | where: 'active', false
assign sorted_values = active_filter_values | concat: inactive_filter_values
endif
-%}
<ul
class="{{ visual_layout_class }}{% if filter_type == 'vertical' %} facets__list--vertical{% else %} facets__list{% endif %} list-unstyled"
role="list"
>
{%- for value in sorted_values -%}
{% liquid
assign input_id = 'Filter-' | append: filter.param_name | escape | append: '-' | append: forloop.index
assign is_disabled = false
if value.count == 0 and value.active == false
assign is_disabled = true
endif
%}
{%- capture label_class -%}
facets__label facet-checkbox{% if is_disabled %} disabled{% endif %}{% if value.active %} active{% endif %}
{%- endcapture -%}
{%- capture text_value -%}
<span class="facet-checkbox__text" aria-hidden="true">
<span class="facet-checkbox__text-label">{{- value.label | escape }}</span> ({{- value.count -}})
</span>
<span class="visually-hidden">
{{- value.label | escape }} (
{%- if value.count == 1 -%}
{{- 'products.facets.product_count_simple.one' | t: count: value.count -}}
{%- else -%}
{{- 'products.facets.product_count_simple.other' | t: count: value.count -}}
{%- endif -%}
)
</span>
{%- endcapture -%}
<li class="list-menu__item facets__item{% if forloop.index > show_more_number and filter_type == 'vertical' %} show-more-item hidden{% endif %}">
{%- if presentation == 'swatch' -%}
<div class="{{ label_class }}">
<div class="swatch-input-wrapper">
{% render 'swatch-input',
id: input_id,
type: 'checkbox',
name: value.param_name,
value: value.value,
product_form_id: 'FacetFiltersForm',
swatch: value.swatch,
checked: value.active,
disabled: is_disabled
%}
</div>
{{ text_value }}
</div>
{%- else -%}
<label for="{{ input_id }}" class="{{ label_class }}">
<input
type="checkbox"
name="{{ value.param_name }}"
value="{{ value.value }}"
id="{{ input_id }}"
{% if value.active %}
checked
{% endif %}
{% if is_disabled %}
disabled
{% endif %}
>
{%- if presentation == 'image' -%}
<div class="facets__image-wrapper">
{%- if value.image -%}
{{
value.image
| image_url: width: 300
| image_tag: class: 'facets__image', alt: value.alt
}}
{%- endif -%}
</div>
{%- else -%}
{{- 'square.svg' | inline_asset_content -}}
<div class="svg-wrapper">
{{- 'icon-checkmark.svg' | inline_asset_content -}}
</div>
{%- endif -%}
{{ text_value }}
</label>
{%- endif -%}
</li>
{%- endfor -%}
</ul>
</fieldset>
{%- if filter.values.size > show_more_number and filter_type == 'vertical' -%}
<show-more-button>
<button
class="button-show-more link underlined-link"
id="Show-More-{{ forloop.index }}-{{ section.id }}"
type="button"
>
<span class="label-show-more label-text"
><span aria-hidden="true">+ </span>{{ 'products.facets.show_more' | t -}}
</span>
<span class="label-show-less label-text hidden"
><span aria-hidden="true">- </span>{{ 'products.facets.show_less' | t -}}
</span>
</button>
</show-more-button>
{%- endif %}
</div>
</details>
{% when 'price_range' %}
<details
id="Details-{{ filter.param_name | escape }}-{{ section.id }}"
class="{% if filter_type == 'horizontal' %}disclosure-has-popup facets__disclosure{% else %} facets__disclosure-vertical{% endif %} js-filter"
data-index="{{ forloop.index }}"
{% if filter_type == 'vertical' and forloop.index == 1 %}
open
{% endif %}
>
<summary class="facets__summary caption-large focus-offset">
<div>
<span>{{ filter.label | escape }}</span>
{{- 'icon-caret.svg' | inline_asset_content -}}
</div>
</summary>
<div
id="Facet-{{ forloop.index }}-{{ section.id }}"
class="{% if filter_type == 'horizontal' %}facets__display{% else %}facets__display-vertical{% endif %}"
>
<div class="{% if filter_type == 'horizontal' %}facets__header{% else %}facets__header-vertical{% endif %}">
{%- assign max_price_amount = filter.range_max | money | strip_html | escape -%}
<span class="facets__selected">
{{- 'products.facets.max_price' | t: price: max_price_amount -}}
</span>
{%- if filter_type != 'vertical' -%}
<facet-remove>
<a href="{{ filter.url_to_remove }}" class="facets__reset link underlined-link">
{{ 'products.facets.reset' | t }}
</a>
</facet-remove>
{%- endif -%}
</div>
<price-range class="facets__price">
{% render 'price-facet', filter: filter, id_prefix: 'Filter-', filter_type: filter_type %}
</price-range>
</div>
</details>
{% endcase %}
{%- endfor -%}
</div>
{% comment %} Pills after filtes on filter type horizontal {% endcomment %}
{%- if filter_type == 'horizontal' -%}
<div class="active-facets active-facets-desktop">
{%- for filter in results.filters -%}
{%- for value in filter.active_values -%}
<facet-remove>
<a href="{{ value.url_to_remove }}" class="active-facets__button active-facets__button--light">
<span class="active-facets__button-inner button button--tertiary">
{{ filter.label | escape }}: {{ value.label | escape }}
<span class="svg-wrapper">
{{- 'icon-close-small.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'products.facets.clear_filter' | t }}</span>
</span>
</a>
</facet-remove>
{%- endfor -%}
{% if filter.type == 'price_range' %}
{% assign min = filter.min_value.value %}
{% assign max = filter.max_value.value %}
{%- if min != null or max != null -%}
<facet-remove>
<a href="{{ filter.url_to_remove }}" class="active-facets__button active-facets__button--light">
<span class="active-facets__button-inner button button--tertiary">
{{ min | default: 0 | money }} - {{ max | default: filter.range_max | money }}
<span class="svg-wrapper">
{{- 'icon-close-small.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'products.facets.clear_filter' | t }}</span>
</span>
</a>
</facet-remove>
{%- endif -%}
{% endif %}
{%- endfor -%}
<facet-remove class="active-facets__button-wrapper">
<a href="{{ results_url }}" class="active-facets__button-remove underlined-link">
<span>{{ 'products.facets.clear_all' | t }}</span>
</a>
</facet-remove>
</div>
{%- endif -%}
{% endif %}
{% if results.current_vendor or results.current_type %}
<input type="hidden" name="q" value="{{ results.current_vendor }}{{ results.current_type }}">
{% endif %}
{%- if filter_type == 'horizontal' -%}
{% comment %} Sorting and product count are the last elements when filter type is horizontal {% endcomment %}
{%- if enable_sorting -%}
<div class="facet-filters sorting caption">
<div class="facet-filters__field">
<h2 class="facet-filters__label caption-large text-body">
<label for="SortBy">{{ 'products.facets.sort_by_label' | t }}</label>
</h2>
<div class="select">
{%- assign sort_by = results.sort_by | default: results.default_sort_by -%}
<select
name="sort_by"
class="facet-filters__sort select__select caption-large"
id="SortBy"
aria-describedby="a11y-refresh-page-message"
>
{%- for option in results.sort_options -%}
<option
value="{{ option.value | escape }}"
{% if option.value == sort_by %}
selected="selected"
{% endif %}
>
{{ option.name | escape }}
</option>
{%- endfor -%}
</select>
<span class="svg-wrapper">
{{- 'icon-caret.svg' | inline_asset_content -}}
</span>
</div>
</div>
</div>
{%- endif -%}
<div class="product-count light" role="status">
<h2 class="product-count__text text-body">
<span id="ProductCountDesktop">
{%- if results.results_count -%}
{{ 'templates.search.results_with_count' | t: terms: results.terms, count: results.results_count }}
{%- elsif results.products_count == results.all_products_count -%}
{{ 'products.facets.product_count_simple' | t: count: results.products_count }}
{%- else -%}
{{
'products.facets.product_count'
| t: product_count: results.products_count, count: results.all_products_count
}}
{%- endif -%}
</span>
</h2>
{%- render 'loading-spinner' -%}
</div>
{%- endif -%}
</form>
</facet-filters-form>
{%- endif -%}
{% comment %} Drawer and mobile filter {% endcomment %}
<menu-drawer
class="mobile-facets__wrapper{% if filter_type == 'horizontal' or filter_type == 'vertical' %} medium-hide large-up-hide{% endif %}"
data-breakpoint="mobile"
>
<details class="mobile-facets__disclosure disclosure-has-popup">
<summary class="mobile-facets__open-wrapper focus-offset">
<span class="mobile-facets__open{% if filter_type == 'drawer' and enable_filtering == false %} medium-hide large-up-hide{% endif %}">
<span class="svg-wrapper">
{{- 'icon-filter.svg' | inline_asset_content -}}
</span>
<span class="mobile-facets__open-label button-label medium-hide large-up-hide">
{%- if enable_filtering and enable_sorting -%}
{{ 'products.facets.filter_and_sort' | t }}
{%- elsif enable_filtering -%}
{{ 'products.facets.filter_button' | t }}
{%- elsif enable_sorting -%}
{{ 'products.facets.sort_button' | t }}
{%- endif -%}
</span>
<span class="mobile-facets__open-label button-label small-hide">
{%- if enable_filtering -%}
{{ 'products.facets.filter_button' | t }}
{%- endif -%}
</span>
</span>
<span tabindex="0" class="mobile-facets__close">
<span class="svg-wrapper">
{{- 'icon-close.svg' | inline_asset_content -}}
</span>
</span>
</summary>
<facet-filters-form>
<form id="FacetFiltersFormMobile" class="mobile-facets">
<div class="mobile-facets__inner gradient">
<div class="mobile-facets__header">
<div class="mobile-facets__header-inner">
<h2 class="mobile-facets__heading medium-hide large-up-hide">
{%- if enable_filtering and enable_sorting -%}
{{ 'products.facets.filter_and_sort' | t }}
{%- elsif enable_filtering -%}
{{ 'products.facets.filter_button' | t }}
{%- elsif enable_sorting -%}
{{ 'products.facets.sort_button' | t }}
{%- endif -%}
</h2>
<h2 class="mobile-facets__heading small-hide">
{%- if enable_filtering -%}
{{ 'products.facets.filter_button' | t }}
{%- endif -%}
</h2>
<p class="mobile-facets__count">
{%- if results.results_count -%}
{{ 'templates.search.results_with_count' | t: terms: results.terms, count: results.results_count }}
{%- elsif results.products_count == results.all_products_count -%}
{{ 'products.facets.product_count_simple' | t: count: results.products_count }}
{%- else -%}
{{
'products.facets.product_count'
| t: product_count: results.products_count, count: results.all_products_count
}}
{%- endif -%}
</p>
</div>
</div>
<div
id="FacetsWrapperMobile"
class="mobile-facets__main has-submenu gradient"
>
{%- if enable_filtering -%}
{%- for filter in results.filters -%}
{% liquid
assign presentation = filter.presentation | default: default_presentation
if presentation == 'image'
assign visual_layout_class = 'facets-layout facets-layout-grid facets-layout-grid--' | append: presentation
else
assign visual_layout_class = 'facets-layout facets-layout-list facets-layout-list--' | append: presentation
endif
%}
{% case filter.type %}
{% when 'boolean', 'list' %}
<details
id="Details-Mobile-{{ filter.param_name | escape }}-{{ section.id }}"
class="mobile-facets__details js-filter"
data-index="mobile-{{ forloop.index }}"
>
<summary class="mobile-facets__summary focus-inset">
<div>
<span>{{ filter.label | escape }}</span>
<span class="mobile-facets__arrow">
{{- 'icon-arrow.svg' | inline_asset_content -}}
</span>
</div>
</summary>
<div
id="FacetMobile-{{ forloop.index }}-{{ section.id }}"
class="mobile-facets__submenu gradient"
>
<button
class="mobile-facets__close-button link link--text focus-inset"
aria-expanded="true"
type="button"
>
{{- 'icon-arrow.svg' | inline_asset_content -}}
<span>{{ filter.label | escape }}</span>
{%- if filter.operator == 'AND' -%}
<span class="facets__and-helptext">
{{ 'products.facets.filter_and_operator_subtitle' | t }}
</span>
{%- endif -%}
</button>
<ul class="{{ visual_layout_class }} mobile-facets__list list-unstyled" role="list">
{%- liquid
assign sorted_values = filter.values
# Keep the selected values grouped together when operator is AND
if filter.operator == 'AND'
assign active_filter_values = filter.values | where: 'active', true
assign inactive_filter_values = filter.values | where: 'active', false
assign sorted_values = active_filter_values | concat: inactive_filter_values
endif
-%}
{%- for value in sorted_values -%}
{% liquid
assign input_id = 'Filter-' | append: filter.param_name | escape | append: '-mobile-' | append: forloop.index
assign is_disabled = false
if value.count == 0 and value.active == false
assign is_disabled = true
endif
%}
{%- capture label_class -%}
facets__label mobile-facets__label{% if is_disabled %} disabled{% endif %}{% if value.active %} active{% endif %}
{%- endcapture -%}
{%- capture text_value -%}
<span class="facet-checkbox__text" aria-hidden="true">
<span class="facet-checkbox__text-label">{{- value.label | escape }}</span> ({{- value.count -}})
</span>
<span class="visually-hidden">
{{- value.label | escape }} (
{%- if value.count == '1' -%}
{{- 'products.facets.product_count_simple.one' | t: count: value.count -}}
{%- else -%}
{{- 'products.facets.product_count_simple.other' | t: count: value.count -}}
{%- endif -%}
)
</span>
{%- endcapture -%}
<li class="mobile-facets__item list-menu__item">
{% if presentation == 'swatch' %}
<div class="{{ label_class }}">
<div class="swatch-input-wrapper">
{% render 'swatch-input',
id: input_id,
type: 'checkbox',
name: value.param_name,
value: value.value,
product_form_id: 'FacetFiltersFormMobile',
swatch: value.swatch,
checked: value.active,
disabled: is_disabled
%}
</div>
{{ text_value }}
</div>
{% else %}
<label for="{{ input_id }}" class="{{ label_class }}">
<input
class="mobile-facets__checkbox"
type="checkbox"
name="{{ value.param_name }}"
value="{{ value.value }}"
id="{{ input_id }}"
{% if value.active %}
checked
{% endif %}
{% if is_disabled %}
disabled
{% endif %}
>
{%- if presentation == 'image' -%}
<div class="facets__image-wrapper">
{%- if value.image -%}
{{
value.image
| image_url: width: 300
| image_tag: class: 'facets__image', alt: value.alt
}}
{%- endif -%}
</div>
{%- else -%}
<span class="mobile-facets__highlight"></span>
{{- 'square.svg' | inline_asset_content -}}
{{- 'icon-checkmark.svg' | inline_asset_content -}}
{%- endif %}
{{ text_value }}
</label>
{% endif %}
</li>
{%- endfor -%}
</ul>
<div class="mobile-facets__footer gradient">
<facet-remove class="mobile-facets__clear-wrapper">
<a href="{{ filter.url_to_remove }}" class="mobile-facets__clear underlined-link">
{{- 'products.facets.clear' | t -}}
</a>
</facet-remove>
<button
type="button"
class="button button--primary"
onclick="this.closest('.mobile-facets__wrapper').querySelector('summary').click()"
>
{{ 'products.facets.apply' | t }}
</button>
</div>
</div>
</details>
{% when 'price_range' %}
<details
id="Details-Mobile-{{ filter.param_name | escape }}-{{ section.id }}"
class="mobile-facets__details js-filter"
data-index="mobile-{{ forloop.index }}"
>
<summary class="mobile-facets__summary focus-inset">
<div>
<span>{{ filter.label | escape }}</span>
<span class="mobile-facets__arrow">
{{- 'icon-arrow.svg' | inline_asset_content -}}
</span>
</div>
</summary>
<div
id="FacetMobile-{{ forloop.index }}-{{ section.id }}"
class="mobile-facets__submenu gradient"
>
<button
class="mobile-facets__close-button link link--text focus-inset"
aria-expanded="true"
type="button"
>
{{- 'icon-arrow.svg' | inline_asset_content -}}
{{ filter.label | escape }}
</button>
{%- assign max_price_amount = filter.range_max | money | strip_html | escape -%}
<p class="mobile-facets__info">
{{ 'products.facets.max_price' | t: price: max_price_amount }}
</p>
<price-range class="facets__price">
{% render 'price-facet', filter: filter, id_prefix: 'Mobile-Filter-' %}
</price-range>
<div class="mobile-facets__footer">
<facet-remove class="mobile-facets__clear-wrapper">
<a href="{{ filter.url_to_remove }}" class="mobile-facets__clear underlined-link">
{{- 'products.facets.clear' | t -}}
</a>
</facet-remove>
<button
type="button"
class="button button--primary"
onclick="this.closest('.mobile-facets__wrapper').querySelector('summary').click()"
>
{{ 'products.facets.apply' | t }}
</button>
</div>
</div>
</details>
{% endcase %}
{%- endfor -%}
{%- endif -%}
{%- if enable_sorting -%}
<div
id="Details-Mobile-SortBy-{{ section.id }}"
class="mobile-facets__details js-filter{% if filter_type == 'drawer' %} medium-hide large-up-hide{% endif %}"
data-index="mobile-{{ forloop.index }}"
>
<div class="mobile-facets__summary">
<div class="mobile-facets__sort">
<label for="SortBy-mobile">{{ 'products.facets.sort_by_label' | t }}</label>
<div class="select">
<select
name="sort_by"
class="select__select"
id="SortBy-mobile"
aria-describedby="a11y-refresh-page-message"
>
{%- for option in results.sort_options -%}
<option
value="{{ option.value | escape }}"
{% if option.value == sort_by %}
selected="selected"
{% endif %}
>
{{ option.name | escape }}
</option>
{%- endfor -%}
</select>
<span class="svg-wrapper">
{{- 'icon-caret.svg' | inline_asset_content -}}
</span>
</div>
</div>
</div>
</div>
{%- endif -%}
<div class="mobile-facets__footer">
<facet-remove class="mobile-facets__clear-wrapper">
<a href="{{ results_url }}" class="mobile-facets__clear underlined-link">
{{- 'products.facets.clear_all' | t -}}
</a>
</facet-remove>
<button
type="button"
class="button button--primary"
onclick="this.closest('.mobile-facets__wrapper').querySelector('summary').click()"
>
{{ 'products.facets.apply' | t }}
</button>
</div>
</div>
{% if results.current_vendor or results.current_type %}
<input type="hidden" name="q" value="{{ results.current_vendor }}{{ results.current_type }}">
{% endif %}
{%- if results.terms -%}
<input type="hidden" name="q" value="{{ results.terms | escape }}">
<input name="options[prefix]" type="hidden" value="last">
{%- endif -%}
</div>
</form>
</facet-filters-form>
</details>
</menu-drawer>
<div class="active-facets active-facets-mobile medium-hide large-up-hide">
{%- for filter in results.filters -%}
{%- for value in filter.active_values -%}
<facet-remove>
<a href="{{ value.url_to_remove }}" class="active-facets__button active-facets__button--light">
<span class="active-facets__button-inner button button--tertiary">
{{ filter.label | escape }}: {{ value.label | escape }}
<span class="svg-wrapper">
{{- 'icon-close-small.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'products.facets.clear_filter' | t }}</span>
</span>
</a>
</facet-remove>
{%- endfor -%}
{%- if filter.type == 'price_range' -%}
{% assign min = filter.min_value.value %}
{% assign max = filter.max_value.value %}
{%- if min != null or max != null -%}
<facet-remove>
<a href="{{ filter.url_to_remove }}" class="active-facets__button active-facets__button--light">
<span class="active-facets__button-inner button button--tertiary">
{{ min | default: 0 | money }} - {{ max | default: filter.range_max | money }}
<span class="svg-wrapper">
{{- 'icon-close-small.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'products.facets.clear_filter' | t }}</span>
</span>
</a>
</facet-remove>
{%- endif -%}
{%- endif -%}
{%- endfor -%}
<facet-remove class="active-facets__button-wrapper">
<a href="{{ results_url }}" class="active-facets__button-remove underlined-link">
<span>{{ 'products.facets.clear_all' | t }}</span>
</a>
</facet-remove>
</div>
{% comment %} Sort, product count and filter pills at the end when filter is type of Drawer for the correct tabbing order {% endcomment %}
{%- if enable_sorting and filter_type == 'drawer' -%}
<facet-filters-form class="facets small-hide">
<form id="FacetSortDrawerForm" class="facets__form">
<div class="facet-filters sorting caption small-hide">
<div class="facet-filters__field">
<h2 class="facet-filters__label caption-large text-body">
<label for="SortBy">{{ 'products.facets.sort_by_label' | t }}</label>
</h2>
<div class="select">
{%- assign sort_by = results.sort_by | default: results.default_sort_by -%}
<select
name="sort_by"
class="facet-filters__sort select__select caption-large"
id="SortBy"
aria-describedby="a11y-refresh-page-message"
>
{%- for option in results.sort_options -%}
<option
value="{{ option.value | escape }}"
{% if option.value == sort_by %}
selected="selected"
{% endif %}
>
{{ option.name | escape }}
</option>
{%- endfor -%}
</select>
<span class="svg-wrapper">
{{- 'icon-caret.svg' | inline_asset_content -}}
</span>
</div>
</div>
</div>
{% if results.current_vendor or results.current_type %}
<input type="hidden" name="q" value="{{ results.current_vendor }}{{ results.current_type }}">
{% endif %}
{%- if results.terms -%}
<input type="hidden" name="q" value="{{ results.terms | escape }}">
<input name="options[prefix]" type="hidden" value="last">
{%- endif -%}
</form>
</facet-filters-form>
{%- endif -%}
<div
class="product-count light{% if filter_type == 'vertical' or filter_type == 'horizontal' %} medium-hide large-up-hide{% endif %}"
role="status"
>
<h2 class="product-count__text text-body">
<span
id="ProductCount"
data-product-count="{{ results.products_count | default: results.results_count }}"
data-total-count="{{ results.all_products_count | default: results.products_count | default: results.results_count }}"
>
{%- if results.results_count -%}
{{ 'templates.search.results_with_count' | t: terms: results.terms, count: results.results_count }}
{%- elsif results.products_count == results.all_products_count -%}
{{ 'products.facets.product_count_simple' | t: count: results.products_count }}
{%- else -%}
{{
'products.facets.product_count'
| t: product_count: results.products_count, count: results.all_products_count
}}
{%- endif -%}
</span>
</h2>
{%- render 'loading-spinner' -%}
</div>
{%- if filter_type == 'drawer' -%}
<facet-filters-form class="facets facets-pill small-hide">
<form id="FacetFiltersPillsForm" class="facets__form">
<div class="active-facets active-facets-desktop">
{%- for filter in results.filters -%}
{%- for value in filter.active_values -%}
<facet-remove>
<a href="{{ value.url_to_remove }}" class="active-facets__button active-facets__button--light">
<span class="active-facets__button-inner button button--tertiary">
{{ filter.label | escape }}: {{ value.label | escape }}
<span class="svg-wrapper">
{{- 'icon-close-small.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'products.facets.clear_filter' | t }}</span>
</span>
</a>
</facet-remove>
{%- endfor -%}
{%- if filter.type == 'price_range' -%}
{% assign min = filter.min_value.value %}
{% assign max = filter.max_value.value %}
{%- if min != null or max != null -%}
<facet-remove>
<a href="{{ filter.url_to_remove }}" class="active-facets__button active-facets__button--light">
<span class="active-facets__button-inner button button--tertiary">
{{ min | default: 0 | money }} - {{ max | default: filter.range_max | money }}
<span class="svg-wrapper">
{{- 'icon-close-small.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'products.facets.clear_filter' | t }}</span>
</span>
</a>
</facet-remove>
{%- endif -%}
{%- endif -%}
{%- endfor -%}
<facet-remove class="active-facets__button-wrapper">
<a href="{{ results_url }}" class="active-facets__button-remove underlined-link">
<span>{{ 'products.facets.clear_all' | t }}</span>
</a>
</facet-remove>
</div>
</form>
</facet-filters-form>
{%- endif -%}
</div>
+222
View File
@@ -0,0 +1,222 @@
{% comment %}
Renders gift card recipient form.
Accepts:
- product: {Object} product object.
- form: {Object} the product form object.
- section: {Object} section to which this snippet belongs.
Usage:
{% render 'gift-card-recipient-form', product: product, form: form, section: section %}
{% endcomment %}
<div class="customer">
{%- assign gift_card_recipient_control_flag = 'properties[__shopify_send_gift_card_to_recipient]' -%}
<script src="{{ 'recipient-form.js' | asset_url }}" defer="defer"></script>
<recipient-form
class="recipient-form"
data-section-id="{{ section.id }}"
data-product-variant-id="{{ product.selected_or_first_available_variant.id }}"
>
<input
id="Recipient-checkbox-{{ section.id }}"
type="checkbox"
name="{{ gift_card_recipient_control_flag }}"
disabled
>
<label class="recipient-checkbox" for="Recipient-checkbox-{{ section.id }}">
{{ 'square.svg' | inline_asset_content }}
{{- 'icon-checkmark.svg' | inline_asset_content -}}
<span>{{ 'recipient.form.checkbox' | t }}</span>
</label>
<div
class="product-form__recipient-error-message-wrapper"
role="alert"
{% unless form.errors %}
hidden
{% endunless %}
>
<h2 class="form__message" tabindex="-1" autofocus>
{{- 'icon-error.svg' | inline_asset_content -}}
<span class="error-message">{{ 'templates.contact.form.error_heading' | t }}</span>
</h2>
<ul>
{%- if form.errors -%}
{%- for field in form.errors -%}
<li>
{%- if field == 'form' -%}
{{ form.errors.messages[field] }}
{%- else -%}
<a href="#Recipient-{{ field }}-{{ section.id }}">
{{ form.errors.messages[field] }}
</a>
{%- endif -%}
</li>
{%- endfor -%}
{%- endif -%}
</ul>
</div>
<p
id="Recipient-fields-live-region-{{ section.id }}"
class="visually-hidden"
role="status"
></p>
<div class="recipient-fields">
<hr>
<div class="recipient-fields__field">
<div class="field">
<input
class="field__input"
id="Recipient-email-{{ section.id }}"
type="email"
placeholder="{{ 'recipient.form.email' | t }}"
name="properties[Recipient email]"
value="{{ form.email }}"
{% if form.errors contains 'email' %}
aria-invalid="true"
aria-describedby="RecipientForm-email-error-{{ section.id }}"
{% endif %}
>
<label class="field__label" for="Recipient-email-{{ section.id }}">
<span class="recipient-email-label required">{{ 'recipient.form.email_label' | t }}</span>
<span class="recipient-email-label optional">
{{- 'recipient.form.email_label_optional_for_no_js_behavior' | t -}}
</span>
</label>
</div>
<div
id="RecipientForm-email-error-{{ section.id }}"
class="form__message{% unless form.errors contains 'email' %} hidden{% endunless %}"
>
{{- 'icon-error.svg' | inline_asset_content -}}
<span class="error-message">
{%- if form.errors contains 'email' -%}
{{ form.errors.messages.email }}.
{%- endif -%}
</span>
</div>
</div>
<div class="recipient-fields__field">
<div class="field">
<input
class="field__input"
autocomplete="name"
type="text"
id="Recipient-name-{{ section.id }}"
name="properties[Recipient name]"
placeholder="{{ 'recipient.form.name' | t }}"
value="{{ form.name }}"
{% if form.errors contains 'name' %}
aria-invalid="true"
aria-describedby="RecipientForm-name-error-{{ section.id }}"
{% endif %}
>
<label class="field__label" for="Recipient-name-{{ section.id }}">
{{- 'recipient.form.name_label' | t -}}
</label>
</div>
<div
id="RecipientForm-name-error-{{ section.id }}"
class="form__message{% unless form.errors contains 'name' %} hidden{% endunless %}"
>
{{- 'icon-error.svg' | inline_asset_content -}}
<span class="error-message">
{%- if form.errors contains 'name' -%}
{{ form.errors.messages.name }}.
{%- endif -%}
</span>
</div>
</div>
<div class="recipient-fields__field">
{%- assign max_chars_message = 200 -%}
{%- assign max_chars_message_rendered = 'recipient.form.max_characters' | t: max_chars: max_chars_message -%}
{%- assign message_label_rendered = 'recipient.form.message_label' | t -%}
<div class="field">
<textarea
rows="10"
id="Recipient-message-{{ section.id }}"
class="text-area field__input"
name="properties[Message]"
maxlength="{{ max_chars_message }}"
placeholder="{{ 'recipient.form.message' | t }}"
aria-label="{{ message_label_rendered }} {{ max_chars_message_rendered }}"
{% if form.errors contains 'message' %}
aria-invalid="true"
aria-describedby="RecipientForm-message-error-{{ section.id }}"
{% endif %}
>{{ form.message }}</textarea>
<label class="form__label field__label" for="Recipient-message-{{ section.id }}">
{{ message_label_rendered }}
</label>
</div>
<label class="form__label recipient-form-field-label recipient-form-field-label--space-between">
<span>{{ max_chars_message_rendered }}</span>
</label>
<div
id="RecipientForm-message-error-{{ section.id }}"
class="form__message{% unless form.errors contains 'message' %} hidden{% endunless %}"
>
{{- 'icon-error.svg' | inline_asset_content -}}
<span class="error-message">
{%- if form.errors contains 'message' -%}
{{ form.errors.messages.message }}.
{%- endif -%}
</span>
</div>
</div>
<div class="recipient-fields__field">
<div class="field">
<input
class="field__input text-body"
autocomplete="send_on"
type="date"
id="Recipient-send-on-{{ section.id }}"
name="properties[Send on]"
placeholder="{{ 'recipient.form.send_on' | t }}"
pattern="\d{4}-\d{2}-\d{2}"
value="{{ form.send_on }}"
{% if form.errors contains 'send_on' %}
aria-invalid="true"
aria-describedby="RecipientForm-send_on-error-{{ section.id }}"
{% endif %}
>
<label class="form__label field__label" for="Recipient-send-on-{{ section.id }}">
{{ 'recipient.form.send_on_label' | t }}
</label>
</div>
<div
id="RecipientForm-send_on-error-{{ section.id }}"
class="form__message{% unless form.errors contains 'send_on' %} hidden{% endunless %}"
>
{{- 'icon-error.svg' | inline_asset_content -}}
<span class="error-message">
{%- if form.errors contains 'send_on' -%}
{{ form.errors.messages.send_on }}.
{%- endif -%}
</span>
</div>
</div>
</div>
<input
type="hidden"
name="{{ gift_card_recipient_control_flag }}"
value="if_present"
id="Recipient-control-{{ section.id }}"
>
<input
type="hidden"
name="properties[__shopify_offset]"
value=""
id="Recipient-timezone-offset-{{ section.id }}"
disabled
>
</recipient-form>
</div>
+295
View File
@@ -0,0 +1,295 @@
{% comment %}
Renders a header drawer menu for mobile and desktop.
Usage:
{% render 'header-drawer' %}
{% endcomment %}
<header-drawer data-breakpoint="{% if section.settings.menu_type_desktop == 'drawer' %}desktop{% else %}tablet{% endif %}">
<details id="Details-menu-drawer-container" class="menu-drawer-container">
<summary
class="header__icon header__icon--menu header__icon--summary link focus-inset"
aria-label="{{ 'sections.header.menu' | t }}"
>
<span>
{{- 'icon-hamburger.svg' | inline_asset_content -}}
{{- 'icon-close.svg' | inline_asset_content -}}
</span>
</summary>
<div id="menu-drawer" class="gradient menu-drawer motion-reduce color-{{ section.settings.menu_color_scheme }}">
<div class="menu-drawer__inner-container">
<div class="menu-drawer__navigation-container">
<nav class="menu-drawer__navigation">
<ul class="menu-drawer__menu has-submenu list-menu" role="list">
{%- for link in section.settings.menu.links -%}
<li>
{%- if link.links != blank -%}
<details id="Details-menu-drawer-menu-item-{{ forloop.index }}">
<summary
id="HeaderDrawer-{{ link.handle }}"
class="menu-drawer__menu-item list-menu__item link link--text focus-inset{% if link.child_active %} menu-drawer__menu-item--active{% endif %}"
>
{{ link.title | escape }}
<span class="svg-wrapper">
{{- 'icon-arrow.svg' | inline_asset_content -}}
</span>
<span class="svg-wrapper">
{{- 'icon-caret.svg' | inline_asset_content -}}
</span>
</summary>
<div
id="link-{{ link.handle | escape }}"
class="menu-drawer__submenu has-submenu gradient motion-reduce"
tabindex="-1"
>
<div class="menu-drawer__inner-submenu">
<button class="menu-drawer__close-button link link--text focus-inset" aria-expanded="true">
<span class="svg-wrapper">
{{- 'icon-arrow.svg' | inline_asset_content -}}
</span>
{{ link.title | escape }}
</button>
<ul class="menu-drawer__menu list-menu" role="list" tabindex="-1">
{%- for childlink in link.links -%}
<li>
{%- if childlink.links == blank -%}
<a
id="HeaderDrawer-{{ link.handle }}-{{ childlink.handle }}"
href="{{ childlink.url }}"
class="menu-drawer__menu-item link link--text list-menu__item focus-inset{% if childlink.current %} menu-drawer__menu-item--active{% endif %}"
{% if childlink.current %}
aria-current="page"
{% endif %}
>
{{ childlink.title | escape }}
</a>
{%- else -%}
<details id="Details-menu-drawer-{{ link.handle }}-{{ childlink.handle }}">
<summary
id="HeaderDrawer-{{ link.handle }}-{{ childlink.handle }}"
class="menu-drawer__menu-item link link--text list-menu__item focus-inset"
>
{{ childlink.title | escape }}
<span class="svg-wrapper">
{{- 'icon-arrow.svg' | inline_asset_content -}}
</span>
<span class="svg-wrapper">
{{- 'icon-caret.svg' | inline_asset_content -}}
</span>
</summary>
<div
id="childlink-{{ childlink.handle | escape }}"
class="menu-drawer__submenu has-submenu gradient motion-reduce"
>
<button
class="menu-drawer__close-button link link--text focus-inset"
aria-expanded="true"
>
<span class="svg-wrapper">
{{- 'icon-arrow.svg' | inline_asset_content -}}
</span>
{{ childlink.title | escape }}
</button>
<ul
class="menu-drawer__menu list-menu"
role="list"
tabindex="-1"
>
{%- for grandchildlink in childlink.links -%}
<li>
<a
id="HeaderDrawer-{{ link.handle }}-{{ childlink.handle }}-{{ grandchildlink.handle }}"
href="{{ grandchildlink.url }}"
class="menu-drawer__menu-item link link--text list-menu__item focus-inset{% if grandchildlink.current %} menu-drawer__menu-item--active{% endif %}"
{% if grandchildlink.current %}
aria-current="page"
{% endif %}
>
{{ grandchildlink.title | escape }}
</a>
</li>
{%- endfor -%}
</ul>
</div>
</details>
{%- endif -%}
</li>
{%- endfor -%}
</ul>
</div>
</div>
</details>
{%- else -%}
<a
id="HeaderDrawer-{{ link.handle }}"
href="{{ link.url }}"
class="menu-drawer__menu-item list-menu__item link link--text focus-inset{% if link.current %} menu-drawer__menu-item--active{% endif %}"
{% if link.current %}
aria-current="page"
{% endif %}
>
{{ link.title | escape }}
</a>
{%- endif -%}
</li>
{%- endfor -%}
</ul>
</nav>
<div class="menu-drawer__utility-links">
{%- if shop.customer_accounts_enabled -%}
<a
href="{%- if customer -%}{{ routes.account_url }}{%- else -%}{{ routes.account_login_url }}{%- endif -%}"
class="menu-drawer__account link focus-inset h5 medium-hide large-up-hide"
rel="nofollow"
>
{%- if section.settings.enable_customer_avatar -%}
<account-icon>
{%- if customer and customer.has_avatar? -%}
{{ customer | avatar }}
{%- else -%}
<span class="svg-wrapper">
{{- 'icon-account.svg' | inline_asset_content -}}
</span>
{%- endif -%}
</account-icon>
{%- else -%}
<span class="svg-wrapper">
{{- 'icon-account.svg' | inline_asset_content -}}
</span>
{%- endif -%}
{%- liquid
if customer
echo 'customer.account_fallback' | t
else
echo 'customer.log_in' | t
endif
-%}
</a>
{%- endif -%}
{%- if localization.available_countries or localization.available_languages -%}
<div class="menu-drawer__localization header-localization">
{%- if localization.available_countries and localization.available_countries.size > 1 -%}
<localization-form>
{%- form 'localization', id: 'HeaderCountryMobileForm', class: 'localization-form' -%}
<div>
<h2 class="visually-hidden" id="HeaderCountryMobileLabel">
{{ 'localization.country_label' | t }}
</h2>
{%- render 'country-localization', localPosition: 'HeaderCountryMobile' -%}
</div>
{%- endform -%}
</localization-form>
{% endif %}
{%- if localization.available_languages and localization.available_languages.size > 1 -%}
<localization-form>
{%- form 'localization', id: 'HeaderLanguageMobileForm', class: 'localization-form' -%}
<div>
<h2 class="visually-hidden" id="HeaderLanguageMobileLabel">
{{ 'localization.language_label' | t }}
</h2>
{%- render 'language-localization', localPosition: 'HeaderLanguageMobile' -%}
</div>
{%- endform -%}
</localization-form>
{%- endif -%}
</div>
{%- endif -%}
<ul class="list list-social list-unstyled" role="list">
{%- if settings.social_twitter_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_twitter_link }}" class="list-social__link link">
<span class="svg-wrapper">
{{- 'icon-twitter.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.twitter' | t }}</span>
</a>
</li>
{%- endif -%}
{%- if settings.social_facebook_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_facebook_link }}" class="list-social__link link">
<span class="svg-wrapper">
{{- 'icon-facebook.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.facebook' | t }}</span>
</a>
</li>
{%- endif -%}
{%- if settings.social_pinterest_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_pinterest_link }}" class="list-social__link link">
<span class="svg-wrapper">
{{- 'icon-pinterest.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.pinterest' | t }}</span>
</a>
</li>
{%- endif -%}
{%- if settings.social_instagram_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_instagram_link }}" class="list-social__link link">
<span class="svg-wrapper">
{{- 'icon-instagram.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.instagram' | t }}</span>
</a>
</li>
{%- endif -%}
{%- if settings.social_tiktok_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_tiktok_link }}" class="list-social__link link">
<span class="svg-wrapper">
{{- 'icon-tiktok.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.tiktok' | t }}</span>
</a>
</li>
{%- endif -%}
{%- if settings.social_tumblr_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_tumblr_link }}" class="list-social__link link">
<span class="svg-wrapper">
{{- 'icon-tumblr.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.tumblr' | t }}</span>
</a>
</li>
{%- endif -%}
{%- if settings.social_snapchat_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_snapchat_link }}" class="list-social__link link">
<span class="svg-wrapper">
{{- 'icon-snapchat.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.snapchat' | t }}</span>
</a>
</li>
{%- endif -%}
{%- if settings.social_youtube_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_youtube_link }}" class="list-social__link link">
<span class="svg-wrapper">
{{- 'icon-youtube.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.youtube' | t }}</span>
</a>
</li>
{%- endif -%}
{%- if settings.social_vimeo_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_vimeo_link }}" class="list-social__link link">
<span class="svg-wrapper">
{{- 'icon-vimeo.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.vimeo' | t }}</span>
</a>
</li>
{%- endif -%}
</ul>
</div>
</div>
</div>
</div>
</details>
</header-drawer>
+103
View File
@@ -0,0 +1,103 @@
{% comment %}
Renders a standard dropdown style menu for the header.
Usage:
{% render 'header-dropdown-menu' %}
{% endcomment %}
<nav class="header__inline-menu">
<ul class="list-menu list-menu--inline" role="list">
{%- for link in section.settings.menu.links -%}
<li>
{%- if link.links != blank -%}
<header-menu>
<details id="Details-HeaderMenu-{{ forloop.index }}">
<summary
id="HeaderMenu-{{ link.handle }}"
class="header__menu-item list-menu__item link focus-inset"
>
<span
{%- if link.child_active %}
class="header__active-menu-item"
{% endif %}
>
{{- link.title | escape -}}
</span>
{{- 'icon-caret.svg' | inline_asset_content -}}
</summary>
<ul
id="HeaderMenu-MenuList-{{ forloop.index }}"
class="header__submenu list-menu list-menu--disclosure color-{{ section.settings.menu_color_scheme }} gradient caption-large motion-reduce global-settings-popup"
role="list"
tabindex="-1"
>
{%- for childlink in link.links -%}
<li>
{%- if childlink.links == blank -%}
<a
id="HeaderMenu-{{ link.handle }}-{{ childlink.handle }}"
href="{{ childlink.url }}"
class="header__menu-item list-menu__item link link--text focus-inset caption-large{% if childlink.current %} list-menu__item--active{% endif %}"
{% if childlink.current %}
aria-current="page"
{% endif %}
>
{{ childlink.title | escape }}
</a>
{%- else -%}
<details id="Details-HeaderSubMenu-{{ link.handle }}-{{ childlink.handle }}">
<summary
id="HeaderMenu-{{ link.handle }}-{{ childlink.handle }}"
class="header__menu-item link link--text list-menu__item focus-inset caption-large"
>
<span>{{ childlink.title | escape }}</span>
{{- 'icon-caret.svg' | inline_asset_content -}}
</summary>
<ul
id="HeaderMenu-SubMenuList-{{ link.handle }}-{{ childlink.handle }}-{{ grandchildlink.handle }}"
class="header__submenu list-menu motion-reduce"
>
{%- for grandchildlink in childlink.links -%}
<li>
<a
id="HeaderMenu-{{ link.handle }}-{{ childlink.handle }}-{{ grandchildlink.handle }}"
href="{{ grandchildlink.url }}"
class="header__menu-item list-menu__item link link--text focus-inset caption-large{% if grandchildlink.current %} list-menu__item--active{% endif %}"
{% if grandchildlink.current %}
aria-current="page"
{% endif %}
>
{{ grandchildlink.title | escape }}
</a>
</li>
{%- endfor -%}
</ul>
</details>
{%- endif -%}
</li>
{%- endfor -%}
</ul>
</details>
</header-menu>
{%- else -%}
<a
id="HeaderMenu-{{ link.handle }}"
href="{{ link.url }}"
class="header__menu-item list-menu__item link link--text focus-inset"
{% if link.current %}
aria-current="page"
{% endif %}
>
<span
{%- if link.current %}
class="header__active-menu-item"
{% endif %}
>
{{- link.title | escape -}}
</span>
</a>
{%- endif -%}
</li>
{%- endfor -%}
</ul>
</nav>
+94
View File
@@ -0,0 +1,94 @@
{% comment %}
Renders a megamenu for the header.
Usage:
{% render 'header-mega-menu' %}
{% endcomment %}
<nav class="header__inline-menu">
<ul class="list-menu list-menu--inline" role="list">
{%- for link in section.settings.menu.links -%}
<li>
{%- if link.links != blank -%}
<header-menu>
<details id="Details-HeaderMenu-{{ forloop.index }}" class="mega-menu">
<summary
id="HeaderMenu-{{ link.handle }}"
class="header__menu-item list-menu__item link focus-inset"
>
<span
{%- if link.child_active %}
class="header__active-menu-item"
{% endif %}
>
{{- link.title | escape -}}
</span>
{{- 'icon-caret.svg' | inline_asset_content -}}
</summary>
<div
id="MegaMenu-Content-{{ forloop.index }}"
class="mega-menu__content color-{{ section.settings.menu_color_scheme }} gradient motion-reduce global-settings-popup"
tabindex="-1"
>
<ul
class="mega-menu__list page-width{% if link.levels == 1 %} mega-menu__list--condensed{% endif %}"
role="list"
>
{%- for childlink in link.links -%}
<li>
<a
id="HeaderMenu-{{ link.handle }}-{{ childlink.handle }}"
href="{{ childlink.url }}"
class="mega-menu__link mega-menu__link--level-2 link{% if childlink.current %} mega-menu__link--active{% endif %}"
{% if childlink.current %}
aria-current="page"
{% endif %}
>
{{ childlink.title | escape }}
</a>
{%- if childlink.links != blank -%}
<ul class="list-unstyled" role="list">
{%- for grandchildlink in childlink.links -%}
<li>
<a
id="HeaderMenu-{{ link.handle }}-{{ childlink.handle }}-{{ grandchildlink.handle }}"
href="{{ grandchildlink.url }}"
class="mega-menu__link link{% if grandchildlink.current %} mega-menu__link--active{% endif %}"
{% if grandchildlink.current %}
aria-current="page"
{% endif %}
>
{{ grandchildlink.title | escape }}
</a>
</li>
{%- endfor -%}
</ul>
{%- endif -%}
</li>
{%- endfor -%}
</ul>
</div>
</details>
</header-menu>
{%- else -%}
<a
id="HeaderMenu-{{ link.handle }}"
href="{{ link.url }}"
class="header__menu-item list-menu__item link link--text focus-inset"
{% if link.current %}
aria-current="page"
{% endif %}
>
<span
{%- if link.current %}
class="header__active-menu-item"
{% endif %}
>
{{- link.title | escape -}}
</span>
</a>
{%- endif -%}
</li>
{%- endfor -%}
</ul>
</nav>
+108
View File
@@ -0,0 +1,108 @@
{% comment %}
Renders a header search modal. Should be used with 'header.liquid'
Accepts:
- input_id: {String} Id for the search input element (required)
Usage:
{% render 'header-search', input_id: 'My-Id'%}
{% endcomment %}
<details-modal class="header__search">
<details>
<summary
class="header__icon header__icon--search header__icon--summary link focus-inset modal__toggle"
aria-haspopup="dialog"
aria-label="{{ 'general.search.search' | t }}"
>
<span>
<span class="svg-wrapper">
{{- 'icon-search.svg' | inline_asset_content -}}
</span>
<span class="svg-wrapper header__icon-close">
{{- 'icon-close.svg' | inline_asset_content -}}
</span>
</span>
</summary>
<div
class="search-modal modal__content gradient"
role="dialog"
aria-modal="true"
aria-label="{{ 'general.search.search' | t }}"
>
<div class="modal-overlay"></div>
<div
class="search-modal__content{% if settings.inputs_shadow_vertical_offset != 0 and settings.inputs_shadow_vertical_offset < 0 %} search-modal__content-top{% else %} search-modal__content-bottom{% endif %}"
tabindex="-1"
>
{%- if settings.predictive_search_enabled -%}
<predictive-search class="search-modal__form" data-loading-text="{{ 'accessibility.loading' | t }}">
{%- else -%}
<search-form class="search-modal__form">
{%- endif -%}
<form action="{{ routes.search_url }}" method="get" role="search" class="search search-modal__form">
<div class="field">
<input
class="search__input field__input"
id="{{ input_id }}"
type="search"
name="q"
value="{{ search.terms | escape }}"
placeholder="{{ 'general.search.search' | t }}"
{%- if settings.predictive_search_enabled -%}
role="combobox"
aria-expanded="false"
aria-owns="predictive-search-results"
aria-controls="predictive-search-results"
aria-haspopup="listbox"
aria-autocomplete="list"
autocorrect="off"
autocomplete="off"
autocapitalize="off"
spellcheck="false"
{%- endif -%}
>
<label class="field__label" for="{{ input_id }}">{{ 'general.search.search' | t }}</label>
<input type="hidden" name="options[prefix]" value="last">
<button
type="reset"
class="reset__button field__button{% if search.terms == blank %} hidden{% endif %}"
aria-label="{{ 'general.search.reset' | t }}"
>
<span class="svg-wrapper">
{{- 'icon-reset.svg' | inline_asset_content -}}
</span>
</button>
<button class="search__button field__button" aria-label="{{ 'general.search.search' | t }}">
<span class="svg-wrapper">
{{- 'icon-search.svg' | inline_asset_content -}}
</span>
</button>
</div>
{%- if settings.predictive_search_enabled -%}
<div class="predictive-search predictive-search--header" tabindex="-1" data-predictive-search>
{%- render 'loading-spinner', class: 'predictive-search__loading-state' -%}
</div>
<span class="predictive-search-status visually-hidden" role="status" aria-hidden="true"></span>
{%- endif -%}
</form>
{%- if settings.predictive_search_enabled -%}
</predictive-search>
{%- else -%}
</search-form>
{%- endif -%}
<button
type="button"
class="search-modal__close-button modal__close-button link link--text focus-inset"
aria-label="{{ 'accessibility.close' | t }}"
>
<span class="svg-wrapper">
{{- 'icon-close.svg' | inline_asset_content -}}
</span>
</button>
</div>
</div>
</details>
</details-modal>
+4
View File
@@ -0,0 +1,4 @@
{%- if icon != 'none' -%}
{%- assign file = icon | replace: '_', '-' | prepend: 'icon-' | append: '.svg' -%}
<span class="svg-wrapper">{{ file | inline_asset_content }}</span>
{%- endif -%}
+109
View File
@@ -0,0 +1,109 @@
{% comment %}
Renders icon with text block
Accepts:
- block: {Object} passes in the block information.
Usage:
{% render 'icon-with-text',
block: block
%}
{% endcomment %}
{%- liquid
assign heading_1_empty = false
assign heading_2_empty = false
assign heading_3_empty = false
assign text_only_all_items = true
if block.settings.heading_1 == empty
assign heading_1_empty = true
endif
if block.settings.heading_2 == empty
assign heading_2_empty = true
endif
if block.settings.heading_3 == empty
assign heading_3_empty = true
endif
if heading_1_empty == false and block.settings.icon_1 != 'none' or block.settings.image_1 != null
assign text_only_all_items = false
elsif heading_2_empty == false and block.settings.icon_2 != 'none' or block.settings.image_2 != null
assign text_only_all_items = false
elsif heading_3_empty == false and block.settings.icon_3 != 'none' or block.settings.image_3 != null
assign text_only_all_items = false
endif
-%}
<ul
class="icon-with-text icon-with-text--{{ block.settings.layout }} list-unstyled{% if text_only_all_items %} icon-with-text--text-only{% endif %}"
{{ block.shopify_attributes }}
>
{%- unless heading_1_empty -%}
<li class="icon-with-text__item">
{%- if block.settings.image_1 == null -%}
{%- render 'icon-accordion', icon: block.settings.icon_1 -%}
{%- else -%}
<img
src="{{ block.settings.image_1 | image_url }}"
{% if block.settings.image_1.alt != blank %}
alt="{{ block.settings.image_1.alt | escape }}"
{% else %}
role="presentation"
{% endif %}
height="auto"
width="auto"
loading="lazy"
>
{%- endif -%}
<span class="h4 inline-richtext">
{{- block.settings.heading_1 -}}
</span>
</li>
{%- endunless -%}
{%- unless heading_2_empty -%}
<li class="icon-with-text__item">
{%- if block.settings.image_2 == null -%}
{% render 'icon-accordion', icon: block.settings.icon_2 -%}
{%- else -%}
<img
src="{{ block.settings.image_2 | image_url }}"
{% if block.settings.image_2.alt != blank %}
alt="{{ block.settings.image_2.alt | escape }}"
{% else %}
role="presentation"
{% endif %}
height="auto"
width="auto"
loading="lazy"
>
{%- endif -%}
<span class="h4 inline-richtext">
{{- block.settings.heading_2 -}}
</span>
</li>
{%- endunless -%}
{%- unless heading_3_empty -%}
<li class="icon-with-text__item">
{%- if block.settings.image_3 == null -%}
{% render 'icon-accordion', icon: block.settings.icon_3 -%}
{%- else -%}
<img
src="{{ block.settings.image_3 | image_url }}"
{% if block.settings.image_3.alt != blank %}
alt="{{ block.settings.image_3.alt | escape }}"
{% else %}
role="presentation"
{% endif %}
height="auto"
width="auto"
loading="lazy"
>
{%- endif -%}
<span class="h4 inline-richtext">
{{- block.settings.heading_3 -}}
</span>
</li>
{%- endunless -%}
</ul>
+49
View File
@@ -0,0 +1,49 @@
{%- comment -%}
Renders the language picker for the localization form
Accepts:
- localPosition: pass in the position in which the form is coming up to create specific IDs
{%- endcomment -%}
<div class="disclosure">
<button
type="button"
class="disclosure__button localization-form__select localization-selector link link--text caption-large"
aria-expanded="false"
aria-controls="{{ localPosition }}List"
aria-describedby="{{ localPosition }}Label"
>
<span>{{ localization.language.endonym_name | capitalize }}</span>
{{ 'icon-caret.svg' | inline_asset_content }}
</button>
<div class="disclosure__list-wrapper language-selector" hidden>
<ul id="{{ localPosition }}List" role="list" class="disclosure__list list-unstyled">
{%- for language in localization.available_languages -%}
<li class="disclosure__item" tabindex="-1">
<a
class="link link--text disclosure__link caption-large focus-inset"
href="#"
hreflang="{{ language.iso_code }}"
lang="{{ language.iso_code }}"
{% if language.iso_code == localization.language.iso_code %}
aria-current="true"
{% endif %}
data-value="{{ language.iso_code }}"
>
<span
{% if language.iso_code != localization.language.iso_code %}
class="visibility-hidden"
{% endif %}
>
{{- 'icon-checkmark.svg' | inline_asset_content -}}
</span>
<span>
{{ language.endonym_name | capitalize }}
</span>
</a>
</li>
{%- endfor -%}
</ul>
</div>
</div>
<input type="hidden" name="locale_code" value="{{ localization.language.iso_code }}">
+12
View File
@@ -0,0 +1,12 @@
{% comment %}
Renders loading-spinner.
Accepts:
- class: {string} css classes to replace the default ones (optional)
Usage:
{% render 'loading-spinner' %}
{% endcomment %}
<div class="{% if class %}{{ class }}{% else %}loading__spinner hidden{% endif %}">
{{ 'loading-spinner.svg' | inline_asset_content }}
</div>
+39
View File
@@ -0,0 +1,39 @@
{%- liquid
assign og_title = page_title | default: shop.name
assign og_url = canonical_url | default: request.origin
assign og_type = 'website'
assign og_description = page_description | default: shop.description | default: shop.name
if request.page_type == 'product'
assign og_type = 'product'
elsif request.page_type == 'article'
assign og_type = 'article'
elsif request.page_type == 'password'
assign og_url = request.origin
endif
%}
<meta property="og:site_name" content="{{ shop.name }}">
<meta property="og:url" content="{{ og_url }}">
<meta property="og:title" content="{{ og_title | escape }}">
<meta property="og:type" content="{{ og_type }}">
<meta property="og:description" content="{{ og_description | escape }}">
{%- if page_image -%}
<meta property="og:image" content="http:{{ page_image | image_url }}">
<meta property="og:image:secure_url" content="https:{{ page_image | image_url }}">
<meta property="og:image:width" content="{{ page_image.width }}">
<meta property="og:image:height" content="{{ page_image.height }}">
{%- endif -%}
{%- if request.page_type == 'product' -%}
<meta property="og:price:amount" content="{{ product.price | money_without_currency | strip_html }}">
<meta property="og:price:currency" content="{{ cart.currency.iso_code }}">
{%- endif -%}
{%- if settings.social_twitter_link != blank -%}
<meta name="twitter:site" content="{{ settings.social_twitter_link | split: 'twitter.com/' | last | prepend: '@' }}">
{%- endif -%}
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ og_title | escape }}">
<meta name="twitter:description" content="{{ og_description | escape }}">
+78
View File
@@ -0,0 +1,78 @@
{% comment %}
Renders a set of links for paginated results. Must be used within paginate tags.
Usage:
{% paginate results by 2 %}
{% render 'pagination', paginate: paginate, anchor: '#yourID' %}
{% endpaginate %}
Accepts:
- paginate: {Object}
- anchor: {String} (optional) This can be added so that on page reload it takes you to wherever you've placed your anchor tag.
{% endcomment %}
{{ 'component-pagination.css' | asset_url | stylesheet_tag }}
{%- if paginate.parts.size > 0 -%}
<div class="pagination-wrapper" data-page="{{ paginate.current_page }}">
<nav class="pagination" role="navigation" aria-label="{{ 'general.pagination.label' | t }}">
<ul class="pagination__list list-unstyled" role="list">
{%- if paginate.previous -%}
<li>
<a
href="{{ paginate.previous.url }}{{ anchor }}"
class="pagination__item pagination__item--next pagination__item-arrow link motion-reduce"
aria-label="{{ 'general.pagination.previous' | t }}"
>
<span class="svg-wrapper">
{{- 'icon-caret.svg' | inline_asset_content -}}
</span>
</a>
</li>
{%- endif -%}
{%- for part in paginate.parts -%}
<li>
{%- if part.is_link -%}
<a
href="{{ part.url }}{{ anchor }}"
class="pagination__item link"
aria-label="{{ 'general.pagination.page' | t: number: part.title }}"
>
{{- part.title -}}
</a>
{%- else -%}
{%- if part.title == paginate.current_page -%}
<a
role="link"
aria-disabled="true"
class="pagination__item pagination__item--current light"
aria-current="page"
aria-label="{{ 'general.pagination.page' | t: number: part.title }}"
>
{{- part.title -}}
</a>
{%- else -%}
<span class="pagination__item">{{ part.title }}</span>
{%- endif -%}
{%- endif -%}
</li>
{%- endfor -%}
{%- if paginate.next -%}
<li>
<a
href="{{ paginate.next.url }}{{ anchor }}"
class="pagination__item pagination__item--prev pagination__item-arrow link motion-reduce"
aria-label="{{ 'general.pagination.next' | t }}"
>
<span class="svg-wrapper">
{{- 'icon-caret.svg' | inline_asset_content -}}
</span>
</a>
</li>
{%- endif -%}
</ul>
</nav>
</div>
{%- endif -%}
+45
View File
@@ -0,0 +1,45 @@
<span class="field-currency">{{ cart.currency.symbol }}</span>
<div class="field">
<input
class="field__input"
name="{{ filter.min_value.param_name }}"
id="{{ id_prefix }}{{ filter.label | escape }}-GTE"
{%- if filter.min_value.value -%}
value="{{ filter.min_value.value | money_without_currency }}"
{%- endif -%}
type="text"
inputmode="decimal"
placeholder="0"
data-pattern="\d| |,|\."
data-min="0"
data-max="{{ filter.range_max | money_without_currency }}"
>
<label class="field__label" for="{{ id_prefix }}{{ filter.label | escape }}-GTE">
{{- 'products.facets.from' | t -}}
</label>
</div>
{%- if filter_type != 'vertical' -%}
<span class="field-currency">{{ cart.currency.symbol }}</span>
{%- endif -%}
<div class="field">
<input
class="field__input"
name="{{ filter.max_value.param_name }}"
id="{{ id_prefix }}{{ filter.label | escape }}-LTE"
{%- if filter.max_value.value -%}
value="{{ filter.max_value.value | money_without_currency }}"
{%- endif -%}
type="text"
inputmode="decimal"
placeholder="{{ filter.range_max | money_without_currency }}"
data-pattern="\d| |,|\."
data-min="0"
data-max="{{ filter.range_max | money_without_currency }}"
>
<label class="field__label" for="{{ id_prefix }}{{ filter.label | escape }}-LTE">
{{- 'products.facets.to' | t -}}
</label>
</div>
+125
View File
@@ -0,0 +1,125 @@
{% comment %}
Renders a list of product's price (regular, sale)
Accepts:
- product: {Object} Product Liquid object (optional)
- placeholder: {Boolean} Renders a placeholder price (optional)
- use_variant: {Boolean} Renders selected or first variant price instead of overall product pricing (optional)
- show_badges: {Boolean} Renders 'Sale' and 'Sold Out' tags if the product matches the condition (optional)
- price_class: {String} Adds a price class to the price element (optional)
- show_compare_at_price: {Boolean} Renders the compare at price if the product matches the condition (optional)
Usage:
{% render 'price', product: product %}
{% endcomment %}
{%- liquid
if use_variant
assign target = product.selected_or_first_available_variant
elsif placeholder
assign target = null
else
assign target = product
endif
assign compare_at_price = target.compare_at_price
assign price = target.price | default: 1999
assign price_min = product.price_min
assign price_max = product.price_max
assign available = target.available | default: false
assign money_price = price | money
assign money_price_min = price_min | money
assign money_price_max = price_max | money
if settings.currency_code_enabled
assign money_price = price | money_with_currency
assign money_price_min = price_min | money_with_currency
assign money_price_max = price_max | money_with_currency
endif
if target == product and product.price_varies
assign money_price = 'products.product.price.from_price_html' | t: price: money_price
endif
-%}
{%- unless target == null and placeholder == null -%}
<div
class="
price
{%- if price_class %} {{ price_class }}{% endif -%}
{%- if available == false %} price--sold-out{% endif -%}
{%- if compare_at_price > price and product.quantity_price_breaks_configured? != true %} price--on-sale{% endif -%}
{%- if compare_at_price > price and product.quantity_price_breaks_configured? %} volume-pricing--sale-badge{% endif -%}
{%- if product.price_varies == false and product.compare_at_price_varies %} price--no-compare{% endif -%}
{%- if show_badges %} price--show-badge{% endif -%}
"
>
<div class="price__container">
{%- comment -%}
Explanation of description list:
- div.price__regular: Displayed when there are no variants on sale
- div.price__sale: Displayed when a variant is a sale
{%- endcomment -%}
<div class="price__regular">
{%- if product.quantity_price_breaks_configured? -%}
{%- if show_compare_at_price and compare_at_price -%}
{%- unless product.price_varies == false and product.compare_at_price_varies %}
<span class="visually-hidden visually-hidden--inline">
{{- 'products.product.price.regular_price' | t -}}
</span>
<span>
<s class="price-item price-item--regular variant-item__old-price">
{% if settings.currency_code_enabled %}
{{ compare_at_price | money_with_currency }}
{% else %}
{{ compare_at_price | money }}
{% endif %}
</s>
</span>
{%- endunless -%}
{%- endif -%}
<span class="visually-hidden visually-hidden--inline">{{ 'products.product.price.regular_price' | t }}</span>
<span class="price-item price-item--regular">
{{-
'products.product.volume_pricing.price_range'
| t: minimum: money_price_min, maximum: money_price_max
-}}
</span>
{%- else -%}
<span class="visually-hidden visually-hidden--inline">{{ 'products.product.price.regular_price' | t }}</span>
<span class="price-item price-item--regular">
{{ money_price }}
</span>
{%- endif -%}
</div>
<div class="price__sale">
{%- unless product.price_varies == false and product.compare_at_price_varies %}
<span class="visually-hidden visually-hidden--inline">{{ 'products.product.price.regular_price' | t }}</span>
<span>
<s class="price-item price-item--regular">
{% if settings.currency_code_enabled %}
{{ compare_at_price | money_with_currency }}
{% else %}
{{ compare_at_price | money }}
{% endif %}
</s>
</span>
{%- endunless -%}
<span class="visually-hidden visually-hidden--inline">{{ 'products.product.price.sale_price' | t }}</span>
<span class="price-item price-item--sale price-item--last">
{{ money_price }}
</span>
</div>
{%- if product.selected_or_first_available_variant.unit_price_measurement -%}
{% render 'unit-price', price: product.selected_or_first_available_variant.unit_price, measurement: product.selected_or_first_available_variant.unit_price_measurement %}
{%- endif -%}
</div>
{%- if show_badges -%}
<span class="badge price__badge-sale color-{{ settings.sale_badge_color_scheme }}">
{{ 'products.product.on_sale' | t }}
</span>
<span class="badge price__badge-sold-out color-{{ settings.sold_out_badge_color_scheme }}">
{{ 'products.product.sold_out' | t }}
</span>
{%- endif -%}
</div>
{% endunless %}
+108
View File
@@ -0,0 +1,108 @@
{%- assign disclosure_surface = surface | default: 'product_page' -%}
{%- assign disclosures = product.metafields.shopify.disclosure.value -%}
{%- assign summary_html = '' -%}
{%- assign details_html = '' -%}
{%- assign rendered_disclosures_count = 0 -%}
{%- if disclosures != blank -%}
{%- for disclosure in disclosures -%}
{%- assign surfaces = disclosure.display_preferences.value.surfaces -%}
{%- if surfaces contains disclosure_surface -%}
{%- assign title = disclosure.title.value -%}
{%- assign img = disclosure.symbol.value -%}
{%- assign content = disclosure.content -%}
{%- capture summary_item -%}
{%- if rendered_disclosures_count > 0 -%}
<span class="disclosures-separator">&bull;</span>
{%- endif -%}
<span class="disclosures-summary-item">
{%- if img != blank -%}
<img
src="{{ img | image_url: width: 40 }}"
srcset="{{ img | image_url: width: 20 }} 1x, {{ img | image_url: width: 40 }} 2x, {{ img | image_url: width: 60 }} 3x"
alt=""
class="disclosures__icon"
width="40"
height="31"
loading="lazy"
>
{%- endif -%}
<span class="disclosures-summary-item__title">{{ title }}</span>
<span class="disclosures-summary-item__open-title">{{ title }}</span>
</span>
{%- endcapture -%}
{%- capture details_item -%}
<div class="disclosures-item">
{%- if rendered_disclosures_count > 0 -%}
{%- if title != blank or img != blank -%}
<div class="disclosures-item__header">
{%- if img != blank -%}
<img
src="{{ img | image_url: width: 40 }}"
srcset="{{ img | image_url: width: 20 }} 1x, {{ img | image_url: width: 40 }} 2x, {{ img | image_url: width: 60 }} 3x"
alt=""
class="disclosures__icon"
width="40"
height="31"
loading="lazy"
>
{%- endif -%}
{%- if title != blank -%}
<span>{{ title }}</span>
{%- endif -%}
</div>
{%- endif -%}
{%- endif -%}
<div class="disclosures-item__content">
{{ content | metafield_tag }}
</div>
</div>
{%- endcapture -%}
{%- capture summary_html -%}{{ summary_html }}{{ summary_item }}{%- endcapture -%}
{%- capture details_html -%}{{ details_html }}{{ details_item }}{%- endcapture -%}
{%- assign rendered_disclosures_count = rendered_disclosures_count | plus: 1 -%}
{%- endif -%}
{%- endfor -%}
{%- endif -%}
{%- if rendered_disclosures_count > 0 -%}
{{ 'component-disclosures.css' | asset_url | stylesheet_tag }}
<div
class="disclosures spacing-style"
{% if block != blank %}
{{ block.shopify_attributes }}
{% endif %}
>
{%- if heading != blank -%}
<h3 class="disclosures__heading {{ heading_size }}">
{{ heading | escape }}
</h3>
{%- endif -%}
<details
class="disclosures__details"
{% if open_by_default %}
open
{% endif %}
>
<summary class="disclosures__summary">
<div class="disclosures__summary-content">
{{ summary_html }}
</div>
{{- 'icon-caret.svg' | inline_asset_content -}}
</summary>
<disclosures-content class="disclosures__content">
{{ details_html }}
</disclosures-content>
</details>
</div>
<script src="{{ 'disclosures.js' | asset_url }}" defer="defer"></script>
{%- endif -%}
+332
View File
@@ -0,0 +1,332 @@
{% comment %}
Renders a product media gallery. Should be used with 'media-gallery.js'
Also see 'product-media-modal'
Accepts:
- product: {Object} Product liquid object
- variant_images: {Array} Product images associated with a variant
- limit: {Number} (optional) When passed, limits the number of media items to render
Usage:
{% render 'product-media-gallery' %}
{% endcomment %}
{%- liquid
if section.settings.hide_variants and variant_images.size == product.media.size
assign single_media_visible = true
endif
if limit == 1
assign single_media_visible = true
endif
assign media_count = product.media.size
if section.settings.hide_variants and media_count > 1 and variant_images.size > 0
assign media_count = media_count | minus: variant_images.size | plus: 1
endif
if media_count == 1 or single_media_visible
assign single_media_visible_mobile = true
endif
if media_count == 0 or single_media_visible_mobile or section.settings.mobile_thumbnails == 'show' or section.settings.mobile_thumbnails == 'columns' and media_count < 3
assign hide_mobile_slider = true
endif
if section.settings.media_size == 'large'
assign media_width = 0.65
elsif section.settings.media_size == 'medium'
assign media_width = 0.55
elsif section.settings.media_size == 'small'
assign media_width = 0.45
endif
-%}
<media-gallery
id="MediaGallery-{{ section.id }}"
role="region"
{% if section.settings.enable_sticky_info %}
class="product__column-sticky"
{% 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>
<slider-component id="GalleryViewer-{{ section.id }}" class="slider-mobile-gutter">
<a class="skip-to-content-link button visually-hidden quick-add-hidden" href="#ProductInfo-{{ section.id }}">
{{ 'accessibility.skip_to_product_info' | t }}
</a>
<ul
id="Slider-Gallery-{{ section.id }}"
class="product__media-list contains-media grid grid--peek list-unstyled slider slider--mobile"
role="list"
>
{%- if product.selected_or_first_available_variant.featured_media != null -%}
{%- assign featured_media = product.selected_or_first_available_variant.featured_media -%}
<li
id="Slide-{{ section.id }}-{{ featured_media.id }}"
class="product__media-item grid__item slider__slide is-active{% if single_media_visible %} product__media-item--single{% endif %}{% if featured_media.media_type != 'image' %} product__media-item--full{% endif %}{% if settings.animations_reveal_on_scroll %} scroll-trigger animate--fade-in{% endif %}"
data-media-id="{{ section.id }}-{{ featured_media.id }}"
>
{%- assign media_position = 1 -%}
{% render 'product-thumbnail',
media: featured_media,
media_count: media_count,
position: media_position,
desktop_layout: section.settings.gallery_layout,
mobile_layout: section.settings.mobile_thumbnails,
loop: section.settings.enable_video_looping,
modal_id: section.id,
xr_button: true,
media_width: media_width,
media_fit: section.settings.media_fit,
constrain_to_viewport: section.settings.constrain_to_viewport,
lazy_load: false
%}
</li>
{%- endif -%}
{%- for media in product.media -%}
{% if media_position >= limit
or media_position >= 1
and section.settings.hide_variants
and variant_images contains media.src
%}
{% continue %}
{% endif %}
{%- unless media.id == product.selected_or_first_available_variant.featured_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 product.selected_or_first_available_variant.featured_media == nil and forloop.index == 1 %} is-active{% endif %}{% if media.media_type != 'image' %} product__media-item--full{% endif %}{% if settings.animations_reveal_on_scroll %} scroll-trigger animate--fade-in{% endif %}"
data-media-id="{{ section.id }}-{{ media.id }}"
>
{%- liquid
assign media_position = media_position | default: 0 | plus: 1
assign lazy_load = false
if media_position > 1
assign lazy_load = true
endif
-%}
{% render 'product-thumbnail',
media: media,
media_count: media_count,
position: media_position,
desktop_layout: section.settings.gallery_layout,
mobile_layout: section.settings.mobile_thumbnails,
loop: section.settings.enable_video_looping,
modal_id: section.id,
xr_button: true,
media_width: media_width,
media_fit: section.settings.media_fit,
constrain_to_viewport: section.settings.constrain_to_viewport,
lazy_load: lazy_load
%}
</li>
{%- endunless -%}
{%- endfor -%}
</ul>
<div class="slider-buttons quick-add-hidden{% if hide_mobile_slider %} small-hide{% endif %}">
<button
type="button"
class="slider-button slider-button--prev"
name="previous"
aria-label="{{ 'general.slider.previous_slide' | t }}"
>
<span class="svg-wrapper">
{{- 'icon-caret.svg' | inline_asset_content -}}
</span>
</button>
<div class="slider-counter caption">
<span class="slider-counter--current">1</span>
<span aria-hidden="true"> / </span>
<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--next"
name="next"
aria-label="{{ 'general.slider.next_slide' | t }}"
>
<span class="svg-wrapper">
{{- 'icon-caret.svg' | inline_asset_content -}}
</span>
</button>
</div>
</slider-component>
{%- if first_3d_model -%}
<button
class="button button--full-width product__xr-button"
type="button"
aria-label="{{ 'products.product.xr_button_label' | t }}"
data-shopify-xr
data-shopify-model3d-id="{{ first_3d_model.id }}"
data-shopify-title="{{ product.title | escape }}"
data-shopify-xr-hidden
>
<span class="svg-wrapper">
{{- 'icon-3d-model.svg' | inline_asset_content -}}
</span>
{{ 'products.product.xr_button' | t }}
</button>
{%- endif -%}
{%- liquid
assign is_not_limited_to_single_item = false
if limit == null or limit > 1
assign is_not_limited_to_single_item = true
endif
-%}
{%- if is_not_limited_to_single_item
and media_count > 1
and section.settings.gallery_layout contains 'thumbnail'
or section.settings.mobile_thumbnails == 'show'
-%}
<slider-component
id="GalleryThumbnails-{{ section.id }}"
class="thumbnail-slider slider-mobile-gutter quick-add-hidden{% unless section.settings.gallery_layout contains 'thumbnail' %} medium-hide large-up-hide{% endunless %}{% if section.settings.mobile_thumbnails != 'show' %} small-hide{% endif %}{% if media_count <= 3 %} thumbnail-slider--no-slide{% endif %}"
>
<button
type="button"
class="slider-button slider-button--prev{% if media_count <= 3 %} small-hide{% endif %}{% if media_count <= 4 %} medium-hide large-up-hide{% endif %}"
name="previous"
aria-label="{{ 'general.slider.previous_slide' | t }}"
aria-controls="GalleryThumbnails-{{ section.id }}"
data-step="3"
>
<span class="svg-wrapper">
{{- 'icon-caret.svg' | inline_asset_content -}}
</span>
</button>
<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 %}"
>
{%- 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 - 8rem) / 3)
{%- endcapture -%}
{%- if featured_media != null -%}
{%- liquid
capture media_index
if featured_media.media_type == 'model'
increment model_index
elsif featured_media.media_type == 'video' or featured_media.media_type == 'external_video'
increment video_index
elsif featured_media.media_type == 'image'
increment image_index
endif
endcapture
assign media_index = media_index | plus: 1
-%}
<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 %}"
data-target="{{ section.id }}-{{ featured_media.id }}"
data-media-position="{{ media_index }}"
>
{%- capture thumbnail_id -%}
Thumbnail-{{ section.id }}-0
{%- endcapture -%}
<button
class="thumbnail global-media-settings global-media-settings--no-shadow"
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 }}"
aria-describedby="{{ thumbnail_id }}"
>
{{
featured_media.preview_image
| image_url: width: 416
| image_tag:
loading: 'lazy',
sizes: sizes,
widths: '54, 74, 104, 162, 208, 324, 416',
id: thumbnail_id,
alt: featured_media.alt
| escape
}}
</button>
</li>
{%- endif -%}
{%- for media in product.media -%}
{%- unless media.id == product.selected_or_first_available_variant.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
-%}
<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 %}"
data-target="{{ section.id }}-{{ media.id }}"
data-media-position="{{ media_index }}"
>
{%- if media.media_type == 'model' -%}
<span class="thumbnail__badge" aria-hidden="true">
<span class="svg-wrapper">
{{- 'icon-3d-model.svg' | inline_asset_content -}}
</span>
</span>
{%- elsif media.media_type == 'video' or media.media_type == 'external_video' -%}
<span class="thumbnail__badge" aria-hidden="true">
<span class="svg-wrapper">
{{- 'icon-play.svg' | inline_asset_content -}}
</span>
</span>
{%- endif -%}
{%- capture thumbnail_id -%}
Thumbnail-{{ section.id }}-{{ forloop.index }}
{%- endcapture -%}
<button
class="thumbnail global-media-settings global-media-settings--no-shadow"
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 == product.selected_or_first_available_variant.featured_media
or product.selected_or_first_available_variant.featured_media == null
and forloop.index == 1
%}
aria-current="true"
{% endif %}
aria-controls="GalleryViewer-{{ section.id }}"
aria-describedby="{{ thumbnail_id }}"
>
{{
media.preview_image
| image_url: width: 416
| image_tag:
loading: 'lazy',
sizes: sizes,
widths: '54, 74, 104, 162, 208, 324, 416',
id: thumbnail_id,
alt: media.alt
| escape
}}
</button>
</li>
{%- endunless -%}
{%- endfor -%}
</ul>
<button
type="button"
class="slider-button slider-button--next{% if media_count <= 3 %} small-hide{% endif %}{% if media_count <= 4 %} medium-hide large-up-hide{% endif %}"
name="next"
aria-label="{{ 'general.slider.next_slide' | t }}"
aria-controls="GalleryThumbnails-{{ section.id }}"
data-step="3"
>
<span class="svg-wrapper">
{{- 'icon-caret.svg' | inline_asset_content -}}
</span>
</button>
</slider-component>
{%- endif -%}
</media-gallery>
+57
View File
@@ -0,0 +1,57 @@
{% comment %}
Renders a product media modal. Also see 'product-media-gallery'
Accepts:
- product: {Object} Product liquid object
- variant_images: {Array} Product images associated with a variant
Usage:
{% render 'product-media-modal' %}
{% endcomment %}
<product-modal id="ProductModal-{{ section.id }}" class="product-media-modal media-modal">
<div
class="product-media-modal__dialog color-{{ section.settings.color_scheme }} gradient"
role="dialog"
aria-label="{{ 'products.modal.label' | t }}"
aria-modal="true"
tabindex="-1"
>
<button
id="ModalClose-{{ section.id }}"
type="button"
class="product-media-modal__toggle"
aria-label="{{ 'accessibility.close' | t }}"
>
{{ 'icon-close.svg' | inline_asset_content }}
</button>
<div
class="product-media-modal__content color-{{ section.settings.color_scheme }} gradient"
role="document"
aria-label="{{ 'products.modal.label' | t }}"
tabindex="0"
>
{%- liquid
if product.selected_or_first_available_variant.featured_media != null
assign media = product.selected_or_first_available_variant.featured_media
render 'product-media', media: media, loop: section.settings.enable_video_looping, variant_image: section.settings.hide_variants
endif
-%}
{%- for media in product.media -%}
{%- liquid
if section.settings.hide_variants and variant_images contains media.src or variant_images contains media.id
assign variant_image = true
else
assign variant_image = false
endif
unless media.id == product.selected_or_first_available_variant.featured_media.id
render 'product-media', media: media, loop: section.settings.enable_video_looping, variant_image: variant_image
endunless
-%}
{%- endfor -%}
</div>
</div>
</product-modal>
+120
View File
@@ -0,0 +1,120 @@
{% comment %}
Renders product media
Accepts:
- media: {Object} Product Media object
- loop: {Boolean} Enable video looping (optional)
- variant_image: {Boolean} Whether or not media is associated with a variant
Usage:
{% render 'product-media',
media: media,
loop: section.settings.enable_video_looping,
variant_image: true
%}
{% endcomment %}
{%- if media.media_type == 'image' -%}
<img
class="global-media-settings global-media-settings--no-shadow{% if variant_image %} product__media-item--variant{% endif %}"
srcset="
{%- if media.preview_image.width >= 550 -%}{{ media.preview_image | image_url: width: 550 }} 550w,{%- endif -%}
{%- if media.preview_image.width >= 1100 -%}{{ media.preview_image | image_url: width: 1100 }} 1100w,{%- endif -%}
{%- if media.preview_image.width >= 1445 -%}{{ media.preview_image | image_url: width: 1445 }} 1445w,{%- endif -%}
{%- if media.preview_image.width >= 1680 -%}{{ media.preview_image | image_url: width: 1680 }} 1680w,{%- endif -%}
{%- if media.preview_image.width >= 2048 -%}{{ media.preview_image | image_url: width: 2048 }} 2048w,{%- endif -%}
{%- if media.preview_image.width >= 2200 -%}{{ media.preview_image | image_url: width: 2200 }} 2200w,{%- endif -%}
{%- if media.preview_image.width >= 2890 -%}{{ media.preview_image | image_url: width: 2890 }} 2890w,{%- endif -%}
{%- if media.preview_image.width >= 4096 -%}{{ media.preview_image | image_url: width: 4096 }} 4096w,{%- endif -%}
{{ media.preview_image | image_url }} {{ media.preview_image.width }}w
"
sizes="(min-width: 750px) calc(100vw - 22rem), 1100px"
src="{{ media.preview_image | image_url: width: 1445 }}"
alt="{{ media.alt | escape }}"
loading="lazy"
width="1100"
height="{{ 1100 | divided_by: media.preview_image.aspect_ratio | ceil }}"
data-media-id="{{ media.id }}"
>
{%- else -%}
{%- if media.media_type == 'model' -%}
<div class="product-media-modal__model" data-media-id="{{ media.id }}">
<product-model
class="deferred-media media media--transparent global-media-settings global-media-settings--no-shadow"
style="padding-top: min(calc(100vh - 12rem), 100%)"
>
{%- else -%}
<deferred-media
class="deferred-media media global-media-settings global-media-settings--no-shadow"
style="padding-top: min(calc(100vh - 12rem), {{ 1 | divided_by: media.aspect_ratio | times: 100 }}%)"
data-media-id="{{ media.id }}"
>
{%- endif -%}
<button id="Deferred-Poster-Modal-{{ media.id }}" class="deferred-media__poster" type="button">
<span class="deferred-media__poster-button motion-reduce">
{%- if media.media_type == 'model' -%}
<span class="svg-wrapper">{{ 'icon-3d-model' | inline_asset_content }}</span>
{%- else -%}
<span class="svg-wrapper">{{ 'icon-play.svg' | inline_asset_content }}</span>
{%- endif -%}
</span>
<img
srcset="
{% if media.preview_image.width >= 288 %}{{ media.preview_image | image_url: width: 288 }} 288w,{% endif %}
{% if media.preview_image.width >= 576 %}{{ media.preview_image | image_url: width: 576 }} 576w,{% endif %}
{% if media.preview_image.width >= 550 %}{{ media.preview_image | image_url: width: 550 }} 550w,{% endif %}
{% if media.preview_image.width >= 1100 %}{{ media.preview_image | image_url: width: 1100 }} 1100w,{% endif %}
{{ media.preview_image | image_url }} {{ media.preview_image.width }}w
"
src="{{ media | image_url: width: 550, height: 550 }}"
sizes="(min-width: 1200px) calc((1200px - 10rem) / 2), (min-width: 750px) calc((100vw - 11.5rem) / 2), calc(100vw - 4rem)"
loading="lazy"
width="576"
height="{{ 576 | divided_by: media.preview_image.aspect_ratio }}"
alt="{{ media.preview_image.alt | escape }}"
>
</button>
<template>
{%- case media.media_type -%}
{%- when 'external_video' -%}
{%- assign video_class = 'js-' | append: media.host -%}
{%- if media.host == 'youtube' -%}
{{
media
| external_video_url: autoplay: true, loop: loop, playlist: media.external_id
| external_video_tag: class: video_class, loading: 'lazy'
}}
{%- else -%}
{{
media
| external_video_url: autoplay: true, loop: loop
| external_video_tag: class: video_class, loading: 'lazy'
}}
{%- endif -%}
{%- when 'video' -%}
{{ media | media_tag: image_size: '2048x', autoplay: true, loop: loop, controls: true, preload: 'none' }}
{%- when 'model' -%}
{{ media | media_tag: image_size: '2048x', toggleable: true }}
{%- endcase -%}
</template>
{%- if media.media_type == 'model' -%}
</product-model>
<button
class="button button--full-width product__xr-button"
type="button"
aria-label="{{ 'products.product.xr_button_label' | t }}"
data-shopify-xr
data-shopify-model3d-id="{{ media.id }}"
data-shopify-title="title"
data-shopify-xr-hidden
>
<span class="svg-wrapper">{{ 'icon-3d-model' | inline_asset_content }}</span>
{{ 'products.product.xr_button' | t }}
</button>
</div>
{%- else -%}
</deferred-media>
{%- endif -%}
{%- endif -%}
+172
View File
@@ -0,0 +1,172 @@
{% comment %}theme-check-disable ImgLazyLoading{% endcomment %}
{% comment %}
Renders a product thumbnail with a modal-opener
Accepts:
- media: {Object} Product Media object
- media_count: {Number} Number of media objects
- position: {String} Position of the media. Used for accessible label.
- desktop_layout: {String} Layout of the media for desktop.
- mobile_layout: {String} Layout of the media for mobile.
- loop: {Boolean} Enable video looping (optional)
- modal_id: {String} The product modal that will be shown by clicking the thumbnail
- xr_button: {Boolean} Renders the "View in your space" button (shopify-xr-button) if the media is a 3D Model
- constrain_to_viewport: {Boolean} Force media height to fit within viewport
- media_fit: {String} Method ("contain" or "cover") to fit image into container
- media_width: {Float} The width percentage that the media column occupies on desktop.
- lazy_load: {Boolean} Image should be lazy loaded. Default: true (optional)
Usage:
{% render 'product-thumbnail',
media: media,
position: forloop.index,
loop: section.settings.enable_video_looping,
modal_id: section.id
%}
{% endcomment %}
{%- liquid
unless lazy_load == false
assign lazy = 'lazy'
endunless
assign desktop_columns = 1
if desktop_layout == 'columns' and media_count > 1
assign desktop_columns = 2
endif
assign mobile_columns = 1
if mobile_layout == 'columns' and media_count > 1
assign mobile_columns = 2
endif
if media.media_type == 'image'
assign image_class = 'image-magnify-' | append: section.settings.image_zoom
endif
-%}
{%- capture sizes -%}
(min-width: {{ settings.page_width }}px) {{ settings.page_width | minus: 100 | times: media_width | divided_by: desktop_columns | round }}px, (min-width: 990px) calc({{ media_width | times: 100 | divided_by: desktop_columns }}vw - 10rem), (min-width: 750px) calc((100vw - 11.5rem) / 2), calc(100vw / {{ mobile_columns }} - 4rem)
{%- endcapture -%}
<div
class="product-media-container media-type-{{ media.media_type }} media-fit-{{ media_fit }} global-media-settings gradient{% if constrain_to_viewport %} constrain-height{% endif %}"
style="--ratio: {{ media.aspect_ratio | default: 1.0 }}; --preview-ratio: {{ media.preview_image.aspect_ratio | default: 1.0 }};"
>
<modal-opener
class="product__modal-opener product__modal-opener--{{ media.media_type }}"
data-modal="#ProductModal-{{ modal_id }}"
>
<span
class="product__media-icon motion-reduce quick-add-hidden{% if media.media_type == 'image' %} product__media-icon--{{ section.settings.image_zoom }}{% endif %}"
aria-hidden="true"
>
{% case media.media_type %}
{% when 'video', 'external_video' %}
<span class="svg-wrapper">
{{- 'icon-play.svg' | inline_asset_content -}}
</span>
{% when 'model' %}
<span class="svg-wrapper">
{{- 'icon-3d-model.svg' | inline_asset_content -}}
</span>
{% else %}
<span class="svg-wrapper">
{{- 'icon-zoom.svg' | inline_asset_content -}}
</span>
{% endcase %}
</span>
{%- render 'loading-spinner' -%}
<div class="product__media media media--transparent">
{{
media.preview_image
| image_url: width: 1946
| image_tag:
class: image_class,
loading: lazy,
sizes: sizes,
widths: '246, 493, 600, 713, 823, 990, 1100, 1206, 1346, 1426, 1646, 1946'
}}
</div>
<button
class="product__media-toggle quick-add-hidden product__media-zoom-{{ section.settings.image_zoom }}"
type="button"
aria-haspopup="dialog"
data-media-id="{{ media.id }}"
>
<span class="visually-hidden">
{{ 'products.product.media.open_media' | t: index: position }}
</span>
</button>
</modal-opener>
{%- if media.media_type != 'image' -%}
{%- if media.media_type == 'model' -%}
<product-model class="deferred-media media media--transparent" data-media-id="{{ media.id }}">
{%- else -%}
<deferred-media class="deferred-media media media--transparent" data-media-id="{{ media.id }}">
{%- endif -%}
<button id="Deferred-Poster-Modal-{{ media.id }}" class="deferred-media__poster" type="button">
<span class="deferred-media__poster-button motion-reduce">
{%- if media.media_type == 'model' -%}
<span class="visually-hidden">{{ 'products.product.media.play_model' | t }}</span>
<span class="svg-wrapper">
{{- 'icon-3d-model.svg' | inline_asset_content -}}
</span>
{%- else -%}
<span class="visually-hidden">{{ 'products.product.media.play_video' | t }}</span>
<span class="svg-wrapper">
{{- 'icon-play.svg' | inline_asset_content -}}
</span>
{%- endif -%}
</span>
{{
media.preview_image
| image_url: width: 1946
| image_tag:
loading: lazy,
sizes: sizes,
widths: '246, 493, 600, 713, 823, 990, 1100, 1206, 1346, 1426, 1646, 1946'
}}
</button>
<template>
{%- liquid
case media.media_type
when 'external_video'
assign video_class = 'js-' | append: media.host
if media.host == 'youtube'
echo media | external_video_url: autoplay: true, loop: loop, playlist: media.external_id | external_video_tag: class: video_class, loading: 'lazy'
else
echo media | external_video_url: autoplay: true, loop: loop | external_video_tag: class: video_class, loading: 'lazy'
endif
when 'video'
echo media | media_tag: image_size: '2048x', autoplay: true, loop: loop, controls: true, preload: 'none'
when 'model'
echo media | media_tag: image_size: '2048x', toggleable: true
endcase
-%}
</template>
{%- if media.media_type == 'model' -%}
</product-model>
{%- if xr_button -%}
<button
class="button button--full-width product__xr-button"
type="button"
aria-label="{{ 'products.product.xr_button_label' | t }}"
data-shopify-xr
data-shopify-model3d-id="{{ media.id }}"
data-shopify-title="{{ product.title | escape }}"
data-shopify-xr-hidden
>
<span class="svg-wrapper">
{{- 'icon-3d-model.svg' | inline_asset_content -}}
</span>
{{ 'products.product.xr_button' | t }}
</button>
{%- endif -%}
{%- else -%}
</deferred-media>
{%- endif -%}
{%- endif -%}
</div>
+124
View File
@@ -0,0 +1,124 @@
{% comment %}
Renders product variant options
Accepts:
- product: {Object} product object.
- option: {Object} current product_option object.
- block: {Object} block object.
- picker_type: {String} type of picker to dispay
Usage:
{% render 'product-variant-options',
product: product,
option: option,
block: block
picker_type: picker_type
%}
{% endcomment %}
{%- liquid
assign product_form_id = 'product-form-' | append: section.id
-%}
{%- for value in option.values -%}
{%- liquid
assign swatch_focal_point = null
if value.swatch.image
assign image_url = value.swatch.image | image_url: width: 50
assign swatch_value = 'url(' | append: image_url | append: ')'
assign swatch_focal_point = value.swatch.image.presentation.focal_point
elsif value.swatch.color
assign swatch_value = 'rgb(' | append: value.swatch.color.rgb | append: ')'
else
assign swatch_value = null
endif
assign option_disabled = true
if value.available
assign option_disabled = false
endif
-%}
{%- capture input_id -%}
{{ section.id }}-{{ option.position }}-{{ forloop.index0 -}}
{%- endcapture -%}
{%- capture input_name -%}
{{ option.name }}-{{ option.position }}
{%- endcapture -%}
{%- capture input_dataset -%}
data-product-url="{{ value.product_url }}"
data-option-value-id="{{ value.id }}"
data-option-name="{{ option.name | escape }}"
{%- endcapture -%}
{%- capture label_unavailable -%}
<span class="visually-hidden label-unavailable">
{{- 'products.product.variant_sold_out_or_unavailable' | t -}}
</span>
{%- endcapture -%}
{% assign escaped_value = value | escape %}
{%- if picker_type == 'swatch' -%}
{%- capture help_text -%}
<span class="visually-hidden">{{ escaped_value }}</span>
{{ label_unavailable }}
{%- endcapture -%}
{%
render 'swatch-input',
id: input_id,
name: input_name,
value: escaped_value,
swatch: value.swatch,
product_form_id: product_form_id,
checked: value.selected,
visually_disabled: option_disabled,
shape: block.settings.swatch_shape,
help_text: help_text,
additional_props: input_dataset
%}
{%- elsif picker_type == 'button' -%}
<input
type="radio"
id="{{ input_id }}"
name="{{ input_name | escape }}"
value="{{ escaped_value }}"
form="{{ product_form_id }}"
{% if value.selected %}
checked
{% endif %}
{% if option_disabled %}
class="disabled"
{% endif %}
{{ input_dataset }}
>
<label for="{{ input_id }}">
{{ value -}}
{{ label_unavailable }}
</label>
{%- elsif picker_type == 'dropdown' or picker_type == 'swatch_dropdown' -%}
<option
id="{{ input_id }}"
value="{{ escaped_value }}"
{% if value.selected %}
selected="selected"
{% endif %}
{% if swatch_value and picker_type == 'swatch_dropdown' %}
data-option-swatch-value="{{ swatch_value }}"
{% if swatch_focal_point %}
data-option-swatch-focal-point="{{ swatch_focal_point }}"
{% endif %}
{% endif %}
{{ input_dataset }}
>
{% if option_disabled -%}
{{- 'products.product.value_unavailable' | t: option_value: value -}}
{%- else -%}
{{- value -}}
{%- endif %}
</option>
{%- endif -%}
{%- endfor -%}
+101
View File
@@ -0,0 +1,101 @@
{% comment %}
Renders product variant-picker
Accepts:
- product: {Object} product object.
- block: {Object} passing the block information.
- product_form_id: {String} Id of the product form to which the variant picker is associated.
Usage:
{% render 'product-variant-picker', product: product, block: block, product_form_id: product_form_id %}
{% endcomment %}
{%- unless product.has_only_default_variant -%}
<variant-selects
id="variant-selects-{{ section.id }}"
data-section="{{ section.id }}"
data-product-handle="{{ product.handle }}"
data-product-title="{{ product.title | escape }}"
data-product-id="{{ product.id }}"
data-currency-code="{{ cart.currency.iso_code }}"
{% # theme-check-disable %}
data-selected-price-amount="{{ product.selected_or_first_available_variant.price | default: 0 | money_amount | escape }}"
{% # theme-check-enable %}
{{ block.shopify_attributes }}
>
{%- for option in product.options_with_values -%}
{%- liquid
assign swatch_count = option.values | map: 'swatch' | compact | size
assign picker_type = block.settings.picker_type
if swatch_count > 0 and block.settings.swatch_shape != 'none'
if block.settings.picker_type == 'dropdown'
assign picker_type = 'swatch_dropdown'
else
assign picker_type = 'swatch'
endif
endif
-%}
{%- if picker_type == 'swatch' -%}
<fieldset class="js product-form__input product-form__input--swatch">
<legend class="form__label">
{{ option.name }}:
<span data-selected-value>
{{- option.selected_value -}}
</span>
</legend>
{% render 'product-variant-options',
product: product,
option: option,
block: block,
picker_type: picker_type
%}
</fieldset>
{%- elsif picker_type == 'button' -%}
<fieldset class="js product-form__input product-form__input--pill">
<legend class="form__label">{{ option.name }}</legend>
{% render 'product-variant-options',
product: product,
option: option,
block: block,
picker_type: picker_type
%}
</fieldset>
{%- else -%}
<div class="product-form__input product-form__input--dropdown">
<label class="form__label" for="Option-{{ section.id }}-{{ forloop.index0 }}">
{{ option.name }}
</label>
<div class="select">
{%- if picker_type == 'swatch_dropdown' -%}
<span
data-selected-value
class="dropdown-swatch"
>
{% render 'swatch', swatch: option.selected_value.swatch, shape: block.settings.swatch_shape %}
</span>
{%- endif -%}
<select
id="Option-{{ section.id }}-{{ forloop.index0 }}"
class="select__select"
name="options[{{ option.name | escape }}]"
form="{{ product_form_id }}"
>
{% render 'product-variant-options',
product: product,
option: option,
block: block,
picker_type: picker_type
%}
</select>
<span class="svg-wrapper">
{{- 'icon-caret.svg' | inline_asset_content -}}
</span>
</div>
</div>
{%- endif -%}
{%- endfor -%}
<script type="application/json" data-selected-variant>
{{ product.selected_or_first_available_variant | json }}
</script>
</variant-selects>
{%- endunless -%}
+5
View File
@@ -0,0 +1,5 @@
<div class="progress-bar-container hidden">
<div class="progress-bar">
<div class="progress-bar-value"></div>
</div>
</div>
+47
View File
@@ -0,0 +1,47 @@
{% comment %}
Quantity input
Accepts:
- variant: {Object} Variant object
- variant_id: {String} Variant ID (optional)
- min: {Number} Min (optional)
Usage:
{% render 'quantity-input' variant: variant %}
{% endcomment %}
<quantity-input class="quantity cart-quantity">
<button class="quantity__button" name="minus" type="button" data-target="decrement-{{ variant.id }}">
<span class="visually-hidden">
{{- 'products.product.quantity.decrease' | t: product: variant.title | escape -}}
</span>
<span class="svg-wrapper">{{ 'icon-minus.svg' | inline_asset_content }}</span>
</button>
<input
class="quantity__input"
data-quantity-variant-id="{{ variant.id }}"
type="number"
name="updates[{{ variant_id }}]"
{% # theme-check-disable %}
value="{{ cart | item_count_for_variant: variant.id }}"
data-cart-quantity="{{ cart | item_count_for_variant: variant.id }}"
min="{{ min }}"
data-min="{{ variant.quantity_rule.min }}"
{% if variant.quantity_rule.max != null %}
max="{{ variant.quantity_rule.max }}"
{% endif %}
step="{{ variant.quantity_rule.increment }}"
{% # theme-check-enable %}
aria-label="{{ 'products.product.quantity.input_label' | t: product: variant.title | escape }}"
id="Quantity-{{ variant.id }}"
data-index="{{ variant.id }}"
data-target="quantity-input-{{ variant.id }}"
>
<button class="quantity__button" name="plus" type="button" data-target="increment-{{ variant.id }}">
<span class="visually-hidden">
{{- 'products.product.quantity.increase' | t: product: variant.title | escape -}}
</span>
<span class="svg-wrapper">{{ 'icon-plus.svg' | inline_asset_content }}</span>
</button>
{%- render 'progress-bar' -%}
</quantity-input>
+453
View File
@@ -0,0 +1,453 @@
{% comment %}
Variant List Row
Accepts:
- item: {Object} Variant or Product object
- sku: {String} Sku of Product or Variant (optional)
- image: {Object} Product or Variant image (optional)
Usage:
{% render 'quick-order-list-row' variant: variant %}
{% endcomment %}
{% # theme-check-disable %}
{% assign cart_qty = cart | item_count_for_variant: variant.id %}
{% # theme-check-enable %}
<tr
class="variant-item{% unless show_image %} variant-item--no-media{% endunless %}{% if item.available and item.unit_price_measurement %} variant-item--unit-price{% endif %}"
id="Variant-{{ variant.id }}"
data-variant-id="{{ variant.id }}"
>
<td class="variant-item__inner{% unless sku and show_sku %} variant-item__inner--no-sku{% endunless %}">
{%- if show_image -%}
<div class="variant-item__media">
<div class="variant-item__image-container global-media-settings{% unless is_modal %} gradient{% endunless %}{% unless image %} variant-item__image-container--no-img{% endunless %}">
{% if image %}
{%- assign img_height = 43 | divided_by: image.aspect_ratio | ceil -%}
{{
image
| image_url: width: 86
| image_tag:
loading: 'lazy',
fetchpriority: 'low',
decoding: 'async',
class: 'variant-item__image',
width: 43,
height: img_height,
widths: '86',
alt: image.alt
| escape
}}
{% endif %}
</div>
</div>
{%- endif -%}
<div class="small-hide medium-hide">
<span class="variant-item__name h4 break">{{ item.title | escape }}</span>
{%- if show_sku -%}
<span class="variant-item__sku break">{{ sku | escape }}</span>
{%- endif -%}
</div>
</td>
<td class="variant-item__details large-up-hide">
<div class="variant-item__info">
<span class="variant-item__name h4 break">{{ item.title | escape }}</span>
{%- if show_sku -%}
<span class="variant-item__sku break">{{ sku | escape }}</span>
{%- endif -%}
</div>
{%- assign item_price = item.price | money -%}
{%- if item.compare_at_price -%}
<dl class="variant-item__discounted-prices">
<dt class="visually-hidden">
{{ 'products.product.price.regular_price' | t }}
</dt>
<dd>
<s class="variant-item__old-price price price--end">
{{ item.compare_at_price | money }}
</s>
</dd>
<dt class="visually-hidden">
{{ 'products.product.price.sale_price' | t }}
</dt>
<dd class="price">
{%- if variant.quantity_price_breaks.size > 0 -%}
{%- liquid
assign volume_pricing_array = variant.quantity_price_breaks | sort: 'quantity' | reverse
-%}
<price-per-item
class="variant-item__price-per-item"
id="Price-Per-Item-{{ variant.id }}"
data-variant-id="{{ variant.id }}"
>
<div class="price-per-item">
{%- if cart_qty < volume_pricing_array.last.minimum_quantity -%}
{%- assign variant_price = variant.price | money -%}
<span class="price-per-item--current price">
{{- 'sections.quick_order_list.each' | t: money: variant_price -}}
</span>
{%- else -%}
{%- for price_break in volume_pricing_array -%}
{%- if cart_qty >= price_break.minimum_quantity -%}
{%- assign price_break_price = price_break.price | money -%}
<span class="price-per-item--current price">
{{- 'sections.quick_order_list.each' | t: money: price_break_price -}}
</span>
{%- break -%}
{%- endif -%}
{%- endfor -%}
{%- endif -%}
</div>
</price-per-item>
{%- else -%}
<span class="price">
{{- 'sections.quick_order_list.each' | t: money: item_price -}}
</span>
{%- endif -%}
</dd>
</dl>
{%- else -%}
{%- if variant.quantity_price_breaks.size > 0 -%}
{%- liquid
assign volume_pricing_array = variant.quantity_price_breaks | sort: 'quantity' | reverse
-%}
<price-per-item
class="variant-item__price-per-item"
id="Price-Per-Item-{{ variant.id }}"
data-variant-id="{{ variant.id }}"
>
<div class="price-per-item">
{%- if cart_qty < volume_pricing_array.last.minimum_quantity -%}
{%- assign variant_price = variant.price | money -%}
<span class="price-per-item--current price">
{{- 'sections.quick_order_list.each' | t: money: variant_price -}}
</span>
{%- else -%}
{%- for price_break in volume_pricing_array -%}
{%- if cart_qty >= price_break.minimum_quantity -%}
{%- assign price_break_price = price_break.price | money -%}
<span class="price-per-item--current price">
{{- 'sections.quick_order_list.each' | t: money: price_break_price -}}
</span>
{%- break -%}
{%- endif -%}
{%- endfor -%}
{%- endif -%}
</div>
</price-per-item>
{%- else -%}
<span class="price">
{{- 'sections.quick_order_list.each' | t: money: item_price -}}
</span>
{%- endif -%}
{%- endif -%}
{%- if item.available and item.unit_price_measurement -%}
{% render 'unit-price', price: item.unit_price, measurement: item.unit_price_measurement %}
{%- endif -%}
</td>
<td class="variant-item__totals right large-up-hide">
{%- render 'loading-spinner' -%}
{% comment %} TODO: enable theme-check once `line_items_for` is accepted as valid filter {% endcomment %}
{% # theme-check-disable %}
<span class="price">{{ cart | line_items_for: item | sum: 'original_line_price' | money }}</span>
{% # theme-check-enable %}
</td>
<td class="variant-item__quantity">
{%- liquid
assign check_against_inventory = true
if variant.inventory_management != 'shopify' or variant.inventory_policy == 'continue'
assign check_against_inventory = false
endif
if variant.quantity_rule.min > variant.inventory_quantity and check_against_inventory
assign quantity_rule_soldout = true
endif
assign has_qty_rules = false
if variant.quantity_rule.increment > 1 or variant.quantity_rule.min > 1 or variant.quantity_rule.max != null
assign has_qty_rules = true
endif
assign has_vol_pricing = false
if variant.quantity_price_breaks.size > 0
assign has_vol_pricing = true
endif
assign is_available = false
assign has_popover = false
unless variant.available == false or quantity_rule_soldout
assign is_available = true
endunless
if has_qty_rules or has_vol_pricing
assign has_popover = true
endif
-%}
<quantity-popover>
<div class="variant-item__quantity-wrapper quantity-popover-wrapper{% unless has_popover %} variant-item__quantity-wrapper--no-info{% endunless %}">
<label class="visually-hidden" for="Quantity-{{ variant.id }}">
{{ 'products.product.quantity.label' | t }}
</label>
<div class="quantity-popover-container{% if is_available and has_popover %} quantity-popover-container--hover{% endif %}{% if cart_qty == 0 %} quantity-popover-container--empty{% endif %}">
{%- if has_qty_rules or has_vol_pricing -%}
<button
type="button"
aria-expanded="false"
aria-controls="quantity-popover-info-{{ variant.id }}"
aria-label="
{%- if has_vol_pricing -%}
{{ 'products.product.volume_pricing.note' | t }}
{%- elsif has_qty_rules -%}
{{ 'products.product.quantity.note' | t }}
{%- endif -%}
"
class="quantity-popover__info-button quantity-popover__info-button--icon-only button button--tertiary small-hide medium-hide no-js-hidden"
>
{{- 'icon-info.svg' | inline_asset_content -}}
</button>
<div
class="global-settings-popup quantity-popover__info"
tabindex="-1"
hidden
id="quantity-popover-info-{{ variant.id }}"
>
{%- if has_qty_rules == false -%}
<span class="volume-pricing-label caption">{{ 'products.product.volume_pricing.title' | t }}</span>
{%- endif -%}
<div class="quantity__rules caption no-js-hidden">
{%- if variant.quantity_rule.increment > 1 -%}
<span class="divider">
{{- 'products.product.quantity.multiples_of' | t: quantity: variant.quantity_rule.increment -}}
</span>
{%- endif -%}
{%- if variant.quantity_rule.min > 1 -%}
<span class="divider">
{{- 'products.product.quantity.min_of' | t: quantity: variant.quantity_rule.min -}}
</span>
{%- endif -%}
{%- if variant.quantity_rule.max != null -%}
<span class="divider">
{{- 'products.product.quantity.max_of' | t: quantity: variant.quantity_rule.max -}}
</span>
{%- endif -%}
</div>
<button
class="button-close button button--tertiary large-up-hide"
type="button"
aria-label="{{ 'accessibility.close' | t }}"
>
{{- 'icon-close.svg' | inline_asset_content -}}
</button>
{%- if variant.quantity_price_breaks.size > 0 -%}
<volume-pricing class="parent-display">
<ul class="list-unstyled">
<li>
<span>{{ variant.quantity_rule.min }}+</span>
{%- assign price = variant.price | money_with_currency -%}
<span>{{ 'sections.quick_order_list.each' | t: money: price }}</span>
</li>
{%- for price_break in variant.quantity_price_breaks -%}
<li>
<span>
{{- price_break.minimum_quantity -}}
<span aria-hidden="true">+</span></span
>
{%- assign price = price_break.price | money_with_currency -%}
<span> {{ 'sections.quick_order_list.each' | t: money: price }}</span>
</li>
{%- endfor -%}
</ul>
</volume-pricing>
{%- endif -%}
</div>
{%- endif -%}
{%- if variant.available == false or quantity_rule_soldout -%}
<span class="variant-item__sold-out"> {{ 'products.product.sold_out' | t }} </span>
{%- else -%}
{% comment %} TODO: Remove theme check {% endcomment %}
{% # theme-check-disable %}
{% assign cart_qty = cart | item_count_for_variant: variant.id %}
{% # theme-check-enable %}
{% render 'quantity-input', variant: variant, min: 0 %}
{%- endif -%}
</div>
{% if cart_qty > 0 %}
<div
id="Remove-{{ variant.id }}"
class="quick-order-list-remove-button"
data-index="{{ variant.id }}"
>
<button
class="button button--tertiary"
aria-label="{{ 'sections.cart.remove_title' | t: title: item.title }}"
data-target="remove-{{ variant.id }}"
>
<span class="svg-wrapper">
{{- 'icon-remove.svg' | inline_asset_content -}}
</span>
</button>
</div>
{% endif %}
</div>
{%- if has_popover -%}
<button
type="button"
class="quantity-popover__info-button quantity-popover__info-button--icon-with-label button button--tertiary large-up-hide"
aria-expanded="false"
>
{{- 'icon-info.svg' | inline_asset_content -}}
<span>
{%- if has_vol_pricing -%}
{{ 'products.product.volume_pricing.note' | t }}
{%- elsif has_qty_rules -%}
{{ 'products.product.quantity.note' | t }}
{%- endif -%}
</span>
</button>
{%- endif -%}
<div
class="variant-item__error large-up-hide"
id="Quick-order-list-item-error-mobile-{{ variant.id }}"
role="alert"
>
<small class="variant-item__error-text"></small>
<span class="svg-wrapper">
{{- 'icon-error.svg' | inline_asset_content -}}
</span>
</div>
</quantity-popover>
</td>
{%- assign item_price = item.price | money -%}
<td class="variant-item__price small-hide medium-hide">
{%- if item.compare_at_price -%}
<dl class="variant-item__discounted-prices">
<dt class="visually-hidden">
{{ 'products.product.price.regular_price' | t }}
</dt>
<dd>
<s class="variant-item__old-price price price--end">
{{ item.compare_at_price | money }}
</s>
</dd>
<dt class="visually-hidden">
{{ 'products.product.price.sale_price' | t }}
</dt>
<dd class="price">
{%- if variant.quantity_price_breaks.size > 0 -%}
{%- liquid
assign volume_pricing_array = variant.quantity_price_breaks | sort: 'quantity' | reverse
-%}
<price-per-item
class="variant-item__price-per-item"
id="Price-Per-Item-{{ variant.id }}"
data-variant-id="{{ variant.id }}"
>
<div class="price-per-item">
{%- if cart_qty < volume_pricing_array.last.minimum_quantity -%}
{%- assign variant_price = variant.price | money -%}
<span class="price-per-item--current price">
{{- 'sections.quick_order_list.each' | t: money: variant_price -}}
</span>
{%- else -%}
{%- for price_break in volume_pricing_array -%}
{%- if cart_qty >= price_break.minimum_quantity -%}
{%- assign price_break_price = price_break.price | money -%}
<span class="price-per-item--current price">
{{- 'sections.quick_order_list.each' | t: money: price_break_price -}}
</span>
{%- break -%}
{%- endif -%}
{%- endfor -%}
{%- endif -%}
</div>
</price-per-item>
{%- else -%}
<span class="price">
{{- 'sections.quick_order_list.each' | t: money: item_price -}}
</span>
{%- endif -%}
</dd>
</dl>
{%- else -%}
{%- if variant.quantity_price_breaks.size > 0 -%}
{%- liquid
assign volume_pricing_array = variant.quantity_price_breaks | sort: 'quantity' | reverse
-%}
<price-per-item
class="variant-item__price-per-item"
id="Price-Per-Item-{{ variant.id }}"
data-variant-id="{{ variant.id }}"
>
<div class="price-per-item">
{%- if cart_qty < volume_pricing_array.last.minimum_quantity -%}
{%- assign variant_price = variant.price | money -%}
<span class="price-per-item--current price">
{{- 'sections.quick_order_list.each' | t: money: variant_price -}}
</span>
{%- else -%}
{%- for price_break in volume_pricing_array -%}
{%- if cart_qty >= price_break.minimum_quantity -%}
{%- assign price_break_price = price_break.price | money -%}
<span class="price-per-item--current price">
{{- 'sections.quick_order_list.each' | t: money: price_break_price -}}
</span>
{%- break -%}
{%- endif -%}
{%- endfor -%}
{%- endif -%}
</div>
</price-per-item>
{%- else -%}
<span class="price">
{{- 'sections.quick_order_list.each' | t: money: item_price -}}
</span>
{%- endif -%}
{%- endif -%}
{%- if item.available and item.unit_price_measurement -%}
{% render 'unit-price', price: item.unit_price, measurement: item.unit_price_measurement %}
{%- endif -%}
</td>
<td class="variant-item__totals right small-hide medium-hide">
{%- render 'loading-spinner' -%}
{% comment %} TODO: enable theme-check once `line_items_for` is accepted as valid filter {% endcomment %}
{% # theme-check-disable %}
<span class="price">{{ cart | line_items_for: item | sum: 'original_line_price' | money }}</span>
{% # theme-check-enable %}
</td>
</tr>
<tr class="small-hide medium-hide hidden desktop-row-error">
<td></td>
<td>
<div class="variant-item__error" id="Quick-order-list-item-error-desktop-{{ variant.id }}" role="alert">
<small class="variant-item__error-text"></small>
<span class="svg-wrapper">{{ 'icon-error.svg' | inline_asset_content }}</span>
</div>
</td>
<td></td>
<td></td>
</tr>
{%- if product.quantity_price_breaks_configured? -%}
<volume-pricing class="hidden" id="Volume-{{ variant.id }}">
<ul>
<li>
<span>{{ variant.quantity_rule.min }}</span>
{%- assign price = variant.price | money -%}
<span data-text="{{ price }}">{{ price }}</span>
</li>
{%- for price_break in variant.quantity_price_breaks -%}
{%- assign price_break_price = price_break.price | money -%}
<li>
<span>
{{- price_break.minimum_quantity -}}
</span>
<span data-text="{{ price_break_price }}">{{- price_break.price | money }}</span>
</li>
{%- endfor -%}
</ul>
</volume-pricing>
{%- endif -%}
+300
View File
@@ -0,0 +1,300 @@
{% comment %}
Renders a list of product's variants
Accepts:
- product: {Object} Product Liquid object
- show_image: {Boolean} Shows image of the variant in the row
- is_modal: {Boolean} Defines if this snippet lives in a modal (optional)
Usage:
{% render 'quick-order-list', product: product %}
{% endcomment %}
{% comment %} TODO: enable theme-check once `line_items_for` is accepted as valid filter {% endcomment %}
{% # theme-check-disable %}
{%- assign items_in_cart = cart | line_items_for: product | sum: 'quantity' -%}
{% # theme-check-enable %}
<div class="quick-order-list-container color-{{ section.settings.color_scheme }}{% unless is_modal %} gradient{% endunless %}">
<quick-order-list
class="page-width section-{{ section.id }}-padding"
id="{{ section.id }}-{{ product.id }}"
data-section="{{ section.id }}"
data-product-id="{{ product.id }}"
data-url="{{ product.url }}"
>
<form
action="{{ routes.cart_update_url }}"
class="quick-order-list__contents critical-hidden"
method="post"
id="QuickOrderList"
>
{% paginate product.variants by section.settings.variants_per_page %}
<div class="quick-order-list__container" id="main-variant-items">
<table class="quick-order-list__table">
<caption class="visually-hidden">
{{ 'sections.cart.title' | t }}
</caption>
<thead>
<tr>
<th class="caption-with-letter-spacing" scope="col">
{%- if product.has_only_default_variant -%}
{{ 'sections.quick_order_list.product' | t }}
{%- else -%}
{{ 'sections.quick_order_list.variant' | t }}
{%- endif -%}
</th>
<th class="large-up-hide right caption-with-letter-spacing" scope="col">
{%- if product.has_only_default_variant -%}
{{ 'sections.quick_order_list.product_total' | t }}
{%- else -%}
{{ 'sections.quick_order_list.variant_total' | t }}
{%- endif -%}
</th>
<th
class="quick-order-list__table-heading--wide small-hide medium-hide caption-with-letter-spacing"
scope="col"
>
{{ 'products.product.quantity.label' | t }}
</th>
<th
class="quick-order-list__table-heading--wide small-hide medium-hide caption-with-letter-spacing"
scope="col"
>
{{ 'sections.cart.headings.price' | t }}
</th>
<th class="small-hide medium-hide right caption-with-letter-spacing" scope="col">
{%- if product.has_only_default_variant -%}
{{ 'sections.quick_order_list.product_total' | t }}
{%- else -%}
{{ 'sections.quick_order_list.variant_total' | t }}
{%- endif -%}
</th>
</tr>
</thead>
<tbody>
{%- if product.has_only_default_variant -%}
{%- render 'quick-order-list-row',
item: product,
image: product.featured_media,
sku: product.selected_or_first_available_variant.sku,
variant: product.selected_or_first_available_variant,
show_image: show_image,
show_sku: show_sku,
is_modal: is_modal
-%}
{%- else -%}
{%- for variant in product.variants -%}
{%- render 'quick-order-list-row',
item: variant,
image: variant.image,
sku: variant.sku,
variant: variant,
show_image: show_image,
show_sku: show_sku,
is_modal: is_modal
-%}
{%- endfor -%}
{%- endif -%}
</tbody>
</table>
</div>
<div class="js-paginate">
{% render 'pagination', paginate: paginate %}
</div>
{%- endpaginate -%}
<p
class="visually-hidden"
id="quick-order-list-live-region-text-{{ product.id }}"
aria-live="polite"
role="status"
></p>
<p
class="visually-hidden"
id="shopping-cart-variant-item-status"
aria-live="polite"
aria-hidden="true"
role="status"
>
{{ 'accessibility.loading' | t }}
</p>
</form>
{%- if product.has_only_default_variant or product.variants_count == 1 -%}
<span class="quick-order-list-error">
{% comment %} Populated by JS {% endcomment %}
</span>
{%- else -%}
<div
class="quick-order-list__total{% unless is_modal %} gradient{% endunless %}"
id="quick-order-list-total-{{ product.id }}-{{ section.id }}"
>
<div class="quick-order-list-total__info">
<div class="quick-order-list-total__column small-hide medium-hide">
<div class="quick-order-list-buttons">
<a
href="{{ routes.cart_url }} "
class="quick-order-list__button button button--secondary small-hide medium-hide"
>
<span class="quick-order-list__button-text">{{- 'sections.quick_order_list.view_cart' | t -}}</span>
</a>
<div class="variant-remove-total{% if items_in_cart == 0 %} variant-remove-total--empty{% endif %}">
{%- render 'loading-spinner' -%}
<quick-order-list-remove-all-button
data-action="confirm"
class="{% if items_in_cart == 0 %}hidden{% endif %}"
>
<button class="button button--tertiary" type="button">
<span class="svg-wrapper">
{{- 'icon-remove.svg' | inline_asset_content -}}
</span>
<span class="text-body">{{ 'sections.quick_order_list.remove_all' | t }}</span>
</button>
</quick-order-list-remove-all-button>
</div>
</div>
<span class="quick-order-list__message caption-large" role="status">
<span class="quick-order-list__message-icon hidden">
<span class="svg-wrapper">
{{- 'icon-checkmark.svg' | inline_asset_content -}}
</span>
</span>
<span class="quick-order-list__message-text"></span>
</span>
<span class="quick-order-list-error">
{% comment %} Populated by JS {% endcomment %}
</span>
</div>
<div class="quick-order-list__total-items">
<span>
{{ items_in_cart }}
</span>
<p class="h5">{{ 'sections.quick_order_list.total_items' | t }}</p>
</div>
<div class="quick-order-list-total__price">
<div class="totals__product-total">
<span class="totals__subtotal-value">
{% comment %} TODO: enable theme-check once `line_items_for` is accepted as valid filter {% endcomment %}
{% # theme-check-disable %}
{{ cart | line_items_for: product | sum: 'original_line_price' | money }}
{% # theme-check-enable %}
</span>
<p class="totals__subtotal h5">{{ 'sections.quick_order_list.product_total' | t }}</p>
</div>
<small class="tax-note caption-large rte">
{%- if cart.duties_included and cart.taxes_included -%}
{%- if shop.shipping_policy.body == blank -%}
{{ 'sections.cart.duties_and_taxes_included_shipping_at_checkout_without_policy' | t }}
{%- else -%}
{{
'sections.cart.duties_and_taxes_included_shipping_at_checkout_with_policy_html'
| t: link: shop.shipping_policy.url
}}
{%- endif -%}
{%- elsif cart.duties_included == false and cart.taxes_included -%}
{%- if shop.shipping_policy.body == blank -%}
{{ 'sections.cart.taxes_included_shipping_at_checkout_without_policy' | t }}
{%- else -%}
{{
'sections.cart.taxes_included_shipping_at_checkout_with_policy_html'
| t: link: shop.shipping_policy.url
}}
{%- endif -%}
{%- elsif cart.duties_included and cart.taxes_included == false -%}
{%- if shop.shipping_policy.body == blank -%}
{{ 'sections.cart.duties_included_taxes_at_checkout_shipping_at_checkout_without_policy' | t }}
{%- else -%}
{{
'sections.cart.duties_included_taxes_at_checkout_shipping_at_checkout_with_policy_html'
| t: link: shop.shipping_policy.url
}}
{%- endif -%}
{%- elsif cart.duties_included == false and cart.taxes_included == false -%}
{%- if shop.shipping_policy.body == blank -%}
{{ 'sections.cart.taxes_at_checkout_shipping_at_checkout_without_policy' | t }}
{%- else -%}
{{
'sections.cart.taxes_at_checkout_shipping_at_checkout_with_policy_html'
| t: link: shop.shipping_policy.url
}}
{%- endif -%}
{%- endif -%}
</small>
</div>
<div class="quick-order-list-total__column large-up-hide">
<div class="quick-order-list-buttons">
<a
href="{{ routes.cart_url }}"
class="quick-order-list__button button button--secondary button--full-width"
>
<span class="quick-order-list__button-text">{{- 'sections.quick_order_list.view_cart' | t -}}</span>
</a>
<div class="variant-remove-total">
{%- render 'loading-spinner' -%}
<quick-order-list-remove-all-button
class="{% if items_in_cart == 0 %}hidden{% endif %}"
data-action="confirm"
>
<button class="button button--tertiary" type="button">
<span class="svg-wrapper">
{{- 'icon-remove.svg' | inline_asset_content -}}
</span>
<span class="text-body">{{ 'sections.quick_order_list.remove_all' | t }}</span>
</button>
</quick-order-list-remove-all-button>
</div>
</div>
<span class="quick-order-list__message caption-large" role="status">
<span class="quick-order-list__message-icon hidden">
<span class="svg-wrapper">
{{- 'icon-checkmark.svg' | inline_asset_content -}}
</span>
</span>
<span class="quick-order-list__message-text"></span>
</span>
<span class="quick-order-list-error">
{% comment %} Populated by JS {% endcomment %}
</span>
</div>
</div>
<div class="quick-order-list-total__confirmation hidden">
<span class="text-body">
{{ 'sections.quick_order_list.remove_all_items_confirmation' | t: quantity: items_in_cart }}
</span>
<quick-order-list-remove-all-button
data-action="remove"
>
<button
class="quick-order-list__button-confirm button button--secondary"
type="button"
>
{{- 'sections.quick_order_list.remove_all' | t -}}
</button>
</quick-order-list-remove-all-button>
<quick-order-list-remove-all-button
data-action="cancel"
>
<button
class="quick-order-list__button-cancel button button--tertiary"
type="button"
>
{{- 'sections.quick_order_list.cancel' | t -}}
</button>
</quick-order-list-remove-all-button>
</div>
<script type="application/json" data-cart-contents>
{{ cart | line_items_for: product | map: "variant_id" | json }}
</script>
</div>
{%- endif -%}
</quick-order-list>
<template id="QuickOrderListErrorTemplate-{{ product.id }}">
<span class="svg-wrapper">
{{ 'icon-error.svg' | inline_asset_content }}
</span>
<span class="quick-order-list-error-message caption-large" role="alert"></span>
</template>
</div>
+41
View File
@@ -0,0 +1,41 @@
{% comment %}
Quick Order Product Row
Accepts:
- item: {Object} Variant or Product object
- image: {Object} Product or Variant image (optional)
Usage:
{% render 'quick-order-product-row' %}
{% endcomment %}
<tr
class="product"
>
<td class="product-item__inner">
<div class="product-item__title--wrapper">
<div class="variant-item__media">
<div class="variant-item__image-container gradient global-media-settings">
{%- if image -%}
{%- assign img_height = 36 | divided_by: image.aspect_ratio | ceil -%}
{{
image
| image_url: width: 72
| image_tag:
loading: 'lazy',
fetchpriority: 'low',
decoding: 'async',
class: 'variant-item__image',
width: 36,
height: img_height,
widths: '72',
alt: image.alt
| escape
}}
{% endif %}
</div>
</div>
<div class="small-hide">
<a href="{{ item.url }}" class="variant-item__name h4 break">{{ item.title | escape }}</a>
</div>
</div>
</td>
</tr>
+53
View File
@@ -0,0 +1,53 @@
{% comment %}
Renders share button.
Accepts:
- block: {Object} passes in the block information.
- share_link: {String} url to be added to the input the user will get/copy.
Usage:
{% render 'share-button',
block: block,
share_link: share_url
%}
{% endcomment %}
<script src="{{ 'share.js' | asset_url }}" defer="defer"></script>
<share-button id="Share-{{ section.id }}" class="share-button quick-add-hidden" {{ block.shopify_attributes }}>
<button class="share-button__button hidden">
<span class="svg-wrapper">{{ 'icon-share.svg' | inline_asset_content }}</span>
{{ block.settings.share_label | escape }}
</button>
<details id="Details-{{ block.id }}-{{ section.id }}">
<summary class="share-button__button">
<span class="svg-wrapper">{{ 'icon-share.svg' | inline_asset_content }}</span>
{{ block.settings.share_label | escape }}
</summary>
<div class="share-button__fallback motion-reduce">
<div class="field">
<span id="ShareMessage-{{ section.id }}" class="share-button__message hidden" role="status"> </span>
<input
type="text"
class="field__input"
id="ShareUrl-{{ section.id }}"
value="{{ share_link }}"
placeholder="{{ 'general.share.share_url' | t }}"
onclick="this.select();"
readonly
>
<label class="field__label" for="ShareUrl-{{ section.id }}">{{ 'general.share.share_url' | t }}</label>
</div>
<button class="share-button__close hidden">
<span class="svg-wrapper">
{{- 'icon-close.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.share.close' | t }}</span>
</button>
<button class="share-button__copy">
<span class="svg-wrapper">
{{- 'icon-copy.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.share.copy_to_clipboard' | t }}</span>
</button>
</div>
</details>
</share-button>
+103
View File
@@ -0,0 +1,103 @@
{% comment %}
Renders social icons.
Accepts:
- class: {String} a class to be added to the <ul> element (optional).
Usage:
{% render 'social-icons',
class: 'my-class'
%}
{% endcomment %}
<ul class="list-unstyled list-social{% if class %} {{ class}}{% endif %}" role="list">
{%- if settings.social_facebook_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_facebook_link }}" class="link list-social__link">
<span class="svg-wrapper">
{{- 'icon-facebook.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.facebook' | t }}</span>
</a>
</li>
{%- endif -%}
{%- if settings.social_instagram_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_instagram_link }}" class="link list-social__link">
<span class="svg-wrapper">
{{- 'icon-instagram.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.instagram' | t }}</span>
</a>
</li>
{%- endif -%}
{%- if settings.social_youtube_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_youtube_link }}" class="link list-social__link">
<span class="svg-wrapper">
{{- 'icon-youtube.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.youtube' | t }}</span>
</a>
</li>
{%- endif -%}
{%- if settings.social_tiktok_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_tiktok_link }}" class="link list-social__link">
<span class="svg-wrapper">
{{- 'icon-tiktok.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.tiktok' | t }}</span>
</a>
</li>
{%- endif -%}
{%- if settings.social_twitter_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_twitter_link }}" class="link list-social__link">
<span class="svg-wrapper">
{{- 'icon-twitter.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.twitter' | t }}</span>
</a>
</li>
{%- endif -%}
{%- if settings.social_pinterest_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_pinterest_link }}" class="link list-social__link">
<span class="svg-wrapper">
{{- 'icon-pinterest.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.pinterest' | t }}</span>
</a>
</li>
{%- endif -%}
{%- if settings.social_snapchat_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_snapchat_link }}" class="link list-social__link">
<span class="svg-wrapper">
{{- 'icon-snapchat.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.snapchat' | t }}</span>
</a>
</li>
{%- endif -%}
{%- if settings.social_tumblr_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_tumblr_link }}" class="link list-social__link">
<span class="svg-wrapper">
{{- 'icon-tumblr.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.tumblr' | t }}</span>
</a>
</li>
{%- endif -%}
{%- if settings.social_vimeo_link != blank -%}
<li class="list-social__item">
<a href="{{ settings.social_vimeo_link }}" class="link list-social__link">
<span class="svg-wrapper">
{{- 'icon-vimeo.svg' | inline_asset_content -}}
</span>
<span class="visually-hidden">{{ 'general.social.links.vimeo' | t }}</span>
</a>
</li>
{%- endif -%}
</ul>
+52
View File
@@ -0,0 +1,52 @@
{% comment %}
Renders a swatch input component.
Accepts:
- id: {String} unique input id
- type: {String} input type. Accepts 'radio' or 'checkbox', defaults to 'radio' (optional)
- name: {String} input name,
- value: {ProductOptionValueDrop} input value
- swatch: {SwatchDrop} the swatch drop
- product_form_id: {String} id of the form associted with the input
- checked: {Boolean} default checked status
- disabled: {Boolean} default disabled status (optional)
- visually_disabled: {Boolean} style the swatch as disabled, but leave the input enabled (optional)
- shape: {String} swatch shape. Accepts 'square', defaults to circle (optional)
- help_text: {String} additional content to render inside the label (optional)
- additional_props: {String} (optional) additional properties to attach to the input
Usage:
{% render 'swatch-input',
id: input_id,
name: input_name,
value: input_value,
swatch: swatch,
product_form_id: product_form_id,
checked: checked
%}
{% endcomment %}
<input
type="{{ type | default: 'radio' }}"
id="{{ id }}"
name="{{ name }}"
value="{{ value }}"
form="{{ product_form_id }}"
class="swatch-input__input{% if visually_disabled %} visually-disabled{% endif %}"
{% if checked %}
checked
{% endif %}
{% if disabled %}
disabled
{% endif %}
{% if additional_props %}
{{ additional_props }}
{% endif %}
>
<label
for="{{ id }}"
title="{{ value }}"
class="swatch-input__label{% if shape == 'square' %} swatch-input__label--square{% endif %}"
>
{% render 'swatch', swatch: swatch, shape: shape %}
{{ help_text }}
</label>
+32
View File
@@ -0,0 +1,32 @@
{% comment %}
Renders a swatch component.
Accepts:
- swatch: {Object} a swatch object
- shape: {String} swatch shape. Accepts 'square', defaults to circle.
Usage:
{% render 'swatch',
swatch: value.swatch
shape: 'square'
%}
{% endcomment %}
{%- liquid
assign swatch_value = null
if swatch.image
assign image_url = swatch.image | image_url: width: 50
assign swatch_value = 'url(' | append: image_url | append: ')'
assign swatch_focal_point = swatch.image.presentation.focal_point
elsif swatch.color
assign swatch_value = 'rgb(' | append: swatch.color.rgb | append: ')'
endif
-%}
<span
{% if swatch_value %}
class="swatch{% if shape == 'square' %} swatch--square{% endif %}"
style="--swatch--background: {{ swatch_value }};{% if swatch_focal_point %} --swatch-focal-point: {{ swatch_focal_point }};{% endif %}"
{% else %}
class="swatch swatch--unavailable{% if shape == 'square' %} swatch--square{% endif %}"
{% endif %}
></span>
+21
View File
@@ -0,0 +1,21 @@
{%- doc -%}
Renders the unit price, including its measurement.
@param {object} price - The unit price (money or string).
@param {object} measurement - The unit_price_measurement object.
@param {boolean} [hide_accessibility_label] - Whether to hide the accessibility label (default: false).
@example
{% render 'unit-price', price: variant.unit_price, measurement: variant.unit_price_measurement %}
@example
{% render 'unit-price', price: line_item.unit_price | money_with_currency, measurement: line_item.unit_price_measurement }
{%- enddoc -%}
<small class="unit-price caption">
{%- unless hide_accessibility_label -%}
<span class="visually-hidden">{{ 'products.product.price.unit_price' | t }}</span>
{%- endunless -%}
<span class="price-item price-item--last">
{{ price | unit_price_with_measurement: measurement }}
</span>
</small>