Skip to content

Commit

Permalink
[MWPW-158004] Fix callout & grey line alignment issues in product mer…
Browse files Browse the repository at this point in the history
…ch cards (adobecom#2946)

* Fix for MWPW-158004

* remove comments

* Adjust slots

* button fix

* add new body-lower slot for product card

* update deps

* Add unit test

* Add local unit test case for mas

* Add eventlistener to resize

* removed debug statements and comments

* UT failure

* Review comment

* ccov

* review comments
  • Loading branch information
rahulgupta999 authored and Jens Singler committed Oct 7, 2024
1 parent 4e0704d commit b57cb87
Show file tree
Hide file tree
Showing 13 changed files with 753 additions and 207 deletions.
4 changes: 4 additions & 0 deletions libs/blocks/merch-card/merch-card.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ div[class*="-merch-card"] > div,
display: none;
}

merch-card .body-lower > hr {
width: 100%
}

.merch-card-price {
margin-top: 8px;
margin-bottom: 16px;
Expand Down
18 changes: 17 additions & 1 deletion libs/blocks/merch-card/merch-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,22 @@ const simplifyHrs = (el) => {
hr.parentElement.replaceWith(hr);
}
});
if (el.variant === PRODUCT) {
const calloutContent = el.querySelector('div[slot="callout-content"]');
const bodySlot = el.querySelector('div[slot="body-xs"]');
if (calloutContent && bodySlot) {
const bodyLowerContent = createTag('div', { slot: 'body-lower' });
const elements = [...bodySlot.children];
elements.forEach((element) => {
if (element.tagName !== 'P') {
bodyLowerContent.append(element);
}
});
if (bodyLowerContent.childNodes.length > 0) {
calloutContent.parentElement.appendChild(bodyLowerContent);
}
}
}
};

const getMiniCompareChartFooterRows = (el) => {
Expand Down Expand Up @@ -496,7 +512,7 @@ export default async function init(el) {
}
}
let footerRows;
if ([MINI_COMPARE_CHART, PLANS, SEGMENT].includes(cardType)) {
if ([MINI_COMPARE_CHART, PLANS, SEGMENT, PRODUCT].includes(cardType)) {
intersectionObserver.observe(merchCard);
}
if (cardType === MINI_COMPARE_CHART) {
Expand Down
298 changes: 204 additions & 94 deletions libs/deps/mas/mas.js

Large diffs are not rendered by default.

164 changes: 95 additions & 69 deletions libs/deps/mas/merch-card.js

Large diffs are not rendered by default.

40 changes: 39 additions & 1 deletion libs/features/mas/mocks/offers.json
Original file line number Diff line number Diff line change
Expand Up @@ -1102,5 +1102,43 @@
"language": "MULT",
"merchant": "ADOBE"
}
]
],
"nTbB50pS4lLGv_x1l_UKggd-lxxo2zAJ7WYDa2mW19s-mult": [
{
"offerSelectorIds": [
"nTbB50pS4lLGv_x1l_UKggd-lxxo2zAJ7WYDa2mW19s"
],
"offerId": "44C623423443E5D4D7F53719C25F71D7",
"startDate": "2022-08-08T07:00:00.000Z",
"endDate": "2099-12-20T07:58:00.000Z",
"priceDetails": {
"price": 22.19,
"priceWithoutDiscount": 23.99,
"priceWithoutTax": 22.19,
"priceWithoutDiscountAndTax": 23.99,
"usePrecision": true,
"formatString": "'US$'#,##0.00",
"taxDisplay": "TAX_EXCLUSIVE",
"taxTerm": "TAX"
},
"analytics": "{\"offerId\":\"44C623423443E5D4D7F53719C25F71D7\",\"label\":\"acrobat_pro_dc_plus_sign_funnel_team\",\"price\":\"22.19\",\"amountWithoutTax\":\"22.19\",\"commitmentType\":\"YEAR\",\"billingFrequency\":\"MONTHLY\",\"currencyCode\":\"USD\"}",
"productArrangementCode": "acrobat_pro_dc_plus_sign_funnel_team",
"productArrangement": {
"productFamily": "ACROBAT",
"productCode": "ASIG"
},
"buyingProgram": "RETAIL",
"commitment": "YEAR",
"term": "MONTHLY",
"customerSegment": "TEAM",
"marketSegments": [
"COM"
],
"salesChannel": "DIRECT",
"offerType": "PROMOTION",
"pricePoint": "ACROBAT_PRO_ASIG_FY22_LO_TEAM_BUNDLE_7_5_OFF_WW_COM",
"language": "MULT",
"merchant": "ADOBE"
}
]
}
53 changes: 14 additions & 39 deletions libs/features/mas/web-components/src/variants/mini-compare-chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,9 @@ export class MiniCompareChart extends VariantLayout {
super(card);
}

