diff --git a/assets/scss/layouts/_layouts.scss b/assets/scss/layouts/_layouts.scss index ad18a92264..3a0b6d838e 100644 --- a/assets/scss/layouts/_layouts.scss +++ b/assets/scss/layouts/_layouts.scss @@ -46,6 +46,9 @@ // Product Sale Badges @import "products/productSaleBadges"; +// Featured Promotion Callouts +@import "products/featuredPromotions"; + // Product view @import "products/productSwatch"; diff --git a/assets/scss/layouts/products/_featuredPromotions.scss b/assets/scss/layouts/products/_featuredPromotions.scss new file mode 100644 index 0000000000..dc33c9deae --- /dev/null +++ b/assets/scss/layouts/products/_featuredPromotions.scss @@ -0,0 +1,47 @@ +// ============================================================================= +// FEATURED PROMOTIONS (CSS) +// ============================================================================= +// +// Chip-style callouts rendered inside product cards, list items, and on PDP. +// +// Markup is server-rendered by `templates/components/products/featured-promotion-callouts.html` +// from the `featured_promotions` array on the Stencil product context (PROMO-1488). +// The container is only emitted when the array is non-empty, so there is no +// `hidden`/`is-loaded` toggling here. + +.featuredPromotions { + display: flex; + flex-wrap: wrap; + gap: spacing("eighth"); + list-style: none; + margin: spacing("eighth") 0 0; + padding: 0; +} + +.featuredPromotions-chip { + background: stencilColor("color_badge_product_sale_badges"); + border-radius: 2px; + color: stencilColor("color_text_product_sale_badges"); + display: inline-block; + font-size: rem-calc(12px); + font-weight: 600; + line-height: rem-calc(16px); + padding: spacing("eighth") spacing("third"); + text-transform: uppercase; + transition: background-color 800ms ease; +} + +.product:hover .featuredPromotions-chip { + background: stencilColor("color_hover_product_sale_badges"); +} + +.productView .featuredPromotions { + margin-top: spacing("half"); + + .featuredPromotions-chip { + font-size: rem-calc(13px); + line-height: rem-calc(18px); + padding: spacing("eighth") spacing("half"); + text-transform: none; + } +} diff --git a/lang/en.json b/lang/en.json index d7c996e1ad..0acef78c07 100755 --- a/lang/en.json +++ b/lang/en.json @@ -833,7 +833,10 @@ "suffix": "each" } }, - "card_default_image_alt": "Image coming soon" + "card_default_image_alt": "Image coming soon", + "featured_promotions": { + "aria_label": "Featured promotions" + } }, "invoice": { "for_order": "{name} Invoice for Order #{id}", diff --git a/templates/components/brand/product-listing.html b/templates/components/brand/product-listing.html index 2e2a9c6ff9..9fc5d11429 100644 --- a/templates/components/brand/product-listing.html +++ b/templates/components/brand/product-listing.html @@ -4,9 +4,9 @@
{{#if theme_settings.product_list_display_mode '===' 'grid'}} - {{> components/products/grid products=brand.products show_compare=brand.show_compare theme_settings=theme_settings event="list"}} + {{> components/products/grid products=brand.products show_compare=brand.show_compare theme_settings=theme_settings event="list" show_featured_promotions=true}} {{else}} - {{> components/products/list products=brand.products show_compare=brand.show_compare theme_settings=theme_settings event="list"}} + {{> components/products/list products=brand.products show_compare=brand.show_compare theme_settings=theme_settings event="list" show_featured_promotions=true}} {{/if}}
diff --git a/templates/components/category/product-listing.html b/templates/components/category/product-listing.html index f8980d248e..06a75bfc80 100644 --- a/templates/components/category/product-listing.html +++ b/templates/components/category/product-listing.html @@ -5,9 +5,9 @@
{{#if theme_settings.product_list_display_mode '===' 'grid'}} - {{> components/products/grid products=category.products show_compare=category.show_compare theme_settings=theme_settings event="list" }} + {{> components/products/grid products=category.products show_compare=category.show_compare theme_settings=theme_settings event="list" show_featured_promotions=true }} {{else}} - {{> components/products/list products=category.products show_compare=category.show_compare theme_settings=theme_settings event="list" }} + {{> components/products/list products=category.products show_compare=category.show_compare theme_settings=theme_settings event="list" show_featured_promotions=true }} {{/if}}
diff --git a/templates/components/products/card.html b/templates/components/products/card.html index c90f62e76a..695583255e 100644 --- a/templates/components/products/card.html +++ b/templates/components/products/card.html @@ -132,6 +132,9 @@

{{> components/common/login-for-pricing}} {{/or}} + {{#if show_featured_promotions}} + {{> components/products/featured-promotion-callouts callouts=featured_promotions}} + {{/if}} {{{region name="product_item_below_price"}}} {{> components/products/bulk-discount-rates}} diff --git a/templates/components/products/featured-promotion-callouts.html b/templates/components/products/featured-promotion-callouts.html new file mode 100644 index 0000000000..cf7601d019 --- /dev/null +++ b/templates/components/products/featured-promotion-callouts.html @@ -0,0 +1,23 @@ +{{!-- + Renders "Featured Promotion" callout chips for a product. + + Source: server-rendered Stencil context. The Storefront service populates + `product.featured_promotions` (PROMO-1488) on: + - the product details page object (PDP) + - each product card in category/brand/search listings (PLP) + via the GraphQL `Product.featuredPromotions` field, gated by the + `PROMO-1488.featured_promotions_in_graphql_enabled` LaunchDarkly flag. + + When the flag is off (or no callouts apply), `featured_promotions` is + omitted from the Stencil context and the block below renders nothing. + + Caller: pass the product's `featured_promotions` array as `callouts`, + e.g. `{{> components/products/featured-promotion-callouts callouts=product.featured_promotions }}`. +--}} +{{#if callouts.length}} + +{{/if}} diff --git a/templates/components/products/grid.html b/templates/components/products/grid.html index 51c8ffcb00..bfca8953c2 100644 --- a/templates/components/products/grid.html +++ b/templates/components/products/grid.html @@ -1,7 +1,7 @@ diff --git a/templates/components/products/list-item.html b/templates/components/products/list-item.html index b2678a4ab1..2dcc5625b2 100644 --- a/templates/components/products/list-item.html +++ b/templates/components/products/list-item.html @@ -86,6 +86,9 @@

{{#or customer (unless settings.hide_price_from_guests)}} {{#if price}}
{{> components/products/price price=price}}
+ {{#if show_featured_promotions}} + {{> components/products/featured-promotion-callouts callouts=featured_promotions}} + {{/if}} {{{region name="product_item_below_price"}}} {{/if}} {{else}} diff --git a/templates/components/products/list.html b/templates/components/products/list.html index 4251cfb752..b5d5697374 100644 --- a/templates/components/products/list.html +++ b/templates/components/products/list.html @@ -1,7 +1,7 @@ diff --git a/templates/components/products/product-view.html b/templates/components/products/product-view.html index 162ca95931..2939bb9bec 100644 --- a/templates/components/products/product-view.html +++ b/templates/components/products/product-view.html @@ -121,6 +121,7 @@

{{> components/common/login-for-pricing}} {{/or}} + {{> components/products/featured-promotion-callouts callouts=product.featured_promotions}} {{{region name="product_below_price"}}}
{{#if settings.show_product_rating}} diff --git a/templates/components/search/product-listing.html b/templates/components/search/product-listing.html index 97d62a9578..aafaa8e9ca 100644 --- a/templates/components/search/product-listing.html +++ b/templates/components/search/product-listing.html @@ -5,9 +5,9 @@ {{/if}}
{{#if theme_settings.product_list_display_mode '===' 'grid'}} - {{> components/products/grid products=product_results.products show_compare=product_results.show_compare event="list" theme_settings=theme_settings}} + {{> components/products/grid products=product_results.products show_compare=product_results.show_compare event="list" theme_settings=theme_settings show_featured_promotions=true}} {{else}} - {{> components/products/list products=product_results.products show_compare=product_results.show_compare event="list" theme_settings=theme_settings}} + {{> components/products/list products=product_results.products show_compare=product_results.show_compare event="list" theme_settings=theme_settings show_featured_promotions=true}} {{/if}}