From 5ff2e8eda080ccf42c7139d7b7dc521b7f793d71 Mon Sep 17 00:00:00 2001 From: Vivian A Goodrich <101133187+vgoodric@users.noreply.github.com> Date: Mon, 3 Jun 2024 09:20:20 -0600 Subject: [PATCH 01/15] MWPW-151476 and MWPW-151189 Post RCP consolidated MEP PR (#2400) * MWPW-151189 [MILO][MEP] Skip Martech timeout if blocked by ad blocker (#2383) * add lana log * MWPW-151476 [MILO][MEP] MEP Control Panel (Button) Bugs (#2387) --- libs/features/personalization/personalization.js | 3 ++- libs/martech/martech.js | 12 ++++++++++++ libs/utils/utils.js | 8 ++++++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/libs/features/personalization/personalization.js b/libs/features/personalization/personalization.js index b936ad2e12..1473eb2bf0 100644 --- a/libs/features/personalization/personalization.js +++ b/libs/features/personalization/personalization.js @@ -830,7 +830,8 @@ export async function applyPers(manifests, postLCP = false) { } = Object.fromEntries(PAGE_URL.searchParams); config.mep = { handleFragmentCommand, - preview: (mepButton !== 'off' && (config.env?.name !== 'prod' || mepButton)), + preview: (mepButton !== 'off' + && (config.env?.name !== 'prod' || mepParam || mepParam === '' || mepButton)), override: mepParam ? decodeURIComponent(mepParam) : '', highlight: (mepHighlight !== undefined && mepHighlight !== 'false'), mepParam, diff --git a/libs/martech/martech.js b/libs/martech/martech.js index ff0d5e5386..28c6d50870 100644 --- a/libs/martech/martech.js +++ b/libs/martech/martech.js @@ -1,6 +1,7 @@ import { getConfig, getMetadata, loadIms, loadLink, loadScript } from '../utils/utils.js'; const ALLOY_SEND_EVENT = 'alloy_sendEvent'; +const ALLOY_SEND_EVENT_ERROR = 'alloy_sendEvent_error'; const TARGET_TIMEOUT_MS = 4000; const ENTITLEMENT_TIMEOUT = 3000; @@ -26,6 +27,12 @@ const waitForEventOrTimeout = (eventName, timeout, returnValIfTimeout) => new Pr resolve(event.detail); }; + const errorListener = () => { + // eslint-disable-next-line no-use-before-define + clearTimeout(timer); + resolve({ error: true }); + }; + const timer = setTimeout(() => { window.removeEventListener(eventName, listener); if (returnValIfTimeout !== undefined) { @@ -36,6 +43,7 @@ const waitForEventOrTimeout = (eventName, timeout, returnValIfTimeout) => new Pr }, timeout); window.addEventListener(eventName, listener, { once: true }); + window.addEventListener(ALLOY_SEND_EVENT_ERROR, errorListener, { once: true }); }); const getExpFromParam = (expParam) => { @@ -125,6 +133,10 @@ const getTargetPersonalization = async () => { let manifests = []; const response = await waitForEventOrTimeout(ALLOY_SEND_EVENT, timeout); + if (response.error) { + window.lana.log('target response time: ad blocker', { tags: 'errorType=info,module=martech' }); + return []; + } if (response.timeout) { waitForEventOrTimeout(ALLOY_SEND_EVENT, 5100 - timeout) .then(() => sendTargetResponseAnalytics(true, responseStart, timeout)); diff --git a/libs/utils/utils.js b/libs/utils/utils.js index 26848bb389..03a167f490 100644 --- a/libs/utils/utils.js +++ b/libs/utils/utils.js @@ -829,7 +829,11 @@ export async function loadIms() { return imsLoaded; } -export async function loadMartech({ persEnabled = false, persManifests = [] } = {}) { +export async function loadMartech({ + persEnabled = false, + persManifests = [], + postLCP = false, +} = {}) { // eslint-disable-next-line no-underscore-dangle if (window.marketingtech?.adobe?.launch && window._satellite) { return true; @@ -844,7 +848,7 @@ export async function loadMartech({ persEnabled = false, persManifests = [] } = loadIms().catch(() => {}); const { default: initMartech } = await import('../martech/martech.js'); - await initMartech({ persEnabled, persManifests }); + await initMartech({ persEnabled, persManifests, postLCP }); return true; } From 69a42fe59dd32a44eba9280804096412248ea87d Mon Sep 17 00:00:00 2001 From: Siva S <163842332+sivasadobe@users.noreply.github.com> Date: Mon, 3 Jun 2024 20:50:27 +0530 Subject: [PATCH 02/15] MWPW-144756 Table - Responsive breakpoints - Text wraps under icon in Content cell (#2230) * update(MWPW-144756): fixed text wraps under icon - added css flex property for Table title text Cell. * fix(table): fixed alignment breaking when more formats applied * fix(linting): removed Trailing spaces * fix(icon): fixed style breaking when using diffrent icons * update: code optimzed --- libs/blocks/table/table.css | 1 + libs/blocks/table/table.js | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/libs/blocks/table/table.css b/libs/blocks/table/table.css index 134a985280..ea42987249 100644 --- a/libs/blocks/table/table.css +++ b/libs/blocks/table/table.css @@ -243,6 +243,7 @@ .table .section-head .section-head-title, .table .section-row .section-row-title, +.table .section-row .section-row-title .table-title-row, .table.merch .section-head .col-merch, .table.merch .section-row .col-merch { display: flex; diff --git a/libs/blocks/table/table.js b/libs/blocks/table/table.js index d1e1bf9b20..c2c35b5f9a 100644 --- a/libs/blocks/table/table.js +++ b/libs/blocks/table/table.js @@ -140,10 +140,20 @@ function handleTitleText(cell) { if (cell.querySelector('.table-title-text')) return; const textSpan = createTag('span', { class: 'table-title-text' }); while (cell.firstChild) textSpan.append(cell.firstChild); - cell.append(textSpan); + const iconTooltip = textSpan.querySelector('.icon-info, .icon-tooltip, .milo-tooltip'); - if (!iconTooltip) return; - cell.append(iconTooltip.closest('em') || iconTooltip); + if (iconTooltip) cell.append(iconTooltip.closest('em') || iconTooltip); + + const firstIcon = textSpan.querySelector('.icon:first-child'); + let nodeToInsert = textSpan; + + if (firstIcon) { + const titleRowSpan = createTag('span', { class: 'table-title-row' }); + titleRowSpan.append(firstIcon, textSpan); + nodeToInsert = titleRowSpan; + } + + cell.insertBefore(nodeToInsert, cell.firstChild); } /** From 802176732b247a5df4d3010cc2dee8e6447ecd5f Mon Sep 17 00:00:00 2001 From: Elan Bartholomew <79870969+elan-tbx@users.noreply.github.com> Date: Mon, 3 Jun 2024 09:20:34 -0600 Subject: [PATCH 03/15] MWPW-143562 - Add "radio" variant to Tabs block (#2327) * add radio variant to tabs * fix stylelint error * fixing styles based on feedback * right left whoopsie * fixes for dark applied to parent * default left * add dark mode, fix spacing * spacing fix * i18n for directional css rules, updated colors * update styles based on QA feedback --------- Co-authored-by: Robert Bogos <146744221+robert-bogos@users.noreply.github.com> --- libs/blocks/tabs/tabs.css | 166 ++++++++++++++++++++++++++++++++++---- libs/blocks/tabs/tabs.js | 8 +- 2 files changed, 156 insertions(+), 18 deletions(-) diff --git a/libs/blocks/tabs/tabs.css b/libs/blocks/tabs/tabs.css index 19b8037be0..0efb1d762f 100644 --- a/libs/blocks/tabs/tabs.css +++ b/libs/blocks/tabs/tabs.css @@ -13,6 +13,10 @@ --tabs-pill-bg-color-active: #c6c6c6; --tabs-pill-text-color: #131313; --tabs-paddle-bs-color: #0000001a; + --tabs-radio-gray: #6D6D6D; + --tabs-radio-blue: #0265DC; + --tabs-radio-bg: #fff; + --tabs-radio-button-bg: #fdfdfd; } :root .dark { @@ -27,6 +31,10 @@ --tabs-pill-bg-color-active: #444; --tabs-pill-text-color: #fff; --tabs-paddle-bs-color: #ffffff1a; + --tabs-radio-gray: #d4d4d4; + --tabs-radio-blue: #5eaaf7; + --tabs-radio-bg: #1e1e1e; + --tabs-radio-button-bg: #000; } .tabs { @@ -96,8 +104,8 @@ } /* center tabs */ -.tabs.center div[role="tablist"]::after, -.tabs.center div[role="tablist"]::before { +.tabs.center > div[role="tablist"]::after, +.tabs.center > div[role="tablist"]::before { content: ""; margin: auto; } @@ -153,6 +161,28 @@ z-index: 1; } +.tabs .tab-paddles .paddle { + position: absolute; + cursor: pointer; + width: 32px; + height: 48px; + bottom: 0; + background: var(--tabs-active-bg-color); + border: 0; + border-bottom: 1px solid var(--tabs-border-color); + padding: 14px 0 12px; + display: flex; + align-items: center; +} + +.tabs.radio div[role="tablist"], +.tabs.radio div[role="tablist"] button, +.tabs.radio .tab-paddles .paddle { + box-shadow: none; + background: none; + border: none; +} + .tabs div[role="tablist"] button:first-of-type { margin-left: 0; margin-top: 0; @@ -205,6 +235,17 @@ padding: 0.2em 1em; } +.tabs.radio div[role="tablist"] button { + background: transparent; + padding-block: 0 var(--spacing-s); + padding-inline: 0; + font-size: var(--type-body-s-size); + font-weight: normal; + color: var(--tabs-active-text-color); + display: flex; + align-items: center; +} + .tabs.quiet div[role="tablist"] button:first-of-type, .tabs[class*='pill'] div[role="tablist"] button:first-of-type { margin-inline-start: 0; @@ -267,20 +308,6 @@ z-index: 3; } -.tabs .tab-paddles .paddle { - position: absolute; - cursor: pointer; - width: 32px; - height: 48px; - bottom: 0; - background: var(--tabs-active-bg-color); - border: 0; - border-bottom: 1px solid var(--tabs-border-color); - padding: 14px 0 12px; - display: flex; - align-items: center; -} - .tabs .tab-paddles .paddle:disabled { cursor: default; box-shadow: none; @@ -323,6 +350,69 @@ border: none; } +.tabs.radio:not(.dark) { + background: none; +} + +.tabs.radio .tab-content { + border: none; +} + +.tabs.radio .tab-paddles { + display: none; +} + +.tabs.radio div[role="tablist"] { + margin-block: 0; + margin-inline: auto; + inline-size: var(--grid-container-width); +} + +.tabs.radio div[role="tablist"] .tab-list-container { + background: var(--tabs-radio-bg); + border: 1px solid var(--tabs-border-color); + border-radius: 24px; + padding-block: var(--spacing-xs) var(--spacing-s); + padding-inline: var(--spacing-s); + font-size: var(--type-body-s-size); + color: var(--tabs-active-text-color); + flex-direction: column; + align-items: start; + inline-size: 100%; +} + +.tabs.radio div[role="tablist"] button:last-of-type { + padding-inline-end: 0; + padding-block-end: 0; +} + +.tabs.radio div[role="tablist"] button::before { + content: ''; + border: 2px solid var(--tabs-radio-gray); + border-radius: 100%; + block-size: 14px; + min-inline-size: 14px; + margin-inline-end: 12px; + background: var(--tabs-radio-button-bg); + transition: border 150ms; + box-sizing: border-box; +} + +.tabs.radio div[role="tablist"] button:hover::before { + border-color: var(--tabs-radio-blue); +} + +.tabs.radio div[role="tablist"] button[aria-selected="true"]::before { + border: 5px solid var(--tabs-radio-blue); +} + +.tabs.radio .tab-list-container::before { + content: attr(data-pretext); + font-weight: var(--type-detail-all-weight); + line-height: var(--type-body-xs-lh); + margin-block-end: var(--spacing-xs); +} + /* Section Metadata */ .tabs-background-transparent .tabs, .tabs-background-transparent .tabs div[role="tablist"], @@ -331,10 +421,54 @@ background: transparent; } +.tabs.radio.center div[role="tablist"] { + justify-content: center; +} + +.tabs.radio.right div[role="tablist"] { + justify-content: end; +} + +.dark .tabs.radio .tab-list-container::before, +.dark .tabs.radio div[role="tablist"] button { + color: var(--color-white); +} + .tabs-background-transparent .tabs div[role="tablist"] button[aria-selected="true"] { border-bottom-color: var(--tabs-active-bg-color); } +@media screen and (min-width: 600px) { + .tabs.radio div[role="tablist"] .tab-list-container { + flex-direction: row; + align-items: center; + border-radius: 40px; + padding-block: 0; + padding-inline: var(--spacing-s); + inline-size: auto; + max-inline-size: var(--grid-container-width); + margin: 0; + gap: var(--spacing-s); + } + + .tabs.radio .tab-list-container::before { + margin-block-end: 0; + margin-inline-end: -8px; + } + + .tabs.radio div[role="tablist"] button { + white-space: normal; + text-align: start; + } + + .tabs.radio div[role="tablist"] button, + .tabs.radio div[role="tablist"] button:last-of-type { + padding-block: var(--spacing-xs); + padding-inline: 0; + min-block-size: 56px; + } +} + @media screen and (min-width: 1200px) { [role='tabpanel'] > .section[class*='-up'] > .content, [role='tabpanel'] > .section[class*='grid-width-'] > .content { diff --git a/libs/blocks/tabs/tabs.js b/libs/blocks/tabs/tabs.js index 55a5cf62db..df9881783d 100644 --- a/libs/blocks/tabs/tabs.js +++ b/libs/blocks/tabs/tabs.js @@ -37,13 +37,14 @@ function changeTabs(e) { const { target } = e; const parent = target.parentNode; const content = parent.parentNode.parentNode.lastElementChild; + const blockId = target.closest('.tabs').id; parent - .querySelectorAll('[aria-selected="true"]') + .querySelectorAll(`[aria-selected="true"][data-block-id="${blockId}"]`) .forEach((t) => t.setAttribute('aria-selected', false)); target.setAttribute('aria-selected', true); scrollTabIntoView(target); content - .querySelectorAll('[role="tabpanel"]') + .querySelectorAll(`[role="tabpanel"][data-block-id="${blockId}"]`) .forEach((p) => p.setAttribute('hidden', true)); content .querySelector(`#${target.getAttribute('aria-controls')}`) @@ -238,6 +239,7 @@ const init = (block) => { tabindex: '0', 'aria-selected': (i === 0) ? 'true' : 'false', 'aria-controls': `tab-panel-${tabId}-${tabName}`, + 'data-block-id': `tabs-${tabId}`, }; const tabBtn = createTag('button', tabBtnAttributes); tabBtn.innerText = item.textContent; @@ -249,6 +251,7 @@ const init = (block) => { class: 'tabpanel', tabindex: '0', 'aria-labelledby': `tab-${tabId}-${tabName}`, + 'data-block-id': `tabs-${tabId}`, }; const tabListContent = createTag('div', tabContentAttributes); tabListContent.setAttribute('aria-labelledby', `tab-${tabId}-${tabName}`); @@ -256,6 +259,7 @@ const init = (block) => { tabContentContainer.append(tabListContent); }); tabListItems[0].parentElement.remove(); + tabListContainer.dataset.pretext = config.pretext; } // Tab Paddles From 2dcb91f551d94ad268654321f79ea56fe3c00530 Mon Sep 17 00:00:00 2001 From: Siva S <163842332+sivasadobe@users.noreply.github.com> Date: Mon, 3 Jun 2024 20:50:42 +0530 Subject: [PATCH 04/15] MWPW-148439 - FIX - Text wraps under icon & No space between Icon and text in RTL Locale. (#2343) * fix: fixed text wrap;fixed icon space issue when RTL enabled * fix: removed old browser support * Update libs/styles/styles.css Co-authored-by: Rares Munteanu --------- Co-authored-by: Rares Munteanu --- libs/blocks/icon-block/icon-block.css | 5 +++++ libs/blocks/icon-block/icon-block.js | 10 +++++++++- libs/features/icons/icons.js | 6 +++--- libs/styles/styles.css | 2 ++ 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/libs/blocks/icon-block/icon-block.css b/libs/blocks/icon-block/icon-block.css index 22d9eae5ef..d0e45323af 100644 --- a/libs/blocks/icon-block/icon-block.css +++ b/libs/blocks/icon-block/icon-block.css @@ -177,6 +177,11 @@ margin-top: var(--spacing-s); } +.icon-block .foreground .second-column .title-row { + display: flex; + align-items: center; +} + .icon-block.full-width.small .foreground .icon-area, .icon-block.vertical.small .foreground .icon-area { margin-bottom: var(--spacing-s); diff --git a/libs/blocks/icon-block/icon-block.js b/libs/blocks/icon-block/icon-block.js index b7163a1f3d..5a4cfad278 100644 --- a/libs/blocks/icon-block/icon-block.js +++ b/libs/blocks/icon-block/icon-block.js @@ -70,7 +70,15 @@ function decorateContent(el) { const textContent = el.querySelectorAll('.text-content > :not(.icon-area)'); const secondColumn = createTag('div', { class: 'second-column' }); textContent.forEach((content) => { - secondColumn.append(content); + let nodeToInsert = content; + const firstIcon = content.querySelector('.icon:first-child'); + if (firstIcon) { + const titleRowSpan = createTag('span', { class: 'title-row' }); + titleRowSpan.append(firstIcon, content); + nodeToInsert = titleRowSpan; + } + + secondColumn.append(nodeToInsert); }); if (secondColumn.children.length === 1) el.classList.add('items-center'); el.querySelector('.foreground .text-content').append(secondColumn); diff --git a/libs/features/icons/icons.js b/libs/features/icons/icons.js index 53bb484b6b..dc7a127656 100644 --- a/libs/features/icons/icons.js +++ b/libs/features/icons/icons.js @@ -63,12 +63,12 @@ export default async function loadIcons(icons, config) { const parent = icon.parentElement; if (parent.childNodes.length > 1) { if (parent.lastChild === icon) { - icon.classList.add('margin-left'); + icon.classList.add('margin-inline-start'); } else if (parent.firstChild === icon) { - icon.classList.add('margin-right'); + icon.classList.add('margin-inline-end'); if (parent.parentElement.tagName === 'LI') parent.parentElement.classList.add('icon-list-item'); } else { - icon.classList.add('margin-left', 'margin-right'); + icon.classList.add('margin-inline-start', 'margin-inline-end'); } } icon.insertAdjacentHTML('afterbegin', iconSVGs[iconName].outerHTML); diff --git a/libs/styles/styles.css b/libs/styles/styles.css index 4514987e6e..6448d279e3 100644 --- a/libs/styles/styles.css +++ b/libs/styles/styles.css @@ -555,6 +555,8 @@ span.icon.margin-left { margin-left: 8px; } span.icon.margin-inline-end { margin-inline-end: 8px; } +span.icon.margin-inline-start { margin-inline-start: 8px; } + .button-l .con-button span.icon.margin-left, .con-button.button-l span.icon.margin-left { margin-left: 12px; } From a6ca0606c01b34d3d80fbb887517f7a10f848b2d Mon Sep 17 00:00:00 2001 From: Brad Johnson Date: Mon, 3 Jun 2024 10:20:49 -0500 Subject: [PATCH 05/15] MWPW-147760: Color contrast fix (#2357) MWPW-147760: Removed disabled text opacity, added disabled text style Co-authored-by: Blaine Gunn --- libs/blocks/quiz/quiz.css | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libs/blocks/quiz/quiz.css b/libs/blocks/quiz/quiz.css index f267bb5415..de738952da 100644 --- a/libs/blocks/quiz/quiz.css +++ b/libs/blocks/quiz/quiz.css @@ -165,11 +165,14 @@ html[dir="rtl"] .quiz-option-icon { } .quiz-option.disabled .quiz-option-icon, -.quiz-option.disabled .quiz-option-image, -.quiz-option.disabled .quiz-option-text-container{ +.quiz-option.disabled .quiz-option-image { opacity: 0.5; } +.quiz-option.disabled .quiz-option-text{ + color: var(--color-gray-600); +} + .quiz-button-container { align-items: center; display: flex; From 7d5c44aabe7dc3f0ef82a0a4cd784ce17c913ef9 Mon Sep 17 00:00:00 2001 From: Cody Lloyd <119891065+colloyd@users.noreply.github.com> Date: Mon, 3 Jun 2024 09:20:56 -0600 Subject: [PATCH 06/15] Quiz option card accessibility fixes (#2364) MWPW-147763 - Quiz option card accessibility fixes * remove heading tags in cards, which have the role of checkbox * set alt to "" for card icons as they are decorative images * applied both fixes to the quiz and quiz-entry blocks Resolves: [MWPW-147763](https://jira.corp.adobe.com/browse/MWPW-147763), [MWPW-147761](https://jira.corp.adobe.com/browse/MWPW-147761) **Test URLs:** - Before: https://main--milo--adobecom.hlx.page/?martech=off - After: https://--milo--adobecom.hlx.page/?martech=off --- libs/blocks/quiz-entry/quizoption.js | 4 ++-- libs/blocks/quiz/quizoption.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/blocks/quiz-entry/quizoption.js b/libs/blocks/quiz-entry/quizoption.js index 42db01b59b..d6a63de97e 100644 --- a/libs/blocks/quiz-entry/quizoption.js +++ b/libs/blocks/quiz-entry/quizoption.js @@ -18,12 +18,12 @@ export const OptionCard = ({ ${iconDesktop && html``} ${iconTablet && html``} - ${`Icon - ${title || text}`} + `; const imageHtml = image ? html`
` : null; - const titleHtml = title ? html`

${title}

` : null; + const titleHtml = title ? html`

${title}

` : null; const textHtml = text ? html`

${text}

` : null; return html`