#container;

getRowMinHeightPropertyName = (index) =>
`--consonant-merch-card-footer-row-${index}-min-height`;

getContainer() {
this.#container = this.#container ?? this.card.closest('[class*="-merch-cards"]') ?? this.card.parentElement;
return this.#container;
}

getGlobalCSS() {
return CSS;
}
Expand All @@ -35,28 +28,10 @@ export class MiniCompareChart extends VariantLayout {
return html`<footer>${secureLabel}<slot name="footer"></slot></footer>`;
}

updateMiniCompareElementMinHeight (el, name) {
const elMinHeightPropertyName = `--consonant-merch-card-mini-compare-${name}-height`;
const height = Math.max(
0,
parseFloat(window.getComputedStyle(el).height) || 0,
);
const maxMinHeight =
parseFloat(
this.getContainer().style.getPropertyValue(elMinHeightPropertyName),
) || 0;
if (height > maxMinHeight) {
this.getContainer().style.setProperty(
elMinHeightPropertyName,
`${height}px`,
);
}
}

adjustMiniCompareBodySlots () {
if (this.card.getBoundingClientRect().width <= 2) return;

this.updateMiniCompareElementMinHeight(
this.updateCardElementMinHeight(
this.card.shadowRoot.querySelector('.top-section'),
'top-section',
);
Expand All @@ -73,12 +48,12 @@ export class MiniCompareChart extends VariantLayout {
];

slots.forEach((slot) =>
this.updateMiniCompareElementMinHeight(
this.updateCardElementMinHeight(
this.card.shadowRoot.querySelector(`slot[name="${slot}"]`),
slot,
),
);
this.updateMiniCompareElementMinHeight(
this.updateCardElementMinHeight(
this.card.shadowRoot.querySelector('footer'),
'footer',
);
Expand All @@ -88,7 +63,7 @@ export class MiniCompareChart extends VariantLayout {
);
if (badge && badge.textContent !== '') {
this.getContainer().style.setProperty(
'--consonant-merch-card-mini-compare-top-section-mobile-height',
'--consonant-merch-card-mini-compare-chart-top-section-mobile-height',
'32px',
);
}
Expand Down Expand Up @@ -158,15 +133,15 @@ export class MiniCompareChart extends VariantLayout {
display: block;
}
:host([variant='mini-compare-chart']) footer {
min-height: var(--consonant-merch-card-mini-compare-footer-height);
min-height: var(--consonant-merch-card-mini-compare-chart-footer-height);
padding: var(--consonant-merch-spacing-xs);
}
/* mini-compare card */
:host([variant='mini-compare-chart']) .top-section {
padding-top: var(--consonant-merch-spacing-s);
padding-inline-start: var(--consonant-merch-spacing-s);
height: var(--consonant-merch-card-mini-compare-top-section-height);
height: var(--consonant-merch-card-mini-compare-chart-top-section-height);
}
@media screen and ${unsafeCSS(TABLET_DOWN)} {
Expand Down Expand Up @@ -194,35 +169,35 @@ export class MiniCompareChart extends VariantLayout {
}
/* mini-compare card heights for the slots: heading-m, body-m, heading-m-price, price-commitment, offers, promo-text, footer */
:host([variant='mini-compare-chart']) slot[name='heading-m'] {
min-height: var(--consonant-merch-card-mini-compare-heading-m-height);
min-height: var(--consonant-merch-card-mini-compare-chart-heading-m-height);
}
:host([variant='mini-compare-chart']) slot[name='body-m'] {
min-height: var(--consonant-merch-card-mini-compare-body-m-height);
min-height: var(--consonant-merch-card-mini-compare-chart-body-m-height);
}
:host([variant='mini-compare-chart']) slot[name='heading-m-price'] {
min-height: var(
--consonant-merch-card-mini-compare-heading-m-price-height
--consonant-merch-card-mini-compare-chart-heading-m-price-height
);
}
:host([variant='mini-compare-chart']) slot[name='body-xxs'] {
min-height: var(
--consonant-merch-card-mini-compare-body-xxs-height
--consonant-merch-card-mini-compare-chart-body-xxs-height
);
}
:host([variant='mini-compare-chart']) slot[name='price-commitment'] {
min-height: var(
--consonant-merch-card-mini-compare-price-commitment-height
--consonant-merch-card-mini-compare-chart-price-commitment-height
);
}
:host([variant='mini-compare-chart']) slot[name='offers'] {
min-height: var(--consonant-merch-card-mini-compare-offers-height);
min-height: var(--consonant-merch-card-mini-compare-chart-offers-height);
}
:host([variant='mini-compare-chart']) slot[name='promo-text'] {
min-height: var(--consonant-merch-card-mini-compare-promo-text-height);
min-height: var(--consonant-merch-card-mini-compare-chart-promo-text-height);
}
:host([variant='mini-compare-chart']) slot[name='callout-content'] {
min-height: var(
--consonant-merch-card-mini-compare-callout-content-height
--consonant-merch-card-mini-compare-chart-callout-content-height
);
}
`;
Expand Down
66 changes: 63 additions & 3 deletions libs/features/mas/web-components/src/variants/product.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { VariantLayout } from "./variant-layout";
import { html } from 'lit';
import { isMobile } from '../utils.js';
import { html, css } from 'lit';
import { CSS } from './product.css.js';

export class Product extends VariantLayout {
Expand All @@ -11,16 +12,75 @@ export class Product extends VariantLayout {
return CSS;
}

adjustProductBodySlots() {
if (this.card.getBoundingClientRect().width === 0) return;

const slots = [
'heading-xs',
'body-xxs',
'body-xs',
'promo-text',
'callout-content',
'body-lower',
];

slots.forEach((slot) =>
this.updateCardElementMinHeight(
this.card.shadowRoot.querySelector(`slot[name="${slot}"]`),
slot
),
);
}

renderLayout() {
return html` ${this.badge}
<div class="body">
<slot name="icons"></slot>
<slot name="heading-xs"></slot>
<slot name="body-xxs"></slot>
${!this.promoBottom ? html`<slot name="promo-text"></slot><slot name="callout-content"></slot>` : ''}
${!this.promoBottom ? html`<slot name="promo-text"></slot>` : ''}
<slot name="body-xs"></slot>
${this.promoBottom ? html`<slot name="promo-text"></slot><slot name="callout-content"></slot>` : ''}
${this.promoBottom ? html`<slot name="promo-text"></slot>` : ''}
<slot name="callout-content"></slot>
<slot name="body-lower"></slot>
</div>
${this.secureLabelFooter}`;
}

connectedCallbackHook() {
super.connectedCallbackHook();
window.addEventListener('resize', this.postCardUpdateHook.bind(this));
}

postCardUpdateHook() {
if (!isMobile()) {
this.adjustProductBodySlots();
}
}

static variantStyle = css`
:host([variant='product']) > slot:not([name='icons']) {
display: block;
}
:host([variant='product']) slot[name='body-xs'] {
min-height: var(--consonant-merch-card-product-body-xs-height);
display: block;
}
:host([variant='product']) slot[name='heading-xs'] {
min-height: var(--consonant-merch-card-product-heading-xs-height);
display: block;
}
:host([variant='product']) slot[name='body-xxs'] {
min-height: var(--consonant-merch-card-product-body-xxs-height);
display: block;
}
:host([variant='product']) slot[name='promo-text'] {
min-height: var(--consonant-merch-card-product-promo-text-height);
display: block;
}
:host([variant='product']) slot[name='callout-content'] {
min-height: var(--consonant-merch-card-product-callout-content-height);
display: block;
}
`;
}
26 changes: 26 additions & 0 deletions libs/features/mas/web-components/src/variants/variant-layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ export class VariantLayout {

card;

#container;

getContainer() {
this.#container = this.#container ?? this.card.closest('[class*="-merch-cards"]') ?? this.card.parentElement;
return this.#container;
}

insertVariantStyle() {
if (!VariantLayout.styleMap[this.card.variant]) {
VariantLayout.styleMap[this.card.variant] = true;
Expand All @@ -14,6 +21,25 @@ export class VariantLayout {
}
}

updateCardElementMinHeight(el, name) {
const elMinHeightPropertyName = `--consonant-merch-card-${this.card.variant}-${name}-height`;
const height = Math.max(
0,
parseInt(window.getComputedStyle(el).height) || 0,
);
const maxMinHeight =
parseInt(
this.getContainer().style.getPropertyValue(elMinHeightPropertyName),
) || 0;

if (height > maxMinHeight) {
this.getContainer().style.setProperty(
elMinHeightPropertyName,
`${height}px`,
);
}
}

constructor(card) {
this.card = card;
this.insertVariantStyle();
Expand Down
1 change: 1 addition & 0 deletions libs/features/mas/web-components/src/variants/variants.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const getVariantStyles = () => {
styles.push(Catalog.variantStyle);
styles.push(CCDAction.variantStyle);
styles.push(MiniCompareChart.variantStyle);
styles.push(Product.variantStyle);
styles.push(Plans.variantStyle);
styles.push(Segment.variantStyle);
styles.push(SpecialOffer.variantStyle);
Expand Down
Loading

0 comments on commit b57cb87

Please sign in to comment.