first commit

This commit is contained in:
Axel
2025-11-12 18:26:25 +08:00
commit 738e32f419
3 changed files with 636 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,189 @@
{%- comment -%}
Pass in:
- product or variant
- format string, one of
- "sale_text"
- "percent_off"
- "minus_percent"
- "save_percent"
- "amount_off"
- "minus_amount"
- "save_amount"
{%- endcomment -%}
{%- assign varies = false -%}
{%- liquid
assign prod_price = prod.price
assign prod_compare_at_price = prod.compare_at_price
if variant
assign prod = variant
assign prod_price = variant.metafields.app--168074346497.auto_discounted_price.value | default: variant.price
assign prod_compare_at_price = variant.compare_at_price
if variant.metafields.app--168074346497.discount_type.value != nil and variant.metafields.app--168074346497.discount_type.value != "fixed" and prod.metafields.app--168074346497.discount_percentage.value > 0.01
assign deducted_percentage = 1.0 | minus: prod.metafields.app--168074346497.discount_percentage.value
if variant.metafields.app--168074346497.discount_percentage.value > 0.01
assign deducted_percentage = 1.0 | minus: variant.metafields.app--168074346497.discount_percentage.value
endif
assign prod_price = variant.price | divided_by: 100.0 | times: deducted_percentage | times: 100.0 | ceil
assign prod_compare_at_price = variant.price
if variant.compare_at_price > prod_compare_at_price
assign prod_compare_at_price = variant.compare_at_price
endif
endif
else
if prod.compare_at_price_varies or prod.price_varies
assign varies = true
assign amount_off_varies = true
assign smallest_amount_off = 0
assign largest_amount_off = 0
for variant in prod.variants
assign variant_price = variant.metafields.app--168074346497.auto_discounted_price.value | default: variant.price
assign variant_compare_at_price = variant.compare_at_price
if variant.metafields.app--168074346497.discount_type.value != nil and variant.metafields.app--168074346497.discount_type.value != "fixed" and prod.metafields.app--168074346497.discount_percentage.value > 0.01
assign deducted_percentage = 1.0 | minus: prod.metafields.app--168074346497.discount_percentage.value
if variant.metafields.app--168074346497.discount_percentage.value > 0.01
assign deducted_percentage = 1.0 | minus: variant.metafields.app--168074346497.discount_percentage.value
endif
assign variant_price = variant.price | divided_by: 100.0 | times: deducted_percentage | times: 100.0 | ceil
assign variant_compare_at_price = variant.price
if variant.compare_at_price > variant_compare_at_price
assign variant_compare_at_price = variant.compare_at_price
endif
endif
if variant_compare_at_price > variant_price
assign variant_amount_off = variant_compare_at_price | minus: variant_price
if smallest_amount_off == 0 or variant_amount_off < smallest_amount_off
assign smallest_amount_off = variant_amount_off
endif
if variant_amount_off > largest_amount_off
assign largest_amount_off = variant_amount_off
endif
endif
endfor
if smallest_amount_off == largest_amount_off
assign amount_off_varies = false
endif
endif
endif
-%}
{% comment %}
{% if variant %}
{% assign prod = variant %}
{% else %}
{%- if prod.compare_at_price_varies or prod.price_varies -%}
{%- assign varies = true -%}
{%- assign amount_off_varies = true -%}
{% comment %}
The price may vary but the amount off may be the same for each variant.
Here we check to see if the amount off for each variant is the same or different.
{% endcomment %}
{%- assign smallest_amount_off = 0 -%}
{%- assign largest_amount_off = 0 -%}
{%- for variant in prod.variants -%}
{%- if variant.compare_at_price > variant.price -%}
{%- assign variant_amount_off = variant.compare_at_price | minus: variant.price -%}
{%- if smallest_amount_off == 0 -%}
{%- assign smallest_amount_off = variant_amount_off -%}
{%- endif -%}
{%- if variant_amount_off > largest_amount_off -%}
{%- assign largest_amount_off = variant_amount_off -%}
{%- endif -%}
{%- if variant_amount_off < smallest_amount_off -%}
{%- assign smallest_amount_off = variant_amount_off -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
{% comment %}
If the smallest amount off is equal to the largest amount then the discount does not vary
{% endcomment %}
{%- if smallest_amount_off == largest_amount_off -%}
{%- assign amount_off_varies = false -%}
{%- endif -%}
{%- endif -%}
{%- endif -%}
{% endcomment %}
{%- if format == 'sale_text' -%}
{%- if prod_compare_at_price > prod_price -%}
{{ 'products.product.on_sale' | t }}
{%- endif -%}
{%- else -%}
{%- assign is_percent_format = false -%}
{%- if format == 'percent_off' or format == 'minus_percent' or format == 'save_percent' -%}
{%- assign is_percent_format = true -%}
{%- endif -%}
{%- if varies -%}
{%- if is_percent_format -%}
{%- capture displayed_discount -%}
{%- render 'get-varied-percent-discount', prod: prod -%}
{%- endcapture -%}
{%- else -%}
{%- capture displayed_discount -%}
{%- render 'get-varied-amount-discount', prod: prod -%}
{%- endcapture -%}
{%- endif -%}
{%- else -%}
{%- if is_percent_format -%}
{%- capture displayed_discount -%}{%- render 'get-percent-discount', prod: prod -%}{%- endcapture -%}
{%- else -%}
{%- capture displayed_discount -%}{%- render 'get-amount-discount', prod: prod -%}{%- endcapture -%}
{%- endif -%}
{%- endif -%}
{% assign displayed_discount = displayed_discount | plus: 0 -%}
{%- unless is_percent_format %}
{% capture formatted_currency_discount %}{{ displayed_discount | money }}{% endcapture %}
{% endunless -%}
{%- if displayed_discount > 0 %}
{%- if format == 'percent_off' -%}
{% if amount_off_varies %}{{ 'products.product.on_sale_varied_prefix' | t }}{% endif %}
{{ 'products.product.on_sale_format_percent_off' | t: value: displayed_discount }}
{%- elsif format == 'minus_percent' -%}
{% if amount_off_varies %}{{ 'products.product.on_sale_varied_prefix' | t }}{% endif %}
{{ 'products.product.on_sale_format_minus_percent' | t: value: displayed_discount }}
{%- elsif format == 'save_percent' -%}
{% if amount_off_varies %}
{{ 'products.product.on_sale_format_save_percent_varied' | t: value: displayed_discount }}
{% else %}
{{ 'products.product.on_sale_format_save_percent' | t: value: displayed_discount }}
{% endif %}
{%- elsif format == 'amount_off' -%}
{% if amount_off_varies %}{{ 'products.product.on_sale_varied_prefix' | t }}{% endif %}
{{ 'products.product.on_sale_format_amount_off' | t: value: formatted_currency_discount }}
{%- elsif format == 'minus_amount' -%}
{% if amount_off_varies %}{{ 'products.product.on_sale_varied_prefix' | t }}{% endif %}
{{ 'products.product.on_sale_format_minus_amount' | t: value: formatted_currency_discount }}
{%- elsif format == 'save_amount' -%}
{% if amount_off_varies %}
{{ 'products.product.on_sale_format_save_amount_varied' | t: value: formatted_currency_discount }}
{% else %}
{{ 'products.product.on_sale_format_save_amount' | t: value: formatted_currency_discount }}
{% endif %}
{%- endif -%}
{% endif -%}
{%- endif -%}

View File

@@ -0,0 +1,447 @@
{%- liquid
comment
pass in :
* prod (product but avoiding collision with globally scoped product)
endcomment
assign prod_compare_at_price = prod.compare_at_price
assign prod_price = prod.price
assign prod_price = prod.metafields.app--168074346497.min_auto_discounted_price.value | default: prod.price
if prod.metafields.app--168074346497.discount_percentage.value > 0.01
assign deducted_percentage = 1.0 | minus: prod.metafields.app--168074346497.discount_percentage.value
assign prod_price = prod.price | divided_by: 100.0 | times: deducted_percentage | times: 100.0 | ceil
assign prod_compare_at_price = prod.price
if prod.compare_at_price > prod_compare_at_price
assign prod_compare_at_price = prod.compare_at_price
endif
endif
assign show_multiple_images = false
if settings.product_listing_show_second_image_on_hover and prod.media.size > 1
assign show_multiple_images = true
endif
assign current_variant = prod.selected_or_first_available_variant
assign mobile_column_count = 2
if product_columns_mobile == 1
assign mobile_column_count = 1
endif
case product_columns_desktop
when '5'
assign sizes = '(max-width: 720px) calc((90vw - 12px) /[[mcc]]), (max-width: 1400px) calc((93.4vw - (12px * 3)) / 5), 270px' | replace: '[[mcc]]', mobile_column_count
when '3'
assign sizes = '(max-width: 720px) calc((90vw - 12px) /[[mcc]]), (max-width: 1400px) calc((93.4vw - (12px * 3)) / 3), 450px' | replace: '[[mcc]]', mobile_column_count
when '2'
assign sizes = '(max-width: 720px) calc((90vw - 12px) /[[mcc]]), (max-width: 1400px) calc((93.4vw - (12px * 3)) / 2), 690px' | replace: '[[mcc]]', mobile_column_count
else
# Using a 4 item grid as default for sizes
assign sizes = '(max-width: 720px) calc((90vw - 12px) /[[mcc]]), (max-width: 1400px) calc((93.4vw - (12px * 3)) / 4), 304px' | replace: '[[mcc]]', mobile_column_count
endcase
assign has_hover_swatches = false
assign has_hover_chips = false
assign show_sibling_swatches = false
assign sibling_products = prod.metafields.stiletto.sibling_collection.value.products | default: prod.metafields.stiletto.siblings_collection.value.products
# Sibling swatches will override other swatches if these conditions are met
if settings.enable_product_card_sibling_swatches and settings.siblings_option_name != blank and sibling_products.size > 0
assign has_hover_swatches = true
assign show_sibling_swatches = true
assign first_swatchified_option = settings.siblings_option_name | downcase
assign displayed_swatch_count = sibling_products.size
elsif settings.enable_product_card_swatches
capture first_swatchified_option
render 'get-first-styled-option', prod: prod, styled_options: settings.swatch_options
endcapture
assign displayed_swatch_count = prod.options_by_name[first_swatchified_option].values.size
if displayed_swatch_count > 0
assign has_hover_swatches = true
endif
endif
if settings.show_product_card_chips
capture first_chipped_option
render 'get-first-styled-option', prod: prod, styled_options: settings.product_card_chip_options
endcapture
assign displayed_chip_count = prod.options_by_name[first_chipped_option].values.size
if displayed_chip_count > 0
assign has_hover_chips = true
endif
endif
if quick_view_is_beneath
assign has_hover_swatches = false
assign has_hover_chips = false
endif
if prod.has_only_default_variant
assign product_has_variants = false
else
assign product_has_variants = true
endif
# Quick add takes precedence over quick view
# Use quick view for products with variants and sold out products
if settings.enable_quick_add and prod.available
if product_has_variants
assign quick_shop_type = 'quick-view'
assign quick_shop_button_text = 'products.product.choose_options' | t
else
assign quick_shop_type = 'quick-add'
assign quick_shop_button_text = 'products.product.add_to_cart' | t
endif
capture quick_shop_button_hoverless_icon
render 'icon', icon: 'quick-add'
endcapture
elsif settings.enable_quick_view
assign quick_shop_type = 'quick-view'
assign quick_shop_button_text = 'products.product.quick_view' | t
capture quick_shop_button_hoverless_icon
render 'icon', icon: 'quick-view'
endcapture
else
assign quick_shop_type = 'none'
endif
-%}
{% if quick_shop_type != 'none' %}
{% capture quick_shop_button_attributes %}
data-quick-shop-trigger="{{ quick_shop_type }}"
{% if quick_shop_type == 'quick-add' %}
data-product-id="{{ prod.variants[0].id }}"
{% else %}
data-product-url="{{ prod.url }}"
{% endif %}
{% endcapture %}
{% capture quick_shop_button %}
<button
class="btn btn--tertiary btn--x-small"
{{ quick_shop_button_attributes }}
tabindex="0"
>
<span>{{ quick_shop_button_text }}</span>
<div class="btn__loading-wrap">
<div class="btn__loading-bar"></div>
</div>
</button>
{% endcapture %}
{% capture quick_shop_button_hoverless %}
<button
class="product-item__hoverless-quick-view-button btn btn--rounded"
{{ quick_shop_button_attributes }}
tabindex="0"
title="{{ quick_shop_button_text }}"
>
{{ quick_shop_button_hoverless_icon }}
</button>
{% endcapture %}
{% endif %}
{% liquid
# wrap add-to-cart buttons in a product form for no-js or if purchase confirmation and quick cart are disabled
if quick_shop_type == 'quick-add'
capture product_form_tags
echo '<input class="product-item__product-form-variant-input" name="id" type="hidden" value="[[vi]]">' | replace: '[[vi]]', prod.variants[0].id
endcapture
capture quick_shop_button
form 'product', prod, class: 'product-item__product-form'
echo product_form_tags
echo quick_shop_button
endform
endcapture
capture quick_shop_button_hoverless
form 'product', prod, class: 'product-item__product-form'
echo product_form_tags
echo quick_shop_button_hoverless
endform
endcapture
endif
%}
<div
class="
product-item
{% if has_hover_swatches -%} product-item--with-hover-swatches {%- endif %}
{% if has_hover_chips -%} product-item--with-hover-chips {%- endif %}
{% if settings.enable_border_on_hover -%} product-item--border-on-hover {%- endif %}
animation
animation--item
{% if has_grid_reveal -%} animation--item-initial {%- endif %}
"
style="--z-index-item: {{ forloop.index }};"
>
<div class="product-item__inner">
<div class="product-item__media {%- if show_multiple_images %} product-item__media--multiple-images {%- endif %}">
<a class="product-item__image-link" href="{{ prod.url | within: collection }}" aria-label="{{ prod.title }}">
{%- liquid
assign image_wrapper_class = 'product-item__image'
if show_multiple_images
assign image_wrapper_class = image_wrapper_class | append: ' product-item__image--one'
assign second_image = prod.media[1].preview_image
if prod.featured_media != prod.media[0]
assign second_image = prod.media[0].preview_image
endif
endif
-%}
{% render 'image',
image: prod.featured_media,
wrapper_class: image_wrapper_class,
aspect_ratio: settings.product_listing_aspect_ratio,
object_fit: settings.product_listing_media_fit,
include_placeholder: true,
sizes: sizes,
src_set_type: 'grid'
%}
{%- if show_multiple_images -%}
{% render 'image',
image: second_image,
wrapper_class: 'product-item__image product-item__image--two',
aspect_ratio: settings.product_listing_aspect_ratio,
object_fit: settings.product_listing_media_fit,
include_placeholder: true,
sizes: sizes,
no_lazy_load: true,
src_set_type: 'grid'
%}
{%- endif -%}
</a>
{% unless placeholder %}
{%- render 'product-badges',
prod: prod,
show_sale_badge: settings.product_listing_show_sale_badge,
show_custom_badges: settings.product_listing_show_custom_badges,
show_sold_out_badge: settings.product_listing_show_sold_out_badge
-%}
{% endunless %}
{% if quick_shop_type != 'none' and quick_view_is_beneath != true %}
<div class="product-item__hover-action-wrap">
{{ quick_shop_button }}
</div>
{% endif %}
{% if quick_shop_type != 'none' %}
{{ quick_shop_button_hoverless }}
{% endif %}
</div>
<div class="product-item__meta">
<div class="product-item__text ta-c ">
<h4 class="ff-body product-item__product-title fs-product-card-title">
{%- if placeholder -%}
{{ 'homepage.onboarding.product_title' | t }}
{%- else -%}
<a href="{{ prod.url | within: collection }}">{{ prod.title }}</a>
{%- endif -%}
</h4>
{% if settings.product_listing_show_vendor and prod.vendor %}
<h5 class="ff-body fs-body-60 product-item__product-vendor">
{{ prod.vendor }}
</h5>
{% endif %}
{% if settings.product_listing_show_rating %}
{% render 'product-rating', prod: prod %}
{% endif %}
{% liquid
assign price_content_type = 'price'
if prod.available
if prod.price == 0 and prod.price_varies == false
if settings.zero_dollar_listing_price_display == 'replace'
assign price_content_type = 'custom'
assign custom_price_content = 'products.inventory.zero_price_custom_label' | t
elsif settings.zero_dollar_listing_price_display == 'hide'
assign price_content_type = 'hide'
assign custom_price_content = blank
endif
endif
else
if settings.sold_out_listing_price_display == 'hide'
assign price_content_type = 'hide'
assign custom_price_content = blank
elsif settings.sold_out_listing_price_display == 'replace'
assign price_content_type = 'custom'
assign custom_price_content = 'products.inventory.sold_out_price_custom_label' | t
endif
endif
%}
{% if price_content_type == 'price' %}
<p class="product-item__price">
{% if placeholder %}
{{ 9999 | money }}
{% elsif prod_compare_at_price > prod_price %}
<span class="visually-hidden">{{ 'products.product.regular_price' | t }}</span>
{% liquid
# Extend Shopify's detection for varied compare_at_price
assign has_null_compare_at_price = false
for variant in prod.variants
assign variant_compare_at_price = variant.compare_at_price
assign variant_price = variant.metafields.app--168074346497.auto_discounted_price.value | default: variant.price
if variant.metafields.app--168074346497.discount_type.value != nil and variant.metafields.app--168074346497.discount_type.value != "fixed" and prod.metafields.app--168074346497.discount_percentage.value > 0.01
assign deducted_percentage = 1.0 | minus: prod.metafields.app--168074346497.discount_percentage.value
if variant.metafields.app--168074346497.discount_percentage.value > 0.01
assign deducted_percentage = 1.0 | minus: variant.metafields.app--168074346497.discount_percentage.value
endif
assign variant_price = variant.price | divided_by: 100.0 | times: deducted_percentage | times: 100.0 | ceil
assign variant_compare_at_price = variant.price
if variant.compare_at_price > variant_compare_at_price
assign variant_compare_at_price = variant.compare_at_price
endif
endif
if variant_price < variant.price and variant_compare_at_price == blank
assign variant_compare_at_price = variant.price
endif
if variant_compare_at_price == null
assign has_null_compare_at_price = true
break
endif
endfor
%}
{% unless prod.compare_at_price_varies or has_null_compare_at_price %}
<s class="t-subdued">{{ prod_compare_at_price | money }}</s>
{% endunless %}
{% if prod.price_varies or prod.compare_at_price_varies or has_null_compare_at_price %}
{%- assign sale_price = prod_price | money -%}
<span class="sale">
{{- 'products.product.on_sale_from_html' | t: price: sale_price -}}
</span>
{% else %}
<span class="sale">{{ prod_price | money }}</span>
{% endif %}
{% else %}
{% if prod.price_varies %}
{%- assign price = prod_price | money -%}
{{ 'products.product.from_lowest_price_html' | t: lowest_price: price }}
{% else %}
<span class="product-item__price">{{ prod_price | money }}</span>
{% endif %}
{% endif %}
{% if settings.product_listing_show_discount %}
<span class="displayed-discount fs-body-50">
{%- render 'get-display-discount', prod: prod, format: settings.product_listing_discount_format -%}
</span>
{% endif %}
{% render 'unit-price', item: current_variant %}
</p>
{% elsif price_content_type == 'custom' %}
{% if prod.price_varies and prod_price == 0 %}
{%- assign price = prod_price | money -%}
{%- assign custom_price_content = 'products.inventory.zero_price_custom_label' | t -%}
<p class="product-item__price">
{% liquid
capture from_lowest_price_html
echo 'products.product.from_lowest_price_html' | t: lowest_price: custom_price_content
endcapture
if prod_compare_at_price > prod_price
echo '<span class="sale">[[flph]]</span>' | replace: '[[flph]]', from_lowest_price_html
else
echo from_lowest_price_html
endif
%}
</p>
{% else %}
{% if custom_price_content != blank %}
<p class="product-item__price">{{ custom_price_content }}</p>
{% endif %}
{% endif %}
{% endif %}
{% if has_hover_swatches or has_hover_chips %}
{% liquid
assign option_string = blank
if has_hover_swatches
assign swatch_string = 'products.product.swatch_count' | t: count: displayed_swatch_count, swatch_name: first_swatchified_option
assign option_string = option_string | append: swatch_string
endif
if has_hover_swatches and has_hover_chips
assign delimiter_string = 'products.product.swatch_and_chip_delimiter' | t
assign option_string = option_string | append: delimiter_string
endif
if has_hover_chips
assign chip_string = 'products.product.chip_count' | t: count: displayed_chip_count, chip_name: first_chipped_option
assign option_string = option_string | append: chip_string
endif
%}
<h5 class="ff-body fs-body-50 product-item__swatch-count">
{{ option_string }}
</h5>
{% endif %}
</div>
{%- if has_hover_swatches or has_hover_chips -%}
<div class="product-item__variant-info">
{%- if has_hover_swatches -%}
{%- render 'product-item-swatches',
prod: prod,
option_name: first_swatchified_option,
show_sibling_swatches: show_sibling_swatches,
sibling_products: sibling_products
-%}
{%- endif -%}
{%- if has_hover_chips -%}
{%- render 'product-item-chips', prod: prod, option_name: first_chipped_option -%}
{%- endif -%}
</div>
{%- endif -%}
{%- if quick_shop_type != 'none' and quick_view_is_beneath -%}
{{ quick_shop_button }}
{%- endif -%}
</div>
<div class="product-item__hover-container"></div>
</div>
</div>