diff --git a/libs/blocks/merch-card/merch-card.js b/libs/blocks/merch-card/merch-card.js index 5197f28e28..43a5f2d2aa 100644 --- a/libs/blocks/merch-card/merch-card.js +++ b/libs/blocks/merch-card/merch-card.js @@ -2,7 +2,6 @@ import { decorateButtons, decorateBlockHrs } from '../../utils/decorate.js'; import { getConfig, createTag, loadStyle } from '../../utils/utils.js'; import { getMetadata } from '../section-metadata/section-metadata.js'; import { processTrackingLabels } from '../../martech/attributes.js'; -import { replaceKey } from '../../features/placeholders.js'; import '../../deps/mas/merch-card.js'; const TAG_PATTERN = /^[a-zA-Z0-9_-]+:[a-zA-Z0-9_-]+\/[a-zA-Z0-9_-].*$/; @@ -403,6 +402,19 @@ const updateBigPrices = (merchCard) => { }); }; +const addStartingAt = async (styles, merchCard) => { + if (styles.includes('starting-at')) { + const { replaceKey } = await import('../../features/placeholders.js'); + await replaceKey('starting-at', getConfig()).then((key) => { + const startingAt = createTag('div', { slot: 'starting-at' }, key); + const price = merchCard.querySelector('span[is="inline-price"]'); + if (price) { + price.parentNode.prepend(startingAt); + } + }); + } +}; + export default async function init(el) { if (!el.querySelector(INNER_ELEMENTS_SELECTOR)) return el; const styles = [...el.classList]; @@ -535,6 +547,7 @@ export default async function init(el) { addStock(merchCard, styles); if (styles.includes('secure')) { + const { replaceKey } = await import('../../features/placeholders.js'); await replaceKey('secure-transaction', getConfig()).then((key) => merchCard.setAttribute('secure-label', key)); } merchCard.setAttribute('filters', categories.join(',')); @@ -571,7 +584,9 @@ export default async function init(el) { } } } + updateBigPrices(merchCard); + await addStartingAt(styles, merchCard); decorateBlockHrs(merchCard); simplifyHrs(merchCard); if (merchCard.classList.contains('has-divider')) merchCard.setAttribute('custom-hr', true); diff --git a/libs/deps/mas/merch-card.js b/libs/deps/mas/merch-card.js index 5eef677cca..207973a952 100644 --- a/libs/deps/mas/merch-card.js +++ b/libs/deps/mas/merch-card.js @@ -23,7 +23,7 @@ import{html as o,LitElement as K,nothing as Q}from"/libs/deps/lit-all.min.js";im width: var(--img-width); height: var(--img-height); } - `};customElements.define("merch-icon",m);var U=localStorage.getItem("masAccessToken"),_={Authorization:`Bearer ${U}`,pragma:"no-cache","cache-control":"no-cache"};async function G({path:c,query:e}){let t={};c&&(t.path=c),e&&(t.fullText={text:encodeURIComponent(e),queryMode:"EXACT_WORDS"});let r=new URLSearchParams({query:JSON.stringify({filter:t})}).toString();return fetch(`${this.cfSearchUrl}?${r}`,{headers:_}).then(n=>n.json()).then(({items:n})=>n)}async function W(c){return fetch(`${this.cfFragmentsUrl}?path=${c}`,{headers:_}).then(e=>e.json()).then(({items:[e]})=>e)}var w=class{sites={cf:{fragments:{search:G.bind(this),getCfByPath:W.bind(this)}}};constructor(e){let r=`${`https://${e}.adobeaemcloud.com`}/adobe/sites`;this.cfFragmentsUrl=`${r}/cf/fragments`,this.cfSearchUrl=`${this.cfFragmentsUrl}/search`}};var A="merch-offer-select:ready",M="merch-card:ready",R="merch-card:action-menu-toggle";var C="merch-storage:change",k="merch-quantity-selector:change";function L(c){let e=[];function t(r){r.nodeType===Node.TEXT_NODE?e.push(r):r.childNodes.forEach(t)}return t(c),e}function x(c,e={},t){let r=document.createElement(c);r.innerHTML=t;for(let[n,a]of Object.entries(e))r.setAttribute(n,a);return r}function O(){return window.matchMedia("(max-width: 767px)").matches}function N(){return window.matchMedia("(max-width: 1024px)").matches}var H="aem-bucket",B={catalog:{name:"catalog",title:{tag:"h3",slot:"heading-xs"},prices:{tag:"h3",slot:"heading-xs"},description:{tag:"div",slot:"body-xs"},ctas:{size:"l"}},ah:{name:"ah",title:{tag:"h3",slot:"heading-xxs"},prices:{tag:"h3",slot:"heading-xs"},description:{tag:"div",slot:"body-xxs"},ctas:{size:"s"}},"ccd-action":{name:"ccd-action",title:{tag:"h3",slot:"heading-xs"},prices:{tag:"h3",slot:"heading-xs"},description:{tag:"div",slot:"body-xs"},ctas:{size:"l"}}};async function Y(c,e){let t=c.fields.reduce((a,{name:i,multiple:u,values:$})=>(a[i]=u?$:$[0],a),{}),{type:r="catalog"}=t,n=B[r]||B.catalog;if(e.variant=r,e.setAttribute("variant",r),t.icon?.forEach(a=>{let i=x("merch-icon",{slot:"icons",src:a,alt:"",href:"",size:"l"});e.append(i)}),t.title&&e.append(x(n.title.tag,{slot:n.title.slot},t.title)),t.prices){let a=t.prices,i=x(n.prices.tag,{slot:n.prices.slot},a);e.append(i)}if(e.append(x("p",{slot:"body-xxs",id:"individuals1"},"Desktop")),t.description){let a=x(n.description.tag,{slot:n.description.slot},t.description);e.append(a)}if(t.ctas){let a=t.ctas,i=x("div",{slot:"footer"},a);e.append(i)}}var z=class{#e=new Map;clear(){this.#e.clear()}add(...e){e.forEach(t=>{let{path:r}=t;r&&this.#e.set(r,t)})}has(e){return this.#e.has(e)}get(e){return this.#e.get(e)}remove(e){this.#e.delete(e)}},P=new z,l=class extends HTMLElement{#e;cache=P;path;static get observedAttributes(){return["source","path"]}attributeChangedCallback(e,t,r){this[e]=r}connectedCallback(){let e=this.getAttribute(H)??document.querySelector("mas-studio")?.getAttribute(H);this.#e=new w(e),this.fetchData()}refresh(){this.cache.remove(this.path),this.fetchData()}async fetchData(){let e=P.get(this.path);if(e||(e=await this.#e.sites.cf.fragments.getCfByPath(this.path)),e){Y(e,this.parentElement),this.render();return}this.render()}async render(){this.isConnected&&this.parentElement.tagName==="MERCH-CARD"&&await Promise.all([...this.parentElement.querySelectorAll('[is="inline-price"],[is="checkout-link"]')].map(e=>e.onceSettled()))}};customElements.define("merch-datasource",l);import{css as S,unsafeCSS as y}from"/libs/deps/lit-all.min.js";var v="(max-width: 767px)",b="(max-width: 1199px)",h="(min-width: 768px)",s="(min-width: 1200px)",d="(min-width: 1600px)";var D=S` + `};customElements.define("merch-icon",m);var U=localStorage.getItem("masAccessToken"),A={Authorization:`Bearer ${U}`,pragma:"no-cache","cache-control":"no-cache"};async function G({path:c,query:e}){let t={};c&&(t.path=c),e&&(t.fullText={text:encodeURIComponent(e),queryMode:"EXACT_WORDS"});let r=new URLSearchParams({query:JSON.stringify({filter:t})}).toString();return fetch(`${this.cfSearchUrl}?${r}`,{headers:A}).then(n=>n.json()).then(({items:n})=>n)}async function W(c){return fetch(`${this.cfFragmentsUrl}?path=${c}`,{headers:A}).then(e=>e.json()).then(({items:[e]})=>e)}var w=class{sites={cf:{fragments:{search:G.bind(this),getCfByPath:W.bind(this)}}};constructor(e){let r=`${`https://${e}.adobeaemcloud.com`}/adobe/sites`;this.cfFragmentsUrl=`${r}/cf/fragments`,this.cfSearchUrl=`${this.cfFragmentsUrl}/search`}};var _="merch-offer-select:ready",M="merch-card:ready",R="merch-card:action-menu-toggle";var C="merch-storage:change",k="merch-quantity-selector:change";function L(c){let e=[];function t(r){r.nodeType===Node.TEXT_NODE?e.push(r):r.childNodes.forEach(t)}return t(c),e}function x(c,e={},t){let r=document.createElement(c);r.innerHTML=t;for(let[n,a]of Object.entries(e))r.setAttribute(n,a);return r}function O(){return window.matchMedia("(max-width: 767px)").matches}function N(){return window.matchMedia("(max-width: 1024px)").matches}var H="aem-bucket",B={catalog:{name:"catalog",title:{tag:"h3",slot:"heading-xs"},prices:{tag:"h3",slot:"heading-xs"},description:{tag:"div",slot:"body-xs"},ctas:{size:"l"}},ah:{name:"ah",title:{tag:"h3",slot:"heading-xxs"},prices:{tag:"h3",slot:"heading-xs"},description:{tag:"div",slot:"body-xxs"},ctas:{size:"s"}},"ccd-action":{name:"ccd-action",title:{tag:"h3",slot:"heading-xs"},prices:{tag:"h3",slot:"heading-xs"},description:{tag:"div",slot:"body-xs"},ctas:{size:"l"}}};async function Y(c,e){let t=c.fields.reduce((a,{name:i,multiple:u,values:$})=>(a[i]=u?$:$[0],a),{}),{type:r="catalog"}=t,n=B[r]||B.catalog;if(e.variant=r,e.setAttribute("variant",r),t.icon?.forEach(a=>{let i=x("merch-icon",{slot:"icons",src:a,alt:"",href:"",size:"l"});e.append(i)}),t.title&&e.append(x(n.title.tag,{slot:n.title.slot},t.title)),t.prices){let a=t.prices,i=x(n.prices.tag,{slot:n.prices.slot},a);e.append(i)}if(e.append(x("p",{slot:"body-xxs",id:"individuals1"},"Desktop")),t.description){let a=x(n.description.tag,{slot:n.description.slot},t.description);e.append(a)}if(t.ctas){let a=t.ctas,i=x("div",{slot:"footer"},a);e.append(i)}}var z=class{#e=new Map;clear(){this.#e.clear()}add(...e){e.forEach(t=>{let{path:r}=t;r&&this.#e.set(r,t)})}has(e){return this.#e.has(e)}get(e){return this.#e.get(e)}remove(e){this.#e.delete(e)}},P=new z,l=class extends HTMLElement{#e;cache=P;path;static get observedAttributes(){return["source","path"]}attributeChangedCallback(e,t,r){this[e]=r}connectedCallback(){let e=this.getAttribute(H)??document.querySelector("mas-studio")?.getAttribute(H);this.#e=new w(e),this.fetchData()}refresh(){this.cache.remove(this.path),this.fetchData()}async fetchData(){let e=P.get(this.path);if(e||(e=await this.#e.sites.cf.fragments.getCfByPath(this.path)),e){Y(e,this.parentElement),this.render();return}this.render()}async render(){this.isConnected&&this.parentElement.tagName==="MERCH-CARD"&&await Promise.all([...this.parentElement.querySelectorAll('[is="inline-price"],[is="checkout-link"]')].map(e=>e.onceSettled()))}};customElements.define("merch-datasource",l);import{css as S,unsafeCSS as y}from"/libs/deps/lit-all.min.js";var v="(max-width: 767px)",b="(max-width: 1199px)",h="(min-width: 768px)",s="(min-width: 1200px)",d="(min-width: 1600px)";var D=S` :host { position: relative; display: flex; @@ -609,6 +609,12 @@ merch-card:not([variant='inline-heading']) [slot='heading-xs'] a { color: var(--merch-color-grey-80); } +merch-card [slot='starting-at'] { + font-size: var(--consonant-merch-card-body-xs-font-size); + line-height: var(--consonant-merch-card-body-xs-line-height); + font-weight: 500; +} + merch-card [slot='heading-xs'] a:not(:hover) { text-decoration: inherit; } @@ -1523,7 +1529,7 @@ body.merch-modal { `:o`
${this.secureLabelFooter} - `}`}get promoBottom(){return this.classList.contains("promo-bottom")}renderSegment(){return o` ${this.badge} + `}`}get promoBottom(){return this.classList.contains("promo-bottom")}get startingAt(){return this.classList.contains("starting-at")}renderSegment(){return o` ${this.badge}
@@ -1631,5 +1637,5 @@ body.merch-modal { ${this.promoBottom?o``:o``} ${this.defaultSlot} -
`}connectedCallback(){super.connectedCallback(),this.#e=this.getContainer(),this.setAttribute("tabindex",this.getAttribute("tabindex")??"0"),this.addEventListener("mouseleave",this.toggleActionMenu),this.addEventListener(k,this.handleQuantitySelection),this.addEventListener(A,this.merchCardReady,{once:!0}),this.updateComplete.then(()=>{this.merchCardReady()}),this.storageOptions?.addEventListener("change",this.handleStorageChange)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(k,this.handleQuantitySelection),this.storageOptions?.removeEventListener(C,this.handleStorageChange)}appendInvisibleSpacesToFooterLinks(){[...this.querySelectorAll('[slot="footer"] a')].forEach(e=>{L(e).forEach(r=>{let i=r.textContent.split(" ").map(u=>u.match(/.{1,7}/g)?.join("\u200B")).join(" ");r.textContent=i})})}updateMiniCompareElementMinHeight(e,t){let r=`--consonant-merch-card-mini-compare-${t}-height`,n=Math.max(0,parseInt(window.getComputedStyle(e).height)||0),a=parseInt(this.#e.style.getPropertyValue(r))||0;n>a&&this.#e.style.setProperty(r,`${n}px`)}async adjustTitleWidth(){if(!["segment","plans"].includes(this.variant))return;let e=this.getBoundingClientRect().width,t=this.badgeElement?.getBoundingClientRect().width||0;e===0||t===0||this.style.setProperty("--consonant-merch-card-heading-xs-max-width",`${Math.round(e-t-16)}px`)}async adjustMiniCompareBodySlots(){if(this.variant!==E||this.getBoundingClientRect().width===0)return;this.updateMiniCompareElementMinHeight(this.shadowRoot.querySelector(".top-section"),"top-section"),["heading-m","body-m","heading-m-price","price-commitment","offers","promo-text","callout-content","secure-transaction-label"].forEach(r=>this.updateMiniCompareElementMinHeight(this.shadowRoot.querySelector(`slot[name="${r}"]`),r)),this.updateMiniCompareElementMinHeight(this.shadowRoot.querySelector("footer"),"footer");let t=this.shadowRoot.querySelector(".mini-compare-chart-badge");t&&t.textContent!==""&&this.#e.style.setProperty("--consonant-merch-card-mini-compare-top-section-mobile-height","32px")}adjustMiniCompareFooterRows(){if(this.variant!==E||this.getBoundingClientRect().width===0)return;[...this.querySelector('[slot="footer-rows"]').children].forEach((t,r)=>{let n=Math.max(Z,parseInt(window.getComputedStyle(t).height)||0),a=parseInt(this.#e.style.getPropertyValue(j(r+1)))||0;n>a&&this.#e.style.setProperty(j(r+1),`${n}px`)})}removeEmptyRows(){if(this.variant!==E)return;this.querySelectorAll(".footer-row-cell").forEach(t=>{let r=t.querySelector(".footer-row-cell-description");r&&!r.textContent.trim()&&t.remove()})}get storageOptions(){return this.querySelector("sp-radio-group#storage")}get storageSpecificOfferSelect(){let e=this.storageOptions?.selected;if(e){let t=this.querySelector(`merch-offer-select[storage="${e}"]`);if(t)return t}return this.querySelector("merch-offer-select")}get offerSelect(){return this.storageOptions?this.storageSpecificOfferSelect:this.querySelector("merch-offer-select")}get quantitySelect(){return this.querySelector("merch-quantity-select")}merchCardReady(){this.offerSelect&&!this.offerSelect.planType||this.dispatchEvent(new CustomEvent(M,{bubbles:!0}))}handleStorageChange(){let e=this.closest("merch-card")?.offerSelect.cloneNode(!0);e&&this.dispatchEvent(new CustomEvent(C,{detail:{offerSelect:e},bubbles:!0}))}get dynamicPrice(){return this.querySelector('[slot="price"]')}selectMerchOffer(e){if(e===this.merchOffer)return;this.merchOffer=e;let t=this.dynamicPrice;if(e.price&&t){let r=e.price.cloneNode(!0);t.onceSettled?t.onceSettled().then(()=>{t.replaceWith(r)}):t.replaceWith(r)}}};customElements.define(g,p); + `}connectedCallback(){super.connectedCallback(),this.#e=this.getContainer(),this.setAttribute("tabindex",this.getAttribute("tabindex")??"0"),this.addEventListener("mouseleave",this.toggleActionMenu),this.addEventListener(k,this.handleQuantitySelection),this.addEventListener(_,this.merchCardReady,{once:!0}),this.updateComplete.then(()=>{this.merchCardReady()}),this.storageOptions?.addEventListener("change",this.handleStorageChange)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(k,this.handleQuantitySelection),this.storageOptions?.removeEventListener(C,this.handleStorageChange)}appendInvisibleSpacesToFooterLinks(){[...this.querySelectorAll('[slot="footer"] a')].forEach(e=>{L(e).forEach(r=>{let i=r.textContent.split(" ").map(u=>u.match(/.{1,7}/g)?.join("\u200B")).join(" ");r.textContent=i})})}updateMiniCompareElementMinHeight(e,t){let r=`--consonant-merch-card-mini-compare-${t}-height`,n=Math.max(0,parseInt(window.getComputedStyle(e).height)||0),a=parseInt(this.#e.style.getPropertyValue(r))||0;n>a&&this.#e.style.setProperty(r,`${n}px`)}async adjustTitleWidth(){if(!["segment","plans"].includes(this.variant))return;let e=this.getBoundingClientRect().width,t=this.badgeElement?.getBoundingClientRect().width||0;e===0||t===0||this.style.setProperty("--consonant-merch-card-heading-xs-max-width",`${Math.round(e-t-16)}px`)}async adjustMiniCompareBodySlots(){if(this.variant!==E||this.getBoundingClientRect().width===0)return;this.updateMiniCompareElementMinHeight(this.shadowRoot.querySelector(".top-section"),"top-section"),["heading-m","body-m","heading-m-price","price-commitment","offers","promo-text","callout-content","secure-transaction-label"].forEach(r=>this.updateMiniCompareElementMinHeight(this.shadowRoot.querySelector(`slot[name="${r}"]`),r)),this.updateMiniCompareElementMinHeight(this.shadowRoot.querySelector("footer"),"footer");let t=this.shadowRoot.querySelector(".mini-compare-chart-badge");t&&t.textContent!==""&&this.#e.style.setProperty("--consonant-merch-card-mini-compare-top-section-mobile-height","32px")}adjustMiniCompareFooterRows(){if(this.variant!==E||this.getBoundingClientRect().width===0)return;[...this.querySelector('[slot="footer-rows"]').children].forEach((t,r)=>{let n=Math.max(Z,parseInt(window.getComputedStyle(t).height)||0),a=parseInt(this.#e.style.getPropertyValue(j(r+1)))||0;n>a&&this.#e.style.setProperty(j(r+1),`${n}px`)})}removeEmptyRows(){if(this.variant!==E)return;this.querySelectorAll(".footer-row-cell").forEach(t=>{let r=t.querySelector(".footer-row-cell-description");r&&!r.textContent.trim()&&t.remove()})}get storageOptions(){return this.querySelector("sp-radio-group#storage")}get storageSpecificOfferSelect(){let e=this.storageOptions?.selected;if(e){let t=this.querySelector(`merch-offer-select[storage="${e}"]`);if(t)return t}return this.querySelector("merch-offer-select")}get offerSelect(){return this.storageOptions?this.storageSpecificOfferSelect:this.querySelector("merch-offer-select")}get quantitySelect(){return this.querySelector("merch-quantity-select")}merchCardReady(){this.offerSelect&&!this.offerSelect.planType||this.dispatchEvent(new CustomEvent(M,{bubbles:!0}))}handleStorageChange(){let e=this.closest("merch-card")?.offerSelect.cloneNode(!0);e&&this.dispatchEvent(new CustomEvent(C,{detail:{offerSelect:e},bubbles:!0}))}get dynamicPrice(){return this.querySelector('[slot="price"]')}selectMerchOffer(e){if(e===this.merchOffer)return;this.merchOffer=e;let t=this.dynamicPrice;if(e.price&&t){let r=e.price.cloneNode(!0);t.onceSettled?t.onceSettled().then(()=>{t.replaceWith(r)}):t.replaceWith(r)}}};customElements.define(g,p); //# sourceMappingURL=merch-card.js.map diff --git a/libs/deps/mas/plans-modal.js b/libs/deps/mas/plans-modal.js index 8d6f889bcc..f11476a023 100644 --- a/libs/deps/mas/plans-modal.js +++ b/libs/deps/mas/plans-modal.js @@ -5206,6 +5206,12 @@ merch-card:not([variant='inline-heading']) [slot='heading-xs'] a { color: var(--merch-color-grey-80); } +merch-card [slot='starting-at'] { + font-size: var(--consonant-merch-card-body-xs-font-size); + line-height: var(--consonant-merch-card-body-xs-line-height); + font-weight: 500; +} + merch-card [slot='heading-xs'] a:not(:hover) { text-decoration: inherit; } diff --git a/libs/features/mas/web-components/src/global.css.js b/libs/features/mas/web-components/src/global.css.js index 888e503630..fa073f83bc 100644 --- a/libs/features/mas/web-components/src/global.css.js +++ b/libs/features/mas/web-components/src/global.css.js @@ -206,6 +206,12 @@ merch-card:not([variant='inline-heading']) [slot='heading-xs'] a { color: var(--merch-color-grey-80); } +merch-card [slot='starting-at'] { + font-size: var(--consonant-merch-card-body-xs-font-size); + line-height: var(--consonant-merch-card-body-xs-line-height); + font-weight: 500; +} + merch-card [slot='heading-xs'] a:not(:hover) { text-decoration: inherit; } diff --git a/libs/features/mas/web-components/src/merch-card.js b/libs/features/mas/web-components/src/merch-card.js index 6207681dea..82b022c76d 100644 --- a/libs/features/mas/web-components/src/merch-card.js +++ b/libs/features/mas/web-components/src/merch-card.js @@ -375,7 +375,11 @@ export class MerchCard extends LitElement { get promoBottom() { return this.classList.contains('promo-bottom'); - } + } + + get startingAt() { + return this.classList.contains('starting-at'); + } renderSegment() { return html` ${this.badge} diff --git a/libs/features/mas/web-components/test/merch-card.test.html b/libs/features/mas/web-components/test/merch-card.test.html index 6378f48c27..840aecddce 100644 --- a/libs/features/mas/web-components/test/merch-card.test.html +++ b/libs/features/mas/web-components/test/merch-card.test.html @@ -950,7 +950,7 @@

Save now - diff --git a/test/blocks/merch-card/mocks/plans-card.html b/test/blocks/merch-card/mocks/plans-card.html index 79479d5c20..c478d935af 100644 --- a/test/blocks/merch-card/mocks/plans-card.html +++ b/test/blocks/merch-card/mocks/plans-card.html @@ -47,7 +47,7 @@
this promo is great see terms
-
+
#EDCC2D, #000000
LOREM IPSUM DOLOR
diff --git a/test/blocks/merch-card/mocks/segment-card.html b/test/blocks/merch-card/mocks/segment-card.html index dfe664cb8c..59bd144d5c 100644 --- a/test/blocks/merch-card/mocks/segment-card.html +++ b/test/blocks/merch-card/mocks/segment-card.html @@ -1,9 +1,10 @@
-
+
+ $59.99

Lorem ipsum dolor sit amet

this promo is great see terms

Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna. Nunc viverra imperdiet enim.