From 60dfabd747c8ae3b9d3707564a5e65beff19401e Mon Sep 17 00:00:00 2001 From: Axel Kee Date: Fri, 29 Aug 2025 15:28:11 +0800 Subject: [PATCH] first commit --- product-card.liquid | 291 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 product-card.liquid diff --git a/product-card.liquid b/product-card.liquid new file mode 100644 index 0000000..841b078 --- /dev/null +++ b/product-card.liquid @@ -0,0 +1,291 @@ +{%- comment -%} +---------------------------------------------------------------------------------------------------------------------- +PRODUCT CARD COMPONENT +---------------------------------------------------------------------------------------------------------------------- + +This component is used in collection and featured collection to render a single product as a card + +******************************************** +Supported variables +******************************************** + +* product: the product to render +* stacked: define if the product is stacked or not on mobile +* reveal: if set to true, the card will be revealed on scroll through animation +* show_badges: show or not the badges (default to true if nothing is set). +* show_rating: show or not the rating. If nothing is set, the theme uses the default product card setting +* show_vendor: show or not the vendor. If nothing is set, the theme uses the default product card setting +* show_quick_buy: show or not the quick buy (which open a modal if the product contains more than 1 choice) +* show_secondary_image: show or not the secondary media on hover. If nothing is set, the theme uses the default product card setting +* show_swatches: show or not the swatches. The swatch type is inferred from setting, and will default to true if nothing is set. +* hide_product_information: if set to true, all content (vendor, badge, title...) are not rendered, to create image-based grid +* quick_buy_context: a unique text to dissociate quick buy if the same product is embedded multiple times +{%- endcomment -%} +{%- liquid + if hide_product_information + assign show_badges = false + assign show_rating = false + assign show_vendor = false + assign show_title = false + assign show_prices = false + assign show_swatches = false + assign show_quick_buy = show_quick_buy | default: settings.show_quick_buy, allow_false: true + assign show_secondary_image = show_secondary_image | default: settings.show_secondary_image, allow_false: true + else + assign show_badges = show_badges | default: true, allow_false: true + assign show_rating = show_rating | default: settings.show_product_rating, allow_false: true + assign show_vendor = show_vendor | default: settings.show_vendor, allow_false: true + assign show_quick_buy = show_quick_buy | default: settings.show_quick_buy, allow_false: true + assign show_title = true + assign show_prices = true + assign show_secondary_image = show_secondary_image | default: settings.show_secondary_image, allow_false: true + assign show_swatches = show_swatches | default: true, allow_false: true + endif +-%} + + + {%- comment -%} + -------------------------------------------------------------------------------------------------------------------- + PRODUCT MEDIA + -------------------------------------------------------------------------------------------------------------------- + {%- endcomment -%} + + {%- if product.media.size > 0 -%} +
+ {%- if show_badges -%} + {%- render 'product-badges', product: product, vertical: true -%} + {%- endif -%} + + + {%- capture sizes -%} + {%- if stacked -%} + (max-width: 699px) calc(100vw / {{ section.settings.products_per_row_mobile }}), (max-width: 999px) calc(100vw / {{ 3 | at_most: section.settings.products_per_row_desktop | default: 3 }} - 64px), calc((100vw - 96px) / {{ section.settings.products_per_row_desktop | default: 3 }} - (24px / {{ section.settings.products_per_row_desktop | default: 3 }} * {{ section.settings.products_per_row_desktop | default: 3 | minus: 1 }})) + {%- else -%} + (max-width: 699px) 74vw, (max-width: 999px) 38vw, calc((100vw - 96px) / {{ section.settings.products_per_row_desktop | default: 3 }} - (24px / {{ section.settings.products_per_row_desktop | default: 3 }} * {{ section.settings.products_per_row_desktop | default: 3 | minus: 1 }})) + {%- endif -%} + {%- endcapture -%} + + {%- capture main_image_classes -%}product-card__image product-card__image--primary {% if settings.product_image_aspect_ratio contains 'crop' %}object-cover{% endif %} aspect-{{ settings.product_image_aspect_ratio | split: '_' | first }}{%- endcapture -%} + {{- product.featured_media | image_url: width: product.featured_media.width | image_tag: loading: 'lazy', sizes: sizes, widths: '200,300,400,500,600,700,800,1000,1200,1400,1600,1800', class: main_image_classes -}} + + {%- if show_secondary_image and product.media.size > 1 -%} + {%- assign next_media = product.media[product.featured_media.position] | default: product.media[1] -%} + {{- next_media | image_url: width: next_media.width | image_tag: class: 'product-card__image product-card__image--secondary', loading: 'lazy', fetchpriority: 'low', sizes: sizes, widths: '200,300,400,500,600,700,800,1000,1200,1400,1600,1800' -}} + {%- endif -%} + + + {%- if show_quick_buy and product.available -%} + {%- if product.variants.size == 1 and product.selling_plan_groups.size == 0 -%} + {%- form 'product', product, is: 'product-form' -%} + + + + {% render 'collection-add-to-cart', product: product %} + {%- endform -%} + {%- else -%} + {%- capture quick_buy_id -%}product-quick-buy-{{ section.id }}-{{ block.id }}-{{ quick_buy_context }}-{{ product.id }}{%- endcapture -%} + + {% render 'collection-add-to-cart', product: product %} + + + + {%- endif -%} + {%- endif -%} +
+ {%- endif -%} + + {%- comment -%} + -------------------------------------------------------------------------------------------------------------------- + PRODUCT INFO + -------------------------------------------------------------------------------------------------------------------- + {%- endcomment -%} + +
+ {%- assign text_class = '' -%} + + {%- if settings.product_card_text_font == 'heading' -%} + {%- assign text_class = 'h5' -%} + {%- endif -%} + + {%- if show_title or show_prices or show_vendor and product.vendor != blank -%} +
+ {%- if show_vendor and product.vendor != blank -%} + {%- capture vendor_class -%}smallcaps {% if settings.product_card_text_font == 'heading' %}heading{% endif %}{% endcapture %} + {%- render 'vendor' with product.vendor, class: vendor_class -%} + {%- endif -%} + +
+ {%- if show_title -%} + 0 %}style="--line-clamp-count: {{ settings.product_title_max_lines }}"{% endif %} data-instant> + {{- product.title -}} + + {%- endif -%} + + {%- if show_prices and product.template_suffix != 'quote' -%} +
+ {{ product.selected_or_first_available_variant.price | money }} +
+ {%- endif -%} +
+
+ {%- endif -%} + + {%- if show_swatches and settings.product_color_display != 'hide' -%} + {%- assign translated_color_label = 'general.label.color' | t | downcase -%} + {%- assign original_color_label = 'Color' | downcase -%} + {%- assign color_labels = translated_color_label | append: ',' | append: original_color_label | split: ',' -%} + + {%- for color_label in color_labels -%} + {%- if product.options_by_name[color_label] != blank -%} + {%- assign product_option = product.options_by_name[color_label] -%} + {%- capture name -%}swatch-{{ quick_buy_context }}-{{ section.id }}-{{ product.id }}-{{ product_option.position }}{%- endcapture -%} + + {%- case settings.product_color_display -%} + {%- when 'count' -%} +

