From 2312464af63e67e9b5945e133707b091b7bbc06e Mon Sep 17 00:00:00 2001 From: Rares Munteanu Date: Fri, 17 Nov 2023 13:11:28 +0100 Subject: [PATCH] [MWPW-136943] Merge stage to main (#1561) * trivial: Update LICENSE (#1558) * [MWPW-136943] Colorful Gnav headings for A/B test (#1532) * [MWPW-136943] Colorful Gnav headings for A/B test * [MWPW-136943] Fix gnav colorful headings caret size --------- Co-authored-by: Chris Millar --- libs/blocks/global-navigation/base.css | 79 +++- .../global-navigation/global-navigation.css | 3 +- .../utilities/keyboard/utils.js | 4 +- .../global-navigation/utilities/menu/menu.css | 27 +- .../global-navigation/utilities/menu/menu.js | 25 +- .../global-navigation.test.js | 7 + .../global-navigation-wide-column.plain.js | 285 +++++++++++++ .../mocks/large-menu-wide-column.plain.js | 377 ++++++++++++++++++ .../global-navigation/test-utilities.js | 8 +- 9 files changed, 792 insertions(+), 23 deletions(-) create mode 100644 test/blocks/global-navigation/mocks/global-navigation-wide-column.plain.js create mode 100644 test/blocks/global-navigation/mocks/large-menu-wide-column.plain.js diff --git a/libs/blocks/global-navigation/base.css b/libs/blocks/global-navigation/base.css index 53c32f3433..abe9622443 100644 --- a/libs/blocks/global-navigation/base.css +++ b/libs/blocks/global-navigation/base.css @@ -64,22 +64,26 @@ color: var(--feds-color-link--light); } +.feds-navLink--hoverCaret:after, +.feds-navLink[class *= '-gradient'] .feds-navLink-title:after { + display: flex; + border-width: 0 1px 1px 0; + border-style: solid; + border-color: var(--feds-color-link--light); + transform-origin: 75% 75%; + transition: transform 0.1s ease; + box-sizing: content-box; +} + .feds-navLink--hoverCaret:after { position: absolute; right: 18px; top: 50%; - display: flex; width: 6px; height: 6px; margin-top: -3px; - border-width: 0 1px 1px 0; - border-style: solid; - border-color: var(--feds-color-link--light); - transform-origin: 75% 75%; transform: rotateZ(45deg); - transition: transform 0.1s ease; content: ""; - box-sizing: content-box; } [dir = "rtl"] .feds-navLink--hoverCaret { @@ -97,6 +101,11 @@ display: none; } +.feds-navLink-title { + display: flex; + align-items: center; +} + /* Desktop styles */ @media (min-width: 900px) { .feds-navLink, @@ -152,7 +161,8 @@ } .feds-navLink-image picture { - width: 25px; + width: max-content; + max-width: 25px; } .feds-navLink-description { @@ -165,4 +175,57 @@ .feds-navLink:focus .feds-navLink-description { color: var(--feds-color-navLink-description--light); } + + /* Nav Link special styles for A/B test */ + .feds-navLink[class *= '-gradient'] { + border-radius: 4px; + } + + .feds-navLink[class *= '-gradient']:not(:first-child) { + margin-top: 12px; + } + + .feds-navLink[class *= '-gradient'] .feds-navLink-title { + column-gap: 4px; + } + + .feds-navLink[class *= '-gradient'] .feds-navLink-title:after { + width: 4px; + height: 4px; + transform: rotate(-45deg); + content: ''; + } + + [dir = "rtl"] .feds-navLink[class *= '-gradient'] .feds-navLink-title:after { + transform: rotate(135deg); + } + + .feds-navLink[class *= '-gradient']:hover .feds-navLink-title:after, + .feds-navLink[class *= '-gradient']:focus .feds-navLink-title:after { + border-color: var(--feds-color-link--hover--light); + } + + .feds-navLink--photo-gradient { + background: linear-gradient(90deg, #d0e8fa, #cef4f4); + } + + .feds-navLink--design-gradient { + background: linear-gradient(90deg, #fccbfc, #ffe9d0); + } + + .feds-navLink--3d-gradient { + background: linear-gradient(90deg, #e1f5cb, #edefb5); + } + + .feds-navLink--pdf-gradient { + background: linear-gradient(90deg, #ffbfbf, #fde6d3); + } + + .feds-navLink--video-gradient { + background: linear-gradient(90deg, #dcd9ff, #d5f1fd); + } + + .feds-navLink--ai-gradient { + background: linear-gradient(90deg, #bce3ff, #ffe9d3, #f8d5e4); + } } diff --git a/libs/blocks/global-navigation/global-navigation.css b/libs/blocks/global-navigation/global-navigation.css index 7b2360f027..8dd0cb6573 100644 --- a/libs/blocks/global-navigation/global-navigation.css +++ b/libs/blocks/global-navigation/global-navigation.css @@ -520,7 +520,6 @@ header.global-navigation { position: absolute; top: 100%; left: 0; - padding: 0; z-index: 1; box-shadow: 0 3px 3px 0 rgb(0 0 0 / 20%); transform: translate3d(0,0,0); /* Fix Safari issues w/ position: sticky */ @@ -543,7 +542,7 @@ header.global-navigation { .feds-navItem--megaMenu .feds-popup { right: 0; justify-content: center; - padding: 20px 0; + padding: 32px 12px; } [dir = "rtl"] .feds-navItem--megaMenu .feds-popup { diff --git a/libs/blocks/global-navigation/utilities/keyboard/utils.js b/libs/blocks/global-navigation/utilities/keyboard/utils.js index 6eb106a259..e9c61bdeaa 100644 --- a/libs/blocks/global-navigation/utilities/keyboard/utils.js +++ b/libs/blocks/global-navigation/utilities/keyboard/utils.js @@ -4,7 +4,7 @@ const selectors = { ...baseSelectors, globalFooter: '.global-footer', mainNavItems: - '.feds-navItem > a, .feds-navItem > .feds-cta-wrapper > .feds-cta', + '.feds-navItem > a, .feds-navItem > button, .feds-navItem > .feds-cta-wrapper > .feds-cta', brand: '.feds-brand', mainNavToggle: '.feds-toggle', searchTrigger: '.feds-search-trigger', @@ -23,7 +23,7 @@ const selectors = { popup: '.feds-popup', headline: '.feds-menu-headline', section: '.feds-menu-section', - column: '.feds-menu-column', + column: '.feds-menu-column:not(.feds-menu-column--group)', cta: '.feds-cta', openSearch: '.feds-search-trigger[aria-expanded = "true"]', regionPicker: '.feds-regionPicker', diff --git a/libs/blocks/global-navigation/utilities/menu/menu.css b/libs/blocks/global-navigation/utilities/menu/menu.css index 0b42578a7f..d63360e71c 100644 --- a/libs/blocks/global-navigation/utilities/menu/menu.css +++ b/libs/blocks/global-navigation/utilities/menu/menu.css @@ -30,10 +30,16 @@ padding: 12px 0; } +.feds-menu-column--group .feds-menu-column:not(:last-child) { + padding-bottom: 12px; + margin-bottom: 12px; + border-bottom: 1px solid var(--feds-borderColor-menu--light); +} + .feds-menu-headline { position: relative; padding: 12px 44px 12px 32px; - border-bottom: solid 1px var(--feds-borderColor-menu--light); + border-bottom: 1px solid var(--feds-borderColor-menu--light); color: var(--feds-color-headline--light); font-weight: 600; white-space: nowrap; @@ -84,8 +90,19 @@ max-width: var(--feds-maxWidth-nav); } - .feds-menu-column { - padding: 12px 0; + .feds-navItem--section .feds-menu-content { + column-gap: 12px; + } + + .feds-menu-column--wide { + flex-grow: 1; + max-width: 75%; + } + + .feds-menu-column--group .feds-menu-column:not(:last-child) { + margin-bottom: 0; + padding-bottom: 0; + border-bottom: none; } .feds-menu-section + .feds-menu-section { @@ -103,6 +120,10 @@ padding: 12px 0; } + .global-navigation .feds-menu-headline { + margin-bottom: 12px; + } + .feds-menu-headline:after { content: none; } diff --git a/libs/blocks/global-navigation/utilities/menu/menu.js b/libs/blocks/global-navigation/utilities/menu/menu.js index 28c2e5ccc6..7f53027722 100644 --- a/libs/blocks/global-navigation/utilities/menu/menu.js +++ b/libs/blocks/global-navigation/utilities/menu/menu.js @@ -12,6 +12,11 @@ import { import { decorateLinks } from '../../../../utils/utils.js'; import { replaceText } from '../../../../features/placeholders.js'; +const selectors = { + gnavPromo: '.gnav-promo', + columnBreak: '.column-break', +}; + const decorateHeadline = (elem, index) => { if (!(elem instanceof HTMLElement)) return null; @@ -134,7 +139,7 @@ const decoratePromo = (elem, index) => { const decorateImage = () => { const linkElem = elem.querySelector('a'); - const imageWrapper = imageElem.closest('.gnav-promo > div'); + const imageWrapper = imageElem.closest(`${selectors.gnavPromo} > div`); let promoImageElem; if (linkElem instanceof HTMLElement) { @@ -208,7 +213,10 @@ const decorateColumns = async ({ content, separatorTagName = 'H5' } = {}) => { await yieldToMain(); const columnElem = column.firstElementChild; - if (columnElem.tagName === separatorTagName) { + if (columnElem.matches(selectors.columnBreak)) { + resetDestination(); + columnElem.remove(); + } else if (columnElem.tagName === separatorTagName) { headlineIndex += 1; // When encountering a separator (h5 for header, h2 for footer), // add the previous section to the column @@ -220,8 +228,19 @@ const decorateColumns = async ({ content, separatorTagName = 'H5' } = {}) => { // turning it into a simple div const sectionHeadline = decorateHeadline(columnElem, headlineIndex); menuItems = toFragment`
`; + itemDestination.append(sectionHeadline, menuItems); - } else if (columnElem.classList.contains('gnav-promo')) { + + if (column.querySelector(selectors.columnBreak)) { + wrapper.classList.add(`${wrapperClass}--group`); + if (column.querySelectorAll(selectors.columnBreak).length > 1) wrapper.classList.add(`${wrapperClass}--wide`); + + const wideColumn = document.createElement('div'); + wideColumn.append(...column.childNodes); + menuItems.append(wideColumn); + await decorateColumns({ content: menuItems }); + } + } else if (columnElem.matches(selectors.gnavPromo)) { // When encountering a promo, add the previous section to the column resetDestination(); // Since the promo is alone on a column, reset the analytics index diff --git a/test/blocks/global-navigation/global-navigation.test.js b/test/blocks/global-navigation/global-navigation.test.js index 6351d9c8ef..bd0729010f 100644 --- a/test/blocks/global-navigation/global-navigation.test.js +++ b/test/blocks/global-navigation/global-navigation.test.js @@ -11,6 +11,7 @@ import longNav from './mocks/global-navigation-long.plain.js'; import noLogoBrandOnlyNav from './mocks/global-navigation-only-brand-no-image.plain.js'; import noBrandImageOnlyNav from './mocks/global-navigation-only-brand-no-explicit-image.js'; import globalNavigationMock from './mocks/global-navigation.plain.js'; +import globalNavigationWideColumnMock from './mocks/global-navigation-wide-column.plain.js'; const ogFetch = window.fetch; @@ -423,6 +424,12 @@ describe('global navigation', () => { expect(hasLinkgroupModifier).to.equal(true); }); + it('should render popups with wide columns', async () => { + await createFullGlobalNavigation({ globalNavigation: globalNavigationWideColumnMock }); + expect(document.querySelector('.feds-navItem--section .feds-menu-column--group .feds-menu-column + .feds-menu-column')).to.exist; + expect(document.querySelector('.column-break')).to.not.exist; + }); + it('should render the promo', async () => { await createFullGlobalNavigation(); diff --git a/test/blocks/global-navigation/mocks/global-navigation-wide-column.plain.js b/test/blocks/global-navigation/mocks/global-navigation-wide-column.plain.js new file mode 100644 index 0000000000..8dde2b075d --- /dev/null +++ b/test/blocks/global-navigation/mocks/global-navigation-wide-column.plain.js @@ -0,0 +1,285 @@ +// Uses the franklin structure without any customizations +export default `
+ +
+
+
+
+
+

+ Cloud Menu +

+
+
+
+
+
+

w/ Promo

+ +
+
+
+

Business Resilience: Leading Through Change

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas + porttitor congue massa. +

+

Check it out

+
+
+
+
+ + + + + + +
+
+
+
+
+

2 Col

+
Column 1 heading
+ + +
Column 2 heading
+ +

+ Events +

+
+
+

1 col

+ +
+
+

+ Primary +

+
+
+

+ Secondary +

+
+
+

Random text

+
+
+

No Dropdown

+
+
+ +
+
+
+
Local Menu Title
+

+ Creativity +

+

+ Digital Transformation +

+

+ Trends & Research +

+
+
+
+ +
+
+
+
+ +
+
+ +
`; diff --git a/test/blocks/global-navigation/mocks/large-menu-wide-column.plain.js b/test/blocks/global-navigation/mocks/large-menu-wide-column.plain.js new file mode 100644 index 0000000000..abde15cb22 --- /dev/null +++ b/test/blocks/global-navigation/mocks/large-menu-wide-column.plain.js @@ -0,0 +1,377 @@ +// Uses the franklin structure without any customizations +export default ` +
+ + +
Test heading
+ + + + +

+ View plans and pricing +

+

+ And another link +

+
+
+ + + + + + + + +

+ View all Creative Cloud products +

+
+ +
+
+
+
+
+ + + + + + +
+
+
+ +
+
+
+`; diff --git a/test/blocks/global-navigation/test-utilities.js b/test/blocks/global-navigation/test-utilities.js index 36f5439021..b0373df989 100644 --- a/test/blocks/global-navigation/test-utilities.js +++ b/test/blocks/global-navigation/test-utilities.js @@ -3,14 +3,11 @@ import sinon, { stub } from 'sinon'; import { setViewport } from '@web/test-runner-commands'; import initGnav from '../../../libs/blocks/global-navigation/global-navigation.js'; -import { - getLocale, - setConfig, - loadStyle, -} from '../../../libs/utils/utils.js'; +import { getLocale, setConfig, loadStyle } from '../../../libs/utils/utils.js'; import defaultPlaceholders from './mocks/placeholders.js'; import defaultProfile from './mocks/profile.js'; import largeMenuMock from './mocks/large-menu.plain.js'; +import largeMenuWideColumnMock from './mocks/large-menu-wide-column.plain.js'; import globalNavigationMock from './mocks/global-navigation.plain.js'; import correctPromoFragmentMock from './mocks/correctPromoFragment.plain.js'; import { isElementVisible, selectors as keyboardSelectors } from '../../../libs/blocks/global-navigation/utilities/keyboard/utils.js'; @@ -131,6 +128,7 @@ export const createFullGlobalNavigation = async ({ if (url.includes('profile')) { return mockRes({ payload: defaultProfile }); } if (url.includes('placeholders')) { return mockRes({ payload: placeholders || defaultPlaceholders }); } if (url.endsWith('large-menu.plain.html')) { return mockRes({ payload: largeMenuMock }); } + if (url.endsWith('large-menu-wide-column.plain.html')) { return mockRes({ payload: largeMenuWideColumnMock }); } if (url.includes('gnav')) { return mockRes({ payload: globalNavigation || globalNavigationMock }); } if (url.includes('correct-promo-fragment')) { return mockRes({ payload: correctPromoFragmentMock }); } if (url.includes('wrong-promo-fragment')) { return mockRes({ payload: '
Non-promo content
' }); }