From 697ba8c26031cff24a2334abe63e8e1969253102 Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Wed, 11 Sep 2024 15:15:27 +0200 Subject: [PATCH 01/20] KAW-7904 Implement header --- blocks/header/header.css | 511 +++++++++++++++++---------------------- blocks/header/header.js | 100 ++++++-- styles/styles.css | 5 +- 3 files changed, 307 insertions(+), 309 deletions(-) diff --git a/blocks/header/header.css b/blocks/header/header.css index 98ba3ef..362725d 100644 --- a/blocks/header/header.css +++ b/blocks/header/header.css @@ -1,433 +1,366 @@ /* header and nav layout */ header .nav-wrapper { - --color-gray: #999; - width: 100%; - z-index: 2; - position: relative; + z-index: var(--z-index-header); + position: fixed; } header nav { - box-sizing: border-box; display: flex; - flex-flow: column; + flex-flow: row; height: var(--nav-height); - padding: 15px 30px; + padding: 20px; + max-width: 1240px; + margin: auto; } -header nav[aria-expanded='true'] { - overflow-y: auto; - min-height: 100vh; - background-color: #222; - color: var(--color-gray); - max-width: 350px; - width: 50%; - position: relative; - min-width: 270px +header nav p { + margin: 0; + line-height: 1; } -header .nav-brand, -.nav-link-section .icon-logo-bimota-h { - display: none; +header a:any-link { + font-size: 1.25rem; + font-style: normal; + font-weight: 500; + line-height: 130%; + color: var(--grey-90); } -header .nav-wrapper.hide .nav-brand { - display: none; +header a:active, +header a:focus, +header a:hover { + color: var(--action-default); } -header .nav-wrapper.hide nav { - height: 100px; +/* brand */ +header .nav-brand { + flex-grow: 1; } -header nav p { - margin: 0; - line-height: 1; +header .nav-brand span.icon { + display: flex; + height: auto; + width: auto; } -.nav-logo-mobile { - position: absolute; - top: 10px; - left: 0; - transform: translateX(40vw); +header .nav-brand img { + width: 111px; + height: 31px; } -.nav-logo-mobile .icon-logo-bimota-h { - width: 100%; - height: 100%; - max-width: 170px; - max-height: 47px; +header .nav-dealer-locator { + margin-right: 20px; } -header a:any-link, -.nav-drop-text { - color: currentcolor; - padding: 5px 0; - display: flex; +header .nav-dealer-locator a.button { + display: inline-flex; + height: 30px; + padding: 6px 12px; + justify-content: center; align-items: center; - column-gap: .25em; - text-decoration: none; -} - -.nav-sections a.active, -.nav-drop.active .nav-drop-text { - color: var(--c-primary-white); + gap: 8px; + border-radius: 26px; + background: var(--white); + color: var(--black); + text-align: center; + font-size: 0.75rem; + font-style: normal; + font-weight: 600; + line-height: 150%; + letter-spacing: 0.44px; } -/* brand */ -header .nav-brand img { - max-width: 100%; - height: auto; +header .nav-drop picture { + display: none; } header .nav-link-section { - display: flex; + position: fixed; + top: 0; + right: 0; + height: 100vh; + width: 320px; + padding: 25px 20px 0; + display: none; flex-flow: column; - gap: 30px; + gap: 20px; + background-color: var(--white); + z-index: 2; } -/* sections */ -header .nav-sections { - flex: 1; - display: none; - visibility: hidden; +header .nav-close-button { + align-self: flex-end; + width: 20px; + margin-bottom: 20px; } -header nav[aria-expanded='true'] .nav-sections { +header .nav-flag { + position: fixed; + bottom: 0; + right: 20px; display: flex; - visibility: visible; } -.nav-tools .default-content-wrapper { +header nav[aria-expanded="true"] .nav-link-section { display: flex; - padding: 7px; - list-style: none; - margin-bottom: 0; - align-items: center; -} - -header .nav-sections .default-content-wrapper { - flex: 1; -} - -.nav-sections .default-content-wrapper .nav-logo { - align-self: flex-start; } header .nav-sections ul { list-style: none; - padding-left: 0; - font-size: 14px; - font-weight: 600; + padding: 0; + font-size: 1.25rem; + font-style: normal; + font-weight: 500; + line-height: 130%; display: flex; - align-items: flex-start; - column-gap: .25em; flex-flow: column; + gap: 24px; + margin: 0; } header .nav-sections ul li { width: 100%; } -.nav-sections ul > li > ul { - margin-top: 0; +header .nav-drop ul { + cursor: auto; } -/* tools */ -header .nav-tools { - display: none; - visibility: hidden; +header .nav-sections ul > li > ul { + margin: 0; + gap: 16px; + padding: 10px 0 0; } -header nav[aria-expanded='true'] .nav-tools { +header .nav-sections ul > li > ul a:any-link { + font-size: 0.875rem; + font-style: normal; + font-weight: 500; + line-height: 150%; + letter-spacing: 0.44px; +} + +/* tools */ +header .nav-tools .default-content-wrapper { + list-style: none; + padding: 0; + gap: 16px; display: flex; - visibility: visible; - padding-left: 30px; - align-items: center; + margin: 27px 0 0; } -.nav-tools .default-content-wrapper li { - padding: 5px 10px 6px; - line-height: 1; - color: var(--c-primary-white); +header .nav-tools .default-content-wrapper li { + margin: 0; +} + +header .nav-tools .default-content-wrapper li a:any-link { + font-size: 0.875rem; + font-style: normal; + font-weight: 600; + line-height: 130%; + letter-spacing: 0.44px; } /* hamburger */ header .nav-hamburger { - height: 22px; display: flex; - align-self: start; - justify-content: flex-end; - flex: 1; + align-items: center; } header .nav-hamburger button { - height: 22px; - margin: auto; + height: 24px; border: 0; border-radius: 0; padding: 0; background-color: transparent; - color: inherit; - overflow: initial; - text-overflow: initial; - white-space: initial; cursor: pointer; } -header .nav-hamburger-icon, -header .nav-hamburger-icon::before, -header .nav-hamburger-icon::after { - box-sizing: border-box; - display: block; - position: relative; - width: 20px; -} - -header .nav-hamburger-icon::before, -header .nav-hamburger-icon::after { - content: ''; - position: absolute; - background: currentcolor; -} - -header nav[aria-expanded='true'] .nav-hamburger { - flex: initial; - align-self: flex-end; -} - -header nav[aria-expanded='false'] .nav-hamburger-icon, -header nav[aria-expanded='false'] .nav-hamburger-icon::before, -header nav[aria-expanded='false'] .nav-hamburger-icon::after { - height: 2px; - border-radius: 2px; - background: var(--color-gray); -} - -header nav[aria-expanded='false'] .nav-hamburger-icon::before { - top: -6px; -} - -header nav[aria-expanded='false'] .nav-hamburger-icon::after { - top: 6px; -} - -header nav[aria-expanded='true'] .nav-hamburger-icon { - height: 22px; -} - -header nav[aria-expanded='true'] .nav-hamburger-icon::before, -header nav[aria-expanded='true'] .nav-hamburger-icon::after { - top: 3px; - left: 1px; - transform: rotate(45deg); - transform-origin: 2px 1px; - width: 24px; - height: 2px; - border-radius: 2px; -} - -header nav[aria-expanded='true'] .nav-hamburger-icon::after { - top: unset; - bottom: 3px; - transform: rotate(-45deg); -} - /* nav-drop */ header .nav-drop { position: relative; cursor: pointer; } -header .nav-drop::after { - content: ''; - display: inline-block; - position: absolute; - top: 10px; - right: 5px; - transform: rotate(135deg); - width: 6px; - height: 6px; - border: 2px solid currentcolor; - border-radius: 0 1px 0 0; - border-width: 2px 2px 0 0; -} - -header .nav-drop[aria-expanded='false'] ul { +header .nav-drop[aria-expanded="false"] ul { display: none; } -header .nav-drop[aria-expanded='true'] ul { +.nav-sections .nav-drop-text { display: flex; - flex-flow: column; - padding: 5px 0 5px 15px; -} - -header .nav-drop[aria-expanded='true']::after { - bottom: 0.5em; - transform: rotate(315deg); + justify-content: space-between; } .nav-sections .nav-drop-text:hover { text-decoration: none; } -.nav-sections a:hover, -header nav[aria-expanded='true'] button:hover .nav-hamburger-icon::after, -header nav[aria-expanded='true'] button:hover .nav-hamburger-icon::before, -header .nav-drop[aria-expanded='true']:hover::after { - color: #ffffffb2; +header .nav-backdrop { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background: rgb(0 0 0 / 40%); + z-index: 1; } -@media (width >= 640px) { - header .nav-drop::after { - top: 8px; - } +header .nav-backdrop.hide { + display: none; } -@media (width >= 992px) { - header { - --nav-height: 130px; - } - +@media (width >= 768px) { header nav { - display: flex; - justify-content: space-between; + padding: 20px 30px 16px 24px; } - header a:any-link, - .nav-link-section .a, - .nav-tools .default-content-wrapper li { - color: var(--text-color); - letter-spacing: 1px; - font-weight: 400; + header .nav-brand img { + height: 34px; + width: auto; } - header .nav-wrapper { - max-width: 100%; - background-color: var(--c-primary-white); - position: fixed; + header .nav-link-section { + padding: 24px 30px 0; } - header nav[aria-expanded='true'] { - min-height: auto; - overflow: visible; - margin: auto; - background-color: var(--c-primary-white); - padding-top: 0; - max-width: 1280px; - width: 100%; + header .nav-dealer-locator { + margin-right: 32px; } - header nav .nav-hamburger { - display: none; - visibility: hidden; + header .nav-flag { + right: 30px; } +} +@media (width >= 1024px) { header .nav-brand { - display: block; - align-self: flex-end; + flex-grow: unset; } header .nav-link-section { - flex-flow: row; - } - - header .nav-sections { - display: flex; - visibility: visible; - white-space: nowrap; + position: static; + width: auto; + padding: 0; + flex-direction: row; + background-color: transparent; + height: auto; + flex-grow: 1; align-items: center; } - header .nav-sections .default-content-wrapper { - display: flex; - flex-flow: row; - justify-content: space-between; - flex: 1; - align-items: center; + header .nav-backdrop { + display: none; } - .nav-logo-mobile .icon-logo-bimota-h { + header .nav-hamburger, + header .nav-close-button, + header .nav-flag, + header .nav-drop-text .chevron-icon { display: none; } - header .nav-sections .icon-logo-bimota-h { - display: block; - height: 100%; - width: 100%; - max-width: 250px; - max-height: 70px; + header .nav-dealer-locator { + margin: 0; + display: flex; + align-items: center; } - .nav-sections a:hover, - .nav-sections a.active, - .nav-drop.active .nav-drop-text { - color: var(--link-color); + header .nav-sections { + flex-grow: 1; + justify-content: center; + display: flex; } header .nav-sections ul { - display: flex; - gap: 30px; - margin: 0; - flex-flow: row; - align-items: center; - justify-content: center; + flex-direction: row; + gap: 28px; } - .nav-tools .default-content-wrapper li { - cursor: pointer; + header .nav-tools { + margin-right: 24px; } - header .nav-sections .default-content-wrapper > ul > li { - flex: 0 1 auto; - position: relative; - font-weight: 500; - min-height: 80px; - display: flex; + header .nav-tools ul { + flex-direction: row; + gap: 12px; } - header .nav-sections .default-content-wrapper > ul > li > ul { - display: none; - position: relative; + header .nav-tools .default-content-wrapper { + margin: 0; } - header .nav-sections .default-content-wrapper > ul > li[aria-expanded='true'] > ul { - display: block; - position: absolute; - width: 250px; - top: 80px; - padding: 25px; - background-color: var(--c-primary-white); - white-space: initial; - box-shadow: 0 5px 12px rgba(0 0 0 / 15%); + header .nav-sections ul, + header .nav-link-section a:any-link, + header .nav-tools .default-content-wrapper li a:any-link { + font-size: 0.875rem; + font-style: normal; + font-weight: 600; + line-height: 130%; + letter-spacing: 0.44px; } - .nav-tools .default-content-wrapper a, - .nav-drop-text { - color: var(--text-color); + header .nav-sections ul li { + width: auto; } - .nav-tools a:any-link:hover { - color: var(--text-color); + /* expanded menu item content */ + header .nav-sections .nav-drop ul { + position: fixed; + top: var(--nav-height); + padding: 40px; + width: 100vw; + left: 0; + height: auto; + background: var(--white); + gap: unset; + justify-content: space-between; + flex-wrap: wrap; + row-gap: 40px; } - - .nav-sections .nav-drop ul a:any-link { - color: var(--color-gray); + + header .nav-sections .nav-drop ul li a:any-link { + padding: 0 16px; + display: flex; + flex-direction: column; + gap: 16px; + font-size: 1.25rem; + font-style: normal; + font-weight: 500; + line-height: 140%; } - - .nav-sections .nav-drop ul a:hover { - color: var(--link-hover-color); + + header .nav-sections .nav-drop ul picture { + display: flex; } - header .nav-sections .default-content-wrapper > ul > li > ul > li { - padding: 8px 0; + header .nav-sections .nav-drop ul img { + width: 187px; + height: auto; } - header .nav-drop::after { - display: none; + header .nav-drop[aria-expanded="true"]::after { + content: ''; + display: block; + width: 100vw; + height: calc(100vh - var(--nav-height)); + position: fixed; + top: var(--nav-height); + left: 0; + background: rgb(0 0 0 / 40%); + z-index: -1; + cursor: auto; } +} - header nav[aria-expanded='true'] .nav-tools { +@media (width >= 1024px) { + header nav { padding-left: 0; + padding-right: 0; + } + + header .nav-sections .nav-drop ul { + padding-left: calc((100vw - 1240px) / 2); + padding-right: calc((100vw - 1240px) / 2); } } \ No newline at end of file diff --git a/blocks/header/header.js b/blocks/header/header.js index 4ebced2..7160a0e 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -2,7 +2,41 @@ import { getMetadata } from '../../scripts/aem.js'; import { loadFragment } from '../fragment/fragment.js'; // media query match that indicates mobile/tablet width -const isDesktop = window.matchMedia('(min-width: 992px)'); +const isDesktop = window.matchMedia('(min-width: 1024px)'); + +const hamburgerIcon = ` + + + + + + + + + + +`; + +const chevronIcon = ` + + + +`; + +const flag = ` + + + + + + +`; + +const closeIcon = ` + + + +`; function closeOnEscape(e) { if (e.code === 'Escape') { @@ -70,6 +104,13 @@ function toggleMenu(nav, navSections, forceExpanded = null) { } }); + const backdropEl = nav.querySelector('.nav-backdrop'); + if (!expanded) { + backdropEl.classList.remove('hide'); + } else { + backdropEl.classList.add('hide'); + } + // enable menu collapse on escape keypress if (!expanded || isDesktop.matches) { // collapse menu on escape press @@ -117,7 +158,8 @@ function redirectPage(event) { export default async function decorate(block) { // load nav as fragment const navMeta = getMetadata('nav'); - const navPath = navMeta ? new URL(navMeta, window.location).pathname : '/nav'; + // const navPath = navMeta ? new URL(navMeta, window.location).pathname : '/nav'; + const navPath = '/drafts/tdziezyk/v3-nav'; const fragment = await loadFragment(navPath); // decorate nav DOM @@ -126,7 +168,7 @@ export default async function decorate(block) { nav.id = 'nav'; while (fragment.firstElementChild) nav.append(fragment.firstElementChild); - const classes = ['brand', 'sections', 'tools']; + const classes = ['brand', 'sections', 'tools', 'dealer-locator']; classes.forEach((c, i) => { const section = nav.children[i]; if (section) section.classList.add(`nav-${c}`); @@ -140,29 +182,31 @@ export default async function decorate(block) { } const navSections = nav.querySelector('.nav-sections'); - const mobileLogoWrapper = document.createElement('div'); - mobileLogoWrapper.classList.add('nav-logo-mobile'); + if (navSections) { navSections.querySelectorAll(':scope .default-content-wrapper > ul > li').forEach((navSection) => { if (navSection.querySelector('ul')) { const textWrapper = document.createElement('a'); textWrapper.classList.add('nav-drop-text'); textWrapper.append(navSection.firstChild); + textWrapper.innerHTML += `${chevronIcon}`; navSection.prepend(textWrapper); navSection.classList.add('nav-drop'); + + // wrapping pictures with links if the link follows immediately after the picture + navSection.querySelectorAll('ul picture + a').forEach((link) => { + const picture = link.previousElementSibling; + + link.prepend(picture); + }); } - navSection.addEventListener('click', () => toggleSubNav(navSection, navSections)); + navSection.addEventListener('click', (event) => { + if (event.target.classList.contains('nav-drop-text')) { + toggleSubNav(navSection, navSections); + } + }); }); - const defaultContentWrapper = navSections.querySelector('.default-content-wrapper'); - const logoButton = defaultContentWrapper.querySelector('.default-content-wrapper .button'); - if (logoButton) { - logoButton.className = 'nav-logo'; - defaultContentWrapper.prepend(logoButton); - const buttonContainer = defaultContentWrapper.querySelector('.button-container'); - mobileLogoWrapper.appendChild(logoButton.cloneNode(true)); - buttonContainer.remove(); - } } const navTools = nav.querySelector('.nav-tools'); @@ -176,21 +220,39 @@ export default async function decorate(block) { }); } + const navDealerLocator = nav.querySelector('.nav-dealer-locator'); + const dealerLocatorButton = navDealerLocator.querySelector('a'); + navDealerLocator.innerHTML = ''; + navDealerLocator.append(dealerLocatorButton); + if (navSections && navTools) { const navLinksWrapper = document.createElement('div'); navLinksWrapper.classList.add('nav-link-section'); - navLinksWrapper.append(navSections, navTools); + const flagEl = document.createElement('span'); + flagEl.classList.add('nav-flag'); + flagEl.innerHTML = flag; + const closeEl = document.createElement('button'); + closeEl.classList.add('nav-close-button'); + closeEl.innerHTML = closeIcon; + closeEl.addEventListener('click', () => toggleMenu(nav, navSections)); + navLinksWrapper.append(closeEl, navSections, navTools, flagEl); nav.append(navLinksWrapper); + + const backdrop = document.createElement('div'); + backdrop.classList.add('nav-backdrop'); + nav.append(backdrop); } + nav.append(navDealerLocator); + // hamburger for mobile const hamburger = document.createElement('div'); hamburger.classList.add('nav-hamburger'); hamburger.innerHTML = ``; hamburger.addEventListener('click', () => toggleMenu(nav, navSections)); - nav.prepend(hamburger); + nav.append(hamburger); nav.setAttribute('aria-expanded', 'false'); // prevent mobile nav behavior on window resize toggleMenu(nav, navSections, isDesktop.matches); @@ -200,7 +262,7 @@ export default async function decorate(block) { const navWrapper = document.createElement('div'); navWrapper.className = 'nav-wrapper'; - navWrapper.append(mobileLogoWrapper, nav); + navWrapper.append(nav); block.append(navWrapper); checkForActiveLink(navSections); diff --git a/styles/styles.css b/styles/styles.css index 7d4b85c..3b7d291 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -17,7 +17,7 @@ --body-font-size: 16px; /* nav height */ - --nav-height: 80px; + --nav-height: 70px; /* section paddings */ --section-y-padding: 40px; @@ -44,6 +44,9 @@ --warning: #e68619; --error: #b81f2d; + /* z indexes */ + --z-index-header: 2; + /* old variables */ --link-color: var(--action-default); --link-hover-color: var(--action-hover); From 51af69cf5b6af2e021bec960d80196ffae19ded7 Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Thu, 12 Sep 2024 09:07:22 +0200 Subject: [PATCH 02/20] KAW-7904 Improve header css'es --- blocks/header/header.css | 75 +++++++++++++++++++++++++++++++++++++--- blocks/header/header.js | 6 ++-- 2 files changed, 74 insertions(+), 7 deletions(-) diff --git a/blocks/header/header.css b/blocks/header/header.css index 362725d..3693fa7 100644 --- a/blocks/header/header.css +++ b/blocks/header/header.css @@ -3,6 +3,7 @@ header .nav-wrapper { width: 100%; z-index: var(--z-index-header); position: fixed; + color: var(--grey-90); } header nav { @@ -12,6 +13,7 @@ header nav { padding: 20px; max-width: 1240px; margin: auto; + background-color: var(--white); } header nav p { @@ -62,13 +64,23 @@ header .nav-dealer-locator a.button { gap: 8px; border-radius: 26px; background: var(--white); - color: var(--black); text-align: center; font-size: 0.75rem; font-style: normal; font-weight: 600; line-height: 150%; letter-spacing: 0.44px; + border: solid 1px var(--action-default); +} + +header .nav-dealer-locator a.button:hover { + border-color: var(--action-hover); + color: var(--action-hover); +} + +header .nav-dealer-locator a.button:focus { + border-color: var(--action-focus); + color: var(--action-focus); } header .nav-drop picture { @@ -177,6 +189,10 @@ header .nav-hamburger button { cursor: pointer; } +header .nav-hamburger button svg { + color: var(--grey-90); +} + /* nav-drop */ header .nav-drop { position: relative; @@ -210,6 +226,40 @@ header .nav-backdrop.hide { display: none; } +header.transparent nav { + background-color: transparent; + color: var(--white); +} + +header.transparent a:any-link { + color: var(--white); +} + +header.transparent .nav-hamburger svg { + color: var(--white); +} + +header.transparent .nav-dealer-locator a.button { + background-color: var(--white); + border-color: transparent; + color: var(--black); +} + +header.transparent .nav-dealer-locator a.button:hover { + border-color: var(--action-hover); + color: var(--action-hover); +} + +header.transparent .nav-dealer-locator a.button:focus { + border-color: var(--action-focus); + color: var(--action-focus); +} + +header.transparent nav[aria-expanded="true"] .nav-link-section a:any-link, +header.transparent nav[aria-expanded="true"] .nav-link-section a.nav-drop-text { + color: var(--grey-90); +} + @media (width >= 768px) { header nav { padding: 20px 30px 16px 24px; @@ -340,7 +390,7 @@ header .nav-backdrop.hide { } header .nav-drop[aria-expanded="true"]::after { - content: ''; + content: ""; display: block; width: 100vw; height: calc(100vh - var(--nav-height)); @@ -351,9 +401,26 @@ header .nav-backdrop.hide { z-index: -1; cursor: auto; } + + header.transparent nav[aria-expanded="true"] .nav-link-section a:any-link, + header.transparent nav[aria-expanded="true"] .nav-link-section a.nav-drop-text { + color: var(--white); + } + + header.transparent nav[aria-expanded="true"] .nav-link-section .nav-drop a:any-link { + color: var(--grey-90); + } + + header.transparent nav[aria-expanded="true"] .nav-link-section .nav-drop a:focus { + color: var(--action-focus); + } + + header.transparent nav[aria-expanded="true"] .nav-link-section .nav-drop a:hover { + color: var(--action-hover); + } } -@media (width >= 1024px) { +@media (width >= 1440px) { header nav { padding-left: 0; padding-right: 0; @@ -363,4 +430,4 @@ header .nav-backdrop.hide { padding-left: calc((100vw - 1240px) / 2); padding-right: calc((100vw - 1240px) / 2); } -} \ No newline at end of file +} diff --git a/blocks/header/header.js b/blocks/header/header.js index 7160a0e..d1ea75d 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -5,9 +5,9 @@ import { loadFragment } from '../fragment/fragment.js'; const isDesktop = window.matchMedia('(min-width: 1024px)'); const hamburgerIcon = ` - + - + @@ -202,7 +202,7 @@ export default async function decorate(block) { } navSection.addEventListener('click', (event) => { - if (event.target.classList.contains('nav-drop-text')) { + if (event.target.classList.contains('nav-drop-text') || event.target.closest('.nav-drop-text')) { toggleSubNav(navSection, navSections); } }); From cc6676475b1bfe7e5446b01dbc11adb6385b3806 Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Thu, 12 Sep 2024 10:43:04 +0200 Subject: [PATCH 03/20] KAW-7904 Add scrolling logic for header --- blocks/header/header.css | 16 ++++++++++++++-- blocks/header/header.js | 31 +++++++++++++++++++++++++++++++ styles/styles.css | 4 ++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/blocks/header/header.css b/blocks/header/header.css index 3693fa7..7cc213e 100644 --- a/blocks/header/header.css +++ b/blocks/header/header.css @@ -1,8 +1,19 @@ /* header and nav layout */ + +header { + position: fixed; + top: 0; + transition: 500ms all; + width: 100vw; + z-index: var(--z-index-header); +} + +header.fade-out { + top: calc(-1 * var(--nav-height)); +} + header .nav-wrapper { width: 100%; - z-index: var(--z-index-header); - position: fixed; color: var(--grey-90); } @@ -231,6 +242,7 @@ header.transparent nav { color: var(--white); } +/* stylelint-disable-next-line no-descending-specificity */ header.transparent a:any-link { color: var(--white); } diff --git a/blocks/header/header.js b/blocks/header/header.js index d1ea75d..b0acf34 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -151,6 +151,35 @@ function redirectPage(event) { } window.location.replace(redirectUrl); } + +function handleTransparentAndScrolling(nav) { + const useTransparentVariant = !!document.querySelector('main > .section > .hero-wrapper'); + const header = nav.closest('header'); + let prevScrollingPosition = 0; + + document.addEventListener('scroll', () => { + const { scrollY } = window; + + if (useTransparentVariant) { + header.classList.add('transparent', 'can-be-transparent'); + + if (scrollY > 100) { + header.classList.remove('transparent'); + } else { + header.classList.add('transparent'); + } + } + + if (scrollY - prevScrollingPosition > 0 && scrollY > 200) { + header.classList.add('fade-out'); + } else if (prevScrollingPosition - scrollY > 0) { + header.classList.remove('fade-out'); + } + + prevScrollingPosition = scrollY; + }); +} + /** * loads and decorates the header, mainly the nav * @param {Element} block The header block element @@ -277,4 +306,6 @@ export default async function decorate(block) { }); }, { rootMargin: '0px 0px -1000px 0px' }); observer.observe(document.querySelector('main')); + + handleTransparentAndScrolling(nav); } diff --git a/styles/styles.css b/styles/styles.css index 3b7d291..96b3268 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -496,6 +496,10 @@ div[class$="-wrapper"]:not(:first-child) { } } +header:not(.can-be-transparent) + main { + margin-top: var(--nav-height); +} + /* sections */ main .section { padding: var(--section-y-padding) var(--section-x-padding); From ff06afa3bb8157a842eb85cbd14fe6987a7f834e Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Thu, 12 Sep 2024 10:49:01 +0200 Subject: [PATCH 04/20] KAW-7904 Fix chevron animation --- blocks/header/header.css | 10 ++++++++++ blocks/header/header.js | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/blocks/header/header.css b/blocks/header/header.css index 7cc213e..2ea963b 100644 --- a/blocks/header/header.css +++ b/blocks/header/header.css @@ -214,6 +214,16 @@ header .nav-drop[aria-expanded="false"] ul { display: none; } +header .nav-drop .chevron-icon { + transition: transform 200ms ease-in-out; + transform-origin: center center; + display: flex; +} + +header .nav-drop[aria-expanded="true"] .chevron-icon { + transform: rotate(180deg); +} + .nav-sections .nav-drop-text { display: flex; justify-content: space-between; diff --git a/blocks/header/header.js b/blocks/header/header.js index b0acf34..e677cfd 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -18,8 +18,8 @@ const hamburgerIcon = ` `; const chevronIcon = ` - - + + `; From 69c0329547b22cdd5d8de26d9ed4834fe4852e1e Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Thu, 12 Sep 2024 10:57:41 +0200 Subject: [PATCH 05/20] KAW-7904 Refactor --- blocks/header/header.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blocks/header/header.css b/blocks/header/header.css index 2ea963b..e8e3b41 100644 --- a/blocks/header/header.css +++ b/blocks/header/header.css @@ -119,7 +119,7 @@ header .nav-close-button { } header .nav-flag { - position: fixed; + position: absolute; bottom: 0; right: 20px; display: flex; From bc596fb9ba17e92686b48f8c59b8d4bdf8cc4e3b Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Thu, 12 Sep 2024 11:25:03 +0200 Subject: [PATCH 06/20] KAW-7904 Update icons --- blocks/header/header.css | 15 ++++++++++--- blocks/header/header.js | 45 ++++++--------------------------------- icons/chevron.svg | 3 +++ icons/close.svg | 4 ++-- icons/hamburger.svg | 10 +++++++++ icons/logo-flag-black.svg | 6 ++++++ icons/logo.svg | 11 ++++++++++ scripts/scripts.js | 32 +++++++++++++++++++++++++++- 8 files changed, 82 insertions(+), 44 deletions(-) create mode 100644 icons/chevron.svg create mode 100644 icons/hamburger.svg create mode 100644 icons/logo-flag-black.svg create mode 100644 icons/logo.svg diff --git a/blocks/header/header.css b/blocks/header/header.css index e8e3b41..e30aac1 100644 --- a/blocks/header/header.css +++ b/blocks/header/header.css @@ -118,6 +118,11 @@ header .nav-close-button { margin-bottom: 20px; } +header .icon-close { + display: flex; + color: var(--grey-90); +} + header .nav-flag { position: absolute; bottom: 0; @@ -125,6 +130,10 @@ header .nav-flag { display: flex; } +header .nav-flag .icon { + display: flex; +} + header nav[aria-expanded="true"] .nav-link-section { display: flex; } @@ -214,13 +223,13 @@ header .nav-drop[aria-expanded="false"] ul { display: none; } -header .nav-drop .chevron-icon { +header .nav-drop .icon-chevron { transition: transform 200ms ease-in-out; transform-origin: center center; display: flex; } -header .nav-drop[aria-expanded="true"] .chevron-icon { +header .nav-drop[aria-expanded="true"] .icon-chevron { transform: rotate(180deg); } @@ -328,7 +337,7 @@ header.transparent nav[aria-expanded="true"] .nav-link-section a.nav-drop-text { header .nav-hamburger, header .nav-close-button, header .nav-flag, - header .nav-drop-text .chevron-icon { + header .nav-drop-text .icon-chevron { display: none; } diff --git a/blocks/header/header.js b/blocks/header/header.js index e677cfd..1222ef2 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -1,43 +1,10 @@ import { getMetadata } from '../../scripts/aem.js'; +import { customDecoreateIcons } from '../../scripts/scripts.js'; import { loadFragment } from '../fragment/fragment.js'; // media query match that indicates mobile/tablet width const isDesktop = window.matchMedia('(min-width: 1024px)'); -const hamburgerIcon = ` - - - - - - - - - - -`; - -const chevronIcon = ` - - - -`; - -const flag = ` - - - - - - -`; - -const closeIcon = ` - - - -`; - function closeOnEscape(e) { if (e.code === 'Escape') { const nav = document.getElementById('nav'); @@ -218,7 +185,7 @@ export default async function decorate(block) { const textWrapper = document.createElement('a'); textWrapper.classList.add('nav-drop-text'); textWrapper.append(navSection.firstChild); - textWrapper.innerHTML += `${chevronIcon}`; + textWrapper.innerHTML += ''; navSection.prepend(textWrapper); navSection.classList.add('nav-drop'); @@ -259,10 +226,10 @@ export default async function decorate(block) { navLinksWrapper.classList.add('nav-link-section'); const flagEl = document.createElement('span'); flagEl.classList.add('nav-flag'); - flagEl.innerHTML = flag; + flagEl.innerHTML = ''; const closeEl = document.createElement('button'); closeEl.classList.add('nav-close-button'); - closeEl.innerHTML = closeIcon; + closeEl.innerHTML = ''; closeEl.addEventListener('click', () => toggleMenu(nav, navSections)); navLinksWrapper.append(closeEl, navSections, navTools, flagEl); nav.append(navLinksWrapper); @@ -278,7 +245,7 @@ export default async function decorate(block) { const hamburger = document.createElement('div'); hamburger.classList.add('nav-hamburger'); hamburger.innerHTML = ``; hamburger.addEventListener('click', () => toggleMenu(nav, navSections)); nav.append(hamburger); @@ -308,4 +275,6 @@ export default async function decorate(block) { observer.observe(document.querySelector('main')); handleTransparentAndScrolling(nav); + + customDecoreateIcons(nav); } diff --git a/icons/chevron.svg b/icons/chevron.svg new file mode 100644 index 0000000..4952f2a --- /dev/null +++ b/icons/chevron.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/close.svg b/icons/close.svg index e7b4747..103f557 100644 --- a/icons/close.svg +++ b/icons/close.svg @@ -1,4 +1,4 @@ - - + + \ No newline at end of file diff --git a/icons/hamburger.svg b/icons/hamburger.svg new file mode 100644 index 0000000..3ab87cb --- /dev/null +++ b/icons/hamburger.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/icons/logo-flag-black.svg b/icons/logo-flag-black.svg new file mode 100644 index 0000000..c199615 --- /dev/null +++ b/icons/logo-flag-black.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/icons/logo.svg b/icons/logo.svg new file mode 100644 index 0000000..142e87d --- /dev/null +++ b/icons/logo.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/scripts/scripts.js b/scripts/scripts.js index d56037b..146584f 100644 --- a/scripts/scripts.js +++ b/scripts/scripts.js @@ -94,6 +94,36 @@ function swappingPlacesBlock(main) { }); } +export function customDecoreateIcons(main) { + // inline icons give the possibility to change its colors using the css variables + const decorateInlineIcons = (rootElement) => { + const inlineIcons = ['icon-logo', 'icon-hamburger', 'icon-chevron', 'icon-close']; + const isInlineIcon = (el) => { + const isInline = (className) => inlineIcons.includes(className); + return [...el.classList].some(isInline); + }; + const inlineIconsList = [...rootElement.querySelectorAll('span.icon')].filter(isInlineIcon); + + inlineIconsList.forEach((async (inlineIcon) => { + const iconName = [...inlineIcon.classList].find((c) => c.startsWith('icon-')).substring(5); + inlineIcon.classList.remove('icon'); // removing the 'icon' class, so the icon won't be used by decorateIcon + const icon = await fetch(`${window.hlx.codeBasePath}/icons/${iconName}.svg`); + + try { + const svgIcon = await icon.text(); + const svgEl = document.createRange().createContextualFragment(svgIcon).children[0]; + inlineIcon.innerHTML = svgEl.outerHTML; + } catch (error) { + // eslint-disable-next-line no-console + console.error(error); + } + })); + }; + + decorateInlineIcons(main); + decorateIcons(main); +} + /** * Decorates the main element. * @param {Element} main The main element @@ -102,7 +132,7 @@ function swappingPlacesBlock(main) { export function decorateMain(main) { // hopefully forward compatible button decoration decorateButtons(main); - decorateIcons(main); + customDecoreateIcons(main); buildAutoBlocks(main); decorateSections(main); customDecorateSections(main); From bb1cdea5fc9a73d4fc20a5dd97e7fa2ae33e194f Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Thu, 12 Sep 2024 12:15:58 +0200 Subject: [PATCH 07/20] KAW-7904 Add underline style for active links --- blocks/header/header.css | 51 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/blocks/header/header.css b/blocks/header/header.css index e30aac1..30c8e9a 100644 --- a/blocks/header/header.css +++ b/blocks/header/header.css @@ -184,8 +184,18 @@ header .nav-tools .default-content-wrapper { header .nav-tools .default-content-wrapper li { margin: 0; + position: relative; +} + +header .nav-tools .default-content-wrapper li.active::after { + content: ""; + display: block; + width: 100%; + height: 1px; + background: black; } + header .nav-tools .default-content-wrapper li a:any-link { font-size: 0.875rem; font-style: normal; @@ -223,6 +233,10 @@ header .nav-drop[aria-expanded="false"] ul { display: none; } +header .nav-sections .nav-drop[aria-expanded="true"] { + color: var(--action-default); +} + header .nav-drop .icon-chevron { transition: transform 200ms ease-in-out; transform-origin: center center; @@ -385,6 +399,20 @@ header.transparent nav[aria-expanded="true"] .nav-link-section a.nav-drop-text { width: auto; } + header .nav-sections .nav-drop[aria-expanded="true"] .nav-drop-text { + color: var(--black); + } + + header .nav-sections .nav-drop[aria-expanded="true"] .nav-drop-text::after { + content: ""; + display: block; + width: 100%; + height: 1px; + position: absolute; + bottom: 0; + background: currentcolor; + } + /* expanded menu item content */ header .nav-sections .nav-drop ul { position: fixed; @@ -434,19 +462,34 @@ header.transparent nav[aria-expanded="true"] .nav-link-section a.nav-drop-text { } header.transparent nav[aria-expanded="true"] .nav-link-section a:any-link, - header.transparent nav[aria-expanded="true"] .nav-link-section a.nav-drop-text { + header.transparent + nav[aria-expanded="true"] + .nav-link-section + a.nav-drop-text { color: var(--white); } - header.transparent nav[aria-expanded="true"] .nav-link-section .nav-drop a:any-link { + header.transparent + nav[aria-expanded="true"] + .nav-link-section + .nav-drop + a:any-link { color: var(--grey-90); } - header.transparent nav[aria-expanded="true"] .nav-link-section .nav-drop a:focus { + header.transparent + nav[aria-expanded="true"] + .nav-link-section + .nav-drop + a:focus { color: var(--action-focus); } - header.transparent nav[aria-expanded="true"] .nav-link-section .nav-drop a:hover { + header.transparent + nav[aria-expanded="true"] + .nav-link-section + .nav-drop + a:hover { color: var(--action-hover); } } From 6a680faea077c007aa4a720536c19b9f8c48e96c Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Thu, 12 Sep 2024 12:23:08 +0200 Subject: [PATCH 08/20] KAW-7904 Fix navigation location --- blocks/header/header.css | 5 +++++ blocks/header/header.js | 16 +++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/blocks/header/header.css b/blocks/header/header.css index 30c8e9a..50009a6 100644 --- a/blocks/header/header.css +++ b/blocks/header/header.css @@ -15,6 +15,7 @@ header.fade-out { header .nav-wrapper { width: 100%; color: var(--grey-90); + background-color: var(--white); } header nav { @@ -275,6 +276,10 @@ header.transparent nav { color: var(--white); } +header.transparent .nav-wrapper { + background-color: transparent; +} + /* stylelint-disable-next-line no-descending-specificity */ header.transparent a:any-link { color: var(--white); diff --git a/blocks/header/header.js b/blocks/header/header.js index 1222ef2..3bf0f91 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -108,7 +108,7 @@ function redirectPage(event) { const currentUrl = window.location; let redirectUrl = currentUrl.origin; - if (event.target.innerHTML === 'ENG') { + if (event.target.innerHTML.toLowerCase() === 'en') { if (!currentUrl.pathname.includes('/en/')) { redirectUrl = `${redirectUrl}/en`; } @@ -154,8 +154,7 @@ function handleTransparentAndScrolling(nav) { export default async function decorate(block) { // load nav as fragment const navMeta = getMetadata('nav'); - // const navPath = navMeta ? new URL(navMeta, window.location).pathname : '/nav'; - const navPath = '/drafts/tdziezyk/v3-nav'; + const navPath = navMeta ? new URL(navMeta, window.location).pathname : '/nav'; const fragment = await loadFragment(navPath); // decorate nav DOM @@ -211,8 +210,15 @@ export default async function decorate(block) { toolsWrapper.classList.add('default-content-wrapper'); navTools.append(toolsWrapper); navTools.firstElementChild.remove(); - toolsWrapper.querySelectorAll('li').forEach((list) => { - list.addEventListener('click', redirectPage); + toolsWrapper.querySelectorAll('li').forEach((item) => { + item.addEventListener('click', redirectPage); + + const urlLang = document.location.pathname.includes('/en/') ? 'en' : 'ita'; + const listItemLang = item.textContent.trim().toLowerCase(); + + if (urlLang === listItemLang) { + item.classList.add('active'); + } }); } From c0d50bd132b843a745541c252baf42c46666495e Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Thu, 12 Sep 2024 12:28:19 +0200 Subject: [PATCH 09/20] KAW-7904 Fix init state of the header --- blocks/header/header.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/blocks/header/header.js b/blocks/header/header.js index 3bf0f91..ff7eee1 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -124,9 +124,7 @@ function handleTransparentAndScrolling(nav) { const header = nav.closest('header'); let prevScrollingPosition = 0; - document.addEventListener('scroll', () => { - const { scrollY } = window; - + const changeToTransparentIfNeeded = (scrollY) => { if (useTransparentVariant) { header.classList.add('transparent', 'can-be-transparent'); @@ -136,6 +134,12 @@ function handleTransparentAndScrolling(nav) { header.classList.add('transparent'); } } + }; + + document.addEventListener('scroll', () => { + const { scrollY } = window; + + changeToTransparentIfNeeded(scrollY); if (scrollY - prevScrollingPosition > 0 && scrollY > 200) { header.classList.add('fade-out'); @@ -145,6 +149,8 @@ function handleTransparentAndScrolling(nav) { prevScrollingPosition = scrollY; }); + + changeToTransparentIfNeeded(window.scrollY); } /** From a1704c40059b9aab67bf73f21335336188b0bed8 Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Thu, 12 Sep 2024 12:39:55 +0200 Subject: [PATCH 10/20] KAW-7904 Fix transparent header when click on models --- blocks/header/header.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/blocks/header/header.js b/blocks/header/header.js index ff7eee1..f110c82 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -91,6 +91,10 @@ function toggleSubNav(navSection, navSections) { const expanded = navSection.getAttribute('aria-expanded') === 'true'; toggleAllNavSections(navSections); navSection.setAttribute('aria-expanded', expanded ? 'false' : 'true'); + + if (!expanded) { + document.querySelector('header').classList.remove('transparent'); + } } function checkForActiveLink(navSections) { From 7879e87b45666a2dd265282657e57e8a8eba1c91 Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Thu, 12 Sep 2024 12:41:54 +0200 Subject: [PATCH 11/20] KAW-7904 Fix language selection --- blocks/header/header.css | 2 +- blocks/header/header.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/blocks/header/header.css b/blocks/header/header.css index 50009a6..f3e43b9 100644 --- a/blocks/header/header.css +++ b/blocks/header/header.css @@ -193,7 +193,7 @@ header .nav-tools .default-content-wrapper li.active::after { display: block; width: 100%; height: 1px; - background: black; + background: currentcolor; } diff --git a/blocks/header/header.js b/blocks/header/header.js index f110c82..4eb00d9 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -223,7 +223,7 @@ export default async function decorate(block) { toolsWrapper.querySelectorAll('li').forEach((item) => { item.addEventListener('click', redirectPage); - const urlLang = document.location.pathname.includes('/en/') ? 'en' : 'ita'; + const urlLang = document.location.pathname.includes('/en/') ? 'en' : 'it'; const listItemLang = item.textContent.trim().toLowerCase(); if (urlLang === listItemLang) { From 691330c07b3ca5f24b9cafaa1e7c9fd6165f7e79 Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Fri, 13 Sep 2024 12:06:42 +0200 Subject: [PATCH 12/20] KAW-7904 Add the Model label for expanded menu on desktop --- blocks/header/header.css | 29 +++++++++++++++++++++++------ blocks/header/header.js | 29 ++++++++++++++--------------- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/blocks/header/header.css b/blocks/header/header.css index f3e43b9..4626fad 100644 --- a/blocks/header/header.css +++ b/blocks/header/header.css @@ -95,7 +95,8 @@ header .nav-dealer-locator a.button:focus { color: var(--action-focus); } -header .nav-drop picture { +header .nav-drop picture, +header .nav-sublist > span { display: none; } @@ -160,13 +161,13 @@ header .nav-drop ul { cursor: auto; } -header .nav-sections ul > li > ul { +header .nav-sections ul > li .nav-sublist ul { margin: 0; gap: 16px; padding: 10px 0 0; } -header .nav-sections ul > li > ul a:any-link { +header .nav-sections ul > li .nav-sublist ul a:any-link { font-size: 0.875rem; font-style: normal; font-weight: 500; @@ -197,6 +198,7 @@ header .nav-tools .default-content-wrapper li.active::after { } +/* stylelint-disable-next-line no-descending-specificity */ header .nav-tools .default-content-wrapper li a:any-link { font-size: 0.875rem; font-style: normal; @@ -230,7 +232,7 @@ header .nav-drop { cursor: pointer; } -header .nav-drop[aria-expanded="false"] ul { +header .nav-drop[aria-expanded="false"] .nav-sublist { display: none; } @@ -419,7 +421,7 @@ header.transparent nav[aria-expanded="true"] .nav-link-section a.nav-drop-text { } /* expanded menu item content */ - header .nav-sections .nav-drop ul { + header .nav-sections .nav-drop .nav-sublist { position: fixed; top: var(--nav-height); padding: 40px; @@ -427,6 +429,10 @@ header.transparent nav[aria-expanded="true"] .nav-link-section a.nav-drop-text { left: 0; height: auto; background: var(--white); + } + + header .nav-sections .nav-drop ul { + padding: 0; gap: unset; justify-content: space-between; flex-wrap: wrap; @@ -444,10 +450,21 @@ header.transparent nav[aria-expanded="true"] .nav-link-section a.nav-drop-text { line-height: 140%; } - header .nav-sections .nav-drop ul picture { + header .nav-sections .nav-drop ul picture, + header .nav-sublist > span { display: flex; } + + header .nav-sublist > span { + padding: 0 40px 24px; + font-weight: 500; + font-size: 1.75rem; + line-height: 2.275; + color: var(--black); + cursor: auto; + } + header .nav-sections .nav-drop ul img { width: 187px; height: auto; diff --git a/blocks/header/header.js b/blocks/header/header.js index 4eb00d9..8c40cc7 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -190,7 +190,8 @@ export default async function decorate(block) { if (navSections) { navSections.querySelectorAll(':scope .default-content-wrapper > ul > li').forEach((navSection) => { - if (navSection.querySelector('ul')) { + const sublist = navSection.querySelector('ul'); + if (sublist) { const textWrapper = document.createElement('a'); textWrapper.classList.add('nav-drop-text'); textWrapper.append(navSection.firstChild); @@ -204,10 +205,21 @@ export default async function decorate(block) { link.prepend(picture); }); + + const sublistWrapper = document.createElement('div'); + sublistWrapper.classList.add('nav-sublist'); + const sublistHeading = document.createElement('span'); + sublistHeading.textContent = textWrapper.textContent; + sublist.replaceWith(sublistWrapper); + sublistWrapper.append(sublistHeading); + sublistWrapper.append(sublist); } navSection.addEventListener('click', (event) => { - if (event.target.classList.contains('nav-drop-text') || event.target.closest('.nav-drop-text')) { + if ( + event.target.classList.contains('nav-drop-text') + || event.target.classList.contains('nav-drop') + || event.target.closest('.nav-drop-text')) { toggleSubNav(navSection, navSections); } }); @@ -278,19 +290,6 @@ export default async function decorate(block) { block.append(navWrapper); checkForActiveLink(navSections); - - const observer = new IntersectionObserver((entries) => { - entries.forEach((entry) => { - if (entry.isIntersecting && isDesktop) { - navWrapper.classList.add('hide'); - } else if (isDesktop) { - navWrapper.classList.remove('hide'); - } - }); - }, { rootMargin: '0px 0px -1000px 0px' }); - observer.observe(document.querySelector('main')); - handleTransparentAndScrolling(nav); - customDecoreateIcons(nav); } From 5e649de6a941733e4e55a0515f0749c76a51c239 Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Fri, 13 Sep 2024 12:33:13 +0200 Subject: [PATCH 13/20] KAW-7904 Fix hover colors --- blocks/header/header.css | 4 ++-- blocks/header/header.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/blocks/header/header.css b/blocks/header/header.css index 4626fad..737b0f9 100644 --- a/blocks/header/header.css +++ b/blocks/header/header.css @@ -44,7 +44,7 @@ header a:any-link { header a:active, header a:focus, header a:hover { - color: var(--action-default); + color: var(--action-hover); } /* brand */ @@ -335,7 +335,7 @@ header.transparent nav[aria-expanded="true"] .nav-link-section a.nav-drop-text { } } -@media (width >= 1024px) { +@media (width >= 1025px) { header .nav-brand { flex-grow: unset; } diff --git a/blocks/header/header.js b/blocks/header/header.js index 8c40cc7..cee5e23 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -3,7 +3,7 @@ import { customDecoreateIcons } from '../../scripts/scripts.js'; import { loadFragment } from '../fragment/fragment.js'; // media query match that indicates mobile/tablet width -const isDesktop = window.matchMedia('(min-width: 1024px)'); +const isDesktop = window.matchMedia('(min-width: 1025px)'); function closeOnEscape(e) { if (e.code === 'Escape') { From 5b997f9404f99bf3edd39761a655433a787a70e2 Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Fri, 13 Sep 2024 13:04:56 +0200 Subject: [PATCH 14/20] KAW-7904 Disable main doc scrolling when the menu is expanded --- blocks/header/header.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/blocks/header/header.js b/blocks/header/header.js index cee5e23..f3e6b97 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -94,6 +94,9 @@ function toggleSubNav(navSection, navSections) { if (!expanded) { document.querySelector('header').classList.remove('transparent'); + document.body.style.overflow = 'hidden'; + } else { + document.body.style.overflow = ''; } } From 9e5545f0c1b3199dab787866449ba799f941d25c Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Mon, 16 Sep 2024 09:22:04 +0200 Subject: [PATCH 15/20] KAW-7904 Add animations for header --- blocks/header/header.css | 21 +++++++----- blocks/header/header.js | 71 +++++++++++++++++++++++++++++++++++----- 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/blocks/header/header.css b/blocks/header/header.css index 737b0f9..2a18a0d 100644 --- a/blocks/header/header.css +++ b/blocks/header/header.css @@ -96,10 +96,14 @@ header .nav-dealer-locator a.button:focus { } header .nav-drop picture, -header .nav-sublist > span { +header .nav-sublist > div > span { display: none; } +header .nav-sublist > div { + overflow: hidden; +} + header .nav-link-section { position: fixed; top: 0; @@ -136,10 +140,6 @@ header .nav-flag .icon { display: flex; } -header nav[aria-expanded="true"] .nav-link-section { - display: flex; -} - header .nav-sections ul { list-style: none; padding: 0; @@ -349,6 +349,7 @@ header.transparent nav[aria-expanded="true"] .nav-link-section a.nav-drop-text { height: auto; flex-grow: 1; align-items: center; + display: flex; } header .nav-backdrop { @@ -424,11 +425,15 @@ header.transparent nav[aria-expanded="true"] .nav-link-section a.nav-drop-text { header .nav-sections .nav-drop .nav-sublist { position: fixed; top: var(--nav-height); - padding: 40px; width: 100vw; left: 0; height: auto; background: var(--white); + padding: 0; + } + + header .nav-sections .nav-drop .nav-sublist > div { + padding: 40px; } header .nav-sections .nav-drop ul { @@ -451,12 +456,12 @@ header.transparent nav[aria-expanded="true"] .nav-link-section a.nav-drop-text { } header .nav-sections .nav-drop ul picture, - header .nav-sublist > span { + header .nav-sublist > div > span { display: flex; } - header .nav-sublist > span { + header .nav-sublist > div > span { padding: 0 40px 24px; font-weight: 500; font-size: 1.75rem; diff --git a/blocks/header/header.js b/blocks/header/header.js index f3e6b97..a06a164 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -5,6 +5,45 @@ import { loadFragment } from '../fragment/fragment.js'; // media query match that indicates mobile/tablet width const isDesktop = window.matchMedia('(min-width: 1025px)'); +const animateInOut = (animateTarget, isFadeIn, initStyles, startStyles, endStyles) => { + animateTarget.style.transition = 'all 300ms ease-in-out'; + + const setStyles = (targetEl, stylesObject) => { + Object.entries(stylesObject).forEach(([key, value]) => { + targetEl.style[key] = value; + }); + }; + + const cssReflow = () => { + // trigger reflow to ensure the transition starts from the current state + // read more here: https://gist.github.com/paulirish/5d52fb081b3570c81e3a + // eslint-disable-next-line no-unused-expressions + animateTarget.offsetWidth; + }; + + const restoreDisplayPropAfterHide = () => { + const transitionEndEvent = () => { + animateTarget.style.display = ''; + animateTarget.removeEventListener('transitionend', transitionEndEvent); + }; + + animateTarget.addEventListener('transitionend', transitionEndEvent); + }; + + setStyles(animateTarget, initStyles); + + if (isFadeIn) { + setStyles(animateTarget, startStyles); + cssReflow(); + setStyles(animateTarget, endStyles); + } else { + setStyles(animateTarget, endStyles); + cssReflow(); + restoreDisplayPropAfterHide(); + setStyles(animateTarget, startStyles); + } +}; + function closeOnEscape(e) { if (e.code === 'Escape') { const nav = document.getElementById('nav'); @@ -73,8 +112,18 @@ function toggleMenu(nav, navSections, forceExpanded = null) { const backdropEl = nav.querySelector('.nav-backdrop'); if (!expanded) { + if (document.querySelector('header nav .nav-link-section')) { + const animateTarget = document.querySelector('header nav .nav-link-section'); + + animateInOut(animateTarget, !expanded, { display: 'flex' }, { right: '-320px' }, { right: '0' }); + } backdropEl.classList.remove('hide'); } else { + if (document.querySelector('header nav .nav-link-section')) { + const animateTarget = document.querySelector('header nav .nav-link-section'); + + animateInOut(animateTarget, !expanded, { display: 'flex' }, { right: '-320px' }, { right: '0' }); + } backdropEl.classList.add('hide'); } @@ -90,14 +139,17 @@ function toggleMenu(nav, navSections, forceExpanded = null) { function toggleSubNav(navSection, navSections) { const expanded = navSection.getAttribute('aria-expanded') === 'true'; toggleAllNavSections(navSections); - navSection.setAttribute('aria-expanded', expanded ? 'false' : 'true'); if (!expanded) { document.querySelector('header').classList.remove('transparent'); document.body.style.overflow = 'hidden'; + animateInOut(navSection.querySelector('.nav-sublist'), expanded, { display: 'grid' }, { gridTemplateRows: '1fr' }, { gridTemplateRows: '0fr' }); } else { document.body.style.overflow = ''; + animateInOut(navSection.querySelector('.nav-sublist'), !expanded, { display: 'grid' }, { gridTemplateRows: '0fr' }, { gridTemplateRows: '1fr' }); } + + navSection.setAttribute('aria-expanded', expanded ? 'false' : 'true'); } function checkForActiveLink(navSections) { @@ -209,13 +261,16 @@ export default async function decorate(block) { link.prepend(picture); }); - const sublistWrapper = document.createElement('div'); - sublistWrapper.classList.add('nav-sublist'); - const sublistHeading = document.createElement('span'); - sublistHeading.textContent = textWrapper.textContent; - sublist.replaceWith(sublistWrapper); - sublistWrapper.append(sublistHeading); - sublistWrapper.append(sublist); + const navSublist = document.createRange().createContextualFragment(` + + `).children[0]; + + sublist.replaceWith(navSublist); } navSection.addEventListener('click', (event) => { From a5665823e2d11ebb75783f28bad954fab1fdeebb Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Mon, 16 Sep 2024 09:46:03 +0200 Subject: [PATCH 16/20] KAW-7904 Refactor --- blocks/header/header.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/blocks/header/header.js b/blocks/header/header.js index a06a164..3244c82 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -138,15 +138,16 @@ function toggleMenu(nav, navSections, forceExpanded = null) { function toggleSubNav(navSection, navSections) { const expanded = navSection.getAttribute('aria-expanded') === 'true'; + const navSublist = navSection.querySelector('.nav-sublist'); toggleAllNavSections(navSections); - if (!expanded) { + if (expanded) { + document.body.style.overflow = ''; + animateInOut(navSublist, !expanded, { display: 'grid' }, { gridTemplateRows: '0fr' }, { gridTemplateRows: '1fr' }); + } else { document.querySelector('header').classList.remove('transparent'); document.body.style.overflow = 'hidden'; - animateInOut(navSection.querySelector('.nav-sublist'), expanded, { display: 'grid' }, { gridTemplateRows: '1fr' }, { gridTemplateRows: '0fr' }); - } else { - document.body.style.overflow = ''; - animateInOut(navSection.querySelector('.nav-sublist'), !expanded, { display: 'grid' }, { gridTemplateRows: '0fr' }, { gridTemplateRows: '1fr' }); + animateInOut(navSublist, !expanded, { display: 'grid' }, { gridTemplateRows: '0fr' }, { gridTemplateRows: '1fr' }); } navSection.setAttribute('aria-expanded', expanded ? 'false' : 'true'); From 5d7ce3f68ea5d79624c41a09729ca92d215bc19d Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Mon, 16 Sep 2024 09:49:24 +0200 Subject: [PATCH 17/20] KAW-7904 Refactor --- blocks/header/header.js | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/blocks/header/header.js b/blocks/header/header.js index 3244c82..5c21304 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -112,21 +112,17 @@ function toggleMenu(nav, navSections, forceExpanded = null) { const backdropEl = nav.querySelector('.nav-backdrop'); if (!expanded) { - if (document.querySelector('header nav .nav-link-section')) { - const animateTarget = document.querySelector('header nav .nav-link-section'); - - animateInOut(animateTarget, !expanded, { display: 'flex' }, { right: '-320px' }, { right: '0' }); - } backdropEl.classList.remove('hide'); } else { - if (document.querySelector('header nav .nav-link-section')) { - const animateTarget = document.querySelector('header nav .nav-link-section'); - - animateInOut(animateTarget, !expanded, { display: 'flex' }, { right: '-320px' }, { right: '0' }); - } backdropEl.classList.add('hide'); } + if (document.querySelector('header nav .nav-link-section')) { + const animateTarget = document.querySelector('header nav .nav-link-section'); + + animateInOut(animateTarget, !expanded, { display: 'flex' }, { right: '-320px' }, { right: '0' }); + } + // enable menu collapse on escape keypress if (!expanded || isDesktop.matches) { // collapse menu on escape press @@ -143,13 +139,12 @@ function toggleSubNav(navSection, navSections) { if (expanded) { document.body.style.overflow = ''; - animateInOut(navSublist, !expanded, { display: 'grid' }, { gridTemplateRows: '0fr' }, { gridTemplateRows: '1fr' }); } else { document.querySelector('header').classList.remove('transparent'); document.body.style.overflow = 'hidden'; - animateInOut(navSublist, !expanded, { display: 'grid' }, { gridTemplateRows: '0fr' }, { gridTemplateRows: '1fr' }); } + animateInOut(navSublist, !expanded, { display: 'grid' }, { gridTemplateRows: '0fr' }, { gridTemplateRows: '1fr' }); navSection.setAttribute('aria-expanded', expanded ? 'false' : 'true'); } From 87f2be1929247aa67002954653d7d8620cfcc144 Mon Sep 17 00:00:00 2001 From: Tomasz Dziezyk Date: Mon, 16 Sep 2024 10:52:13 +0200 Subject: [PATCH 18/20] KAW-7904 Add animation for each model --- blocks/header/header.css | 8 ++++++++ blocks/header/header.js | 13 ++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/blocks/header/header.css b/blocks/header/header.css index 2a18a0d..4348d50 100644 --- a/blocks/header/header.css +++ b/blocks/header/header.css @@ -460,6 +460,14 @@ header.transparent nav[aria-expanded="true"] .nav-link-section a.nav-drop-text { display: flex; } + header .nav-sections .nav-sublist li { + transition: opacity 400ms linear; + opacity: 0; + } + + header .nav-sections .nav-sublist.subnav-fadein li { + opacity: 1; + } header .nav-sublist > div > span { padding: 0 40px 24px; diff --git a/blocks/header/header.js b/blocks/header/header.js index 5c21304..18b43f8 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -4,9 +4,10 @@ import { loadFragment } from '../fragment/fragment.js'; // media query match that indicates mobile/tablet width const isDesktop = window.matchMedia('(min-width: 1025px)'); +const fadeTransitionTime = 300; const animateInOut = (animateTarget, isFadeIn, initStyles, startStyles, endStyles) => { - animateTarget.style.transition = 'all 300ms ease-in-out'; + animateTarget.style.transition = `all ${fadeTransitionTime}ms ease-in-out`; const setStyles = (targetEl, stylesObject) => { Object.entries(stylesObject).forEach(([key, value]) => { @@ -139,8 +140,13 @@ function toggleSubNav(navSection, navSections) { if (expanded) { document.body.style.overflow = ''; + navSublist.classList.remove('subnav-fadein'); } else { document.querySelector('header').classList.remove('transparent'); + + setTimeout(() => { + navSublist.classList.add('subnav-fadein'); + }, 0); document.body.style.overflow = 'hidden'; } @@ -257,6 +263,11 @@ export default async function decorate(block) { link.prepend(picture); }); + // setting transtion delay for every list item + navSection.querySelectorAll('ul li').forEach((li, index) => { + li.style.transitionDelay = `${fadeTransitionTime + index * 200}ms`; + }); + const navSublist = document.createRange().createContextualFragment(`