{{- 'product.general.available_colors_count' | t: count: product_option.values.size -}}

+ + {%- when 'swatch' -%} +
+ {%- for option_value in product_option.values -%} + {%- if forloop.first or product.selected_or_first_available_variant.matched and option_value == product_option.selected_value -%} + {%- assign selected = true -%} + {%- else -%} + {% assign selected = false %} + {%- endif -%} + {%- unless product.template_suffix == 'quote' -%} + {%- render 'swatch', type: 'colors', value: option_value, name: name, selected: selected, size: 'sm', show_tooltip: true -%} + {%- endunless -%} + {%- endfor %} +
+ {%- endcase -%} + + {%- assign type_option = product.options_with_values[1] -%} + {%- if type_option and type_option.values.size > 1 and type_option.name != 'Color' -%} + + + {%- unless product.template_suffix == 'quote' -%} +
+ + +
+ {%- endunless -%} + {%- endif -%} + + {% if product.options.size > 2 %} +
+ + +
+ {% endif %} + {%- break -%} + {%- endif -%} + {%- endfor -%} + + + {% assign alphabet = 'A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z' | split: ',' %} + + {% if product.template_suffix == "1Letter" %} +
+ + +
+ + {% elsif product.template_suffix == "2Letter" %} + {% for i in (1..2) %} +
+ + +
+ {% endfor %} + + {% elsif product.template_suffix == "3Letter" %} + {% for i in (1..3) %} +
+ + +
+ {% endfor %} + {% endif %} + + + {% if product.template_suffix == "1Date" %} +
+ + +
+ {% endif %} + {%- endif -%} + + + {%- if show_rating -%} + {%- render 'product-rating', product: product, show_empty: settings.show_product_rating_if_empty, display_mode: settings.product_rating_mode -%} + {%- endif -%} +
+
+ + +