diff --git a/blocks/header/header.css b/blocks/header/header.css index 98ba3ef..4fcfe82 100644 --- a/blocks/header/header.css +++ b/blocks/header/header.css @@ -1,433 +1,564 @@ /* header and nav layout */ -header .nav-wrapper { - --color-gray: #999; +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: 2; - position: relative; + color: var(--grey-90); + background-color: var(--white); } 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; + background-color: var(--white); } -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-hover); } -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; + gap: 8px; + border-radius: 26px; + background: var(--white); + 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); } -.nav-sections a.active, -.nav-drop.active .nav-drop-text { - color: var(--c-primary-white); +header .nav-dealer-locator a.button:hover { + border-color: var(--action-hover); + color: var(--action-hover); } -/* brand */ -header .nav-brand img { - max-width: 100%; - height: auto; +header .nav-dealer-locator a.button:focus { + border-color: var(--action-focus); + color: var(--action-focus); } -header .nav-link-section { - display: flex; - flex-flow: column; - gap: 30px; +header .nav-drop picture, +header .nav-sublist > div > span { + display: none; +} + +header .nav-sublist > div { + overflow: hidden; } -/* sections */ -header .nav-sections { - flex: 1; +header .nav-link-section { + position: fixed; + top: 0; + right: 0; + height: 100vh; + width: 320px; + padding: 25px 20px 0; display: none; - visibility: hidden; + flex-flow: column; + gap: 20px; + background-color: var(--white); + z-index: 2; } -header nav[aria-expanded='true'] .nav-sections { - display: flex; - visibility: visible; +header .nav-close-button { + align-self: flex-end; + width: 20px; + margin-bottom: 20px; } -.nav-tools .default-content-wrapper { +header .icon-close { display: flex; - padding: 7px; - list-style: none; - margin-bottom: 0; - align-items: center; + color: var(--grey-90); } -header .nav-sections .default-content-wrapper { - flex: 1; +header .nav-flag { + position: absolute; + bottom: 0; + right: 20px; + display: flex; } -.nav-sections .default-content-wrapper .nav-logo { - align-self: flex-start; +header .nav-flag .icon { + display: flex; } 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 .nav-sublist ul { + margin: 0; + gap: 16px; + padding: 10px 0 0; +} + +header .nav-sections ul > li .nav-sublist ul a:any-link { + font-size: 0.875rem; + font-style: normal; + font-weight: 500; + line-height: 150%; + letter-spacing: 0.44px; } -header nav[aria-expanded='true'] .nav-tools { +/* 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; + position: relative; +} + +header .nav-tools .default-content-wrapper li.active::after { + content: ""; + display: block; + width: 100%; + height: 1px; + background: currentcolor; +} + + +/* stylelint-disable-next-line no-descending-specificity */ +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 button svg { + color: var(--grey-90); } -header .nav-hamburger-icon::before, -header .nav-hamburger-icon::after { - content: ''; - position: absolute; - background: currentcolor; +/* nav-drop */ +header .nav-drop { + position: relative; + cursor: pointer; } -header nav[aria-expanded='true'] .nav-hamburger { - flex: initial; - align-self: flex-end; +header .nav-drop[aria-expanded="false"] .nav-sublist { + display: none; } -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-sections .nav-drop[aria-expanded="true"] { + color: var(--action-default); } -header nav[aria-expanded='false'] .nav-hamburger-icon::before { - top: -6px; +header .nav-drop .icon-chevron { + transition: transform 200ms ease-in-out; + transform-origin: center center; + display: flex; } -header nav[aria-expanded='false'] .nav-hamburger-icon::after { - top: 6px; +header .nav-drop[aria-expanded="true"] .icon-chevron { + transform: rotate(180deg); } -header nav[aria-expanded='true'] .nav-hamburger-icon { - height: 22px; +.nav-sections .nav-drop-text { + display: flex; + justify-content: space-between; } -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; +.nav-sections .nav-drop-text:hover { + text-decoration: none; } -header nav[aria-expanded='true'] .nav-hamburger-icon::after { - top: unset; - bottom: 3px; - transform: rotate(-45deg); +header .nav-backdrop { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background: rgb(0 0 0 / 40%); + z-index: 1; } -/* nav-drop */ -header .nav-drop { - position: relative; - cursor: pointer; +header .nav-backdrop.hide { + display: none; } -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.transparent nav { + background-color: transparent; + color: var(--white); } -header .nav-drop[aria-expanded='false'] ul { - display: none; +header.transparent .nav-wrapper { + background-color: transparent; } -header .nav-drop[aria-expanded='true'] ul { - display: flex; - flex-flow: column; - padding: 5px 0 5px 15px; +/* stylelint-disable-next-line no-descending-specificity */ +header.transparent a:any-link { + color: var(--white); } -header .nav-drop[aria-expanded='true']::after { - bottom: 0.5em; - transform: rotate(315deg); +header.transparent .nav-hamburger svg { + color: var(--white); } -.nav-sections .nav-drop-text:hover { - text-decoration: none; +header.transparent .nav-dealer-locator a.button { + background-color: var(--white); + border-color: transparent; + color: var(--black); } -.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.transparent .nav-dealer-locator a.button:hover { + border-color: var(--action-hover); + color: var(--action-hover); } -@media (width >= 640px) { - header .nav-drop::after { - top: 8px; - } +header.transparent .nav-dealer-locator a.button:focus { + border-color: var(--action-focus); + color: var(--action-focus); } -@media (width >= 992px) { - header { - --nav-height: 130px; - } +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 { - 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 >= 1025px) { header .nav-brand { - display: block; - align-self: flex-end; + flex-grow: unset; } header .nav-link-section { - flex-flow: row; + position: static; + width: auto; + padding: 0; + flex-direction: row; + background-color: transparent; + height: auto; + flex-grow: 1; + align-items: center; + display: flex; } - header .nav-sections { + header .nav-backdrop { + display: none; + } + + header .nav-hamburger, + header .nav-close-button, + header .nav-flag, + header .nav-drop-text .icon-chevron { + display: none; + } + + header .nav-dealer-locator { + margin: 0; display: flex; - visibility: visible; - white-space: nowrap; align-items: center; } - header .nav-sections .default-content-wrapper { + header .nav-sections { + flex-grow: 1; + justify-content: center; display: flex; - flex-flow: row; - justify-content: space-between; - flex: 1; - align-items: center; } - .nav-logo-mobile .icon-logo-bimota-h { - display: none; + header .nav-sections ul { + flex-direction: row; + gap: 28px; + } + + header .nav-tools { + margin-right: 24px; + } + + header .nav-tools ul { + flex-direction: row; + gap: 12px; + } + + header .nav-tools .default-content-wrapper { + margin: 0; + } + + 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; } - header .nav-sections .icon-logo-bimota-h { + header .nav-sections ul li { + 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; - height: 100%; width: 100%; - max-width: 250px; - max-height: 70px; + height: 1px; + position: absolute; + bottom: 0; + background: currentcolor; } - .nav-sections a:hover, - .nav-sections a.active, - .nav-drop.active .nav-drop-text { - color: var(--link-color); + /* expanded menu item content */ + header .nav-sections .nav-drop .nav-sublist { + position: fixed; + top: var(--nav-height); + width: 100vw; + left: 0; + height: auto; + background: var(--white); + padding: 0; + overflow: hidden; } - header .nav-sections ul { - display: flex; - gap: 30px; - margin: 0; - flex-flow: row; - align-items: center; - justify-content: center; + header .nav-sections .nav-drop .nav-sublist > div { + padding: 40px; + margin: auto; } - .nav-tools .default-content-wrapper li { - cursor: pointer; + header .nav-sections .nav-drop ul { + padding: 0; + gap: unset; + justify-content: space-between; + flex-wrap: wrap; + row-gap: 40px; } - header .nav-sections .default-content-wrapper > ul > li { - flex: 0 1 auto; - position: relative; + 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; - min-height: 80px; + line-height: 140%; + } + + header .nav-sections .nav-drop ul picture:first-child, + header .nav-sublist > div > span { display: flex; } - header .nav-sections .default-content-wrapper > ul > li > ul { + header .nav-sections .nav-sublist li { + transition: opacity 400ms linear; + opacity: 0; + } + + header .nav-sections .nav-sublist a.swipe-on-hover:hover picture:first-child { display: none; - position: relative; } - header .nav-sections .default-content-wrapper > ul > li[aria-expanded='true'] > ul { + header .nav-sections .nav-sublist a.swipe-on-hover:hover picture:nth-child(2) { + display: flex; + } + + header .nav-sections .nav-sublist.subnav-fadein li { + opacity: 1; + } + + header .nav-sublist > div > 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; + } + + header .nav-drop[aria-expanded="true"]::after { + content: ""; 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%); + 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; } - .nav-tools .default-content-wrapper a, - .nav-drop-text { - color: var(--text-color); + 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); } - .nav-tools a:any-link:hover { - color: var(--text-color); + header.transparent + nav[aria-expanded="true"] + .nav-link-section + .nav-drop + a:any-link { + color: var(--grey-90); } - - .nav-sections .nav-drop ul a:any-link { - color: var(--color-gray); + + header.transparent + nav[aria-expanded="true"] + .nav-link-section + .nav-drop + a:focus { + color: var(--action-focus); } - - .nav-sections .nav-drop ul a:hover { - color: var(--link-hover-color); + + header.transparent + nav[aria-expanded="true"] + .nav-link-section + .nav-drop + a:hover { + color: var(--action-hover); } +} - header .nav-sections .default-content-wrapper > ul > li > ul > li { - padding: 8px 0; +@media (width >= 1440px) { + header nav { + padding-left: 0; + padding-right: 0; } - header .nav-drop::after { - display: none; + header .nav-sections .nav-drop ul { + padding-left: calc((100vw - 1240px) / 2); + padding-right: calc((100vw - 1240px) / 2); } - header nav[aria-expanded='true'] .nav-tools { + header .nav-sections .nav-drop .nav-sublist > div { + width: 1440px; + max-width: 1440px; + padding-left: 100px; + padding-right: 100px; + } + + header .nav-sections .nav-drop .nav-sublist > div > span { padding-left: 0; + padding-right: 0; } -} \ No newline at end of file +} diff --git a/blocks/header/header.js b/blocks/header/header.js index 4ebced2..f527209 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -1,8 +1,49 @@ 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: 992px)'); +const isDesktop = window.matchMedia('(min-width: 1025px)'); +const fadeTransitionTime = 300; + +const animateInOut = (animateTarget, isFadeIn, initStyles, startStyles, endStyles) => { + animateTarget.style.transition = `all ${fadeTransitionTime}ms 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') { @@ -70,6 +111,19 @@ function toggleMenu(nav, navSections, forceExpanded = null) { } }); + const backdropEl = nav.querySelector('.nav-backdrop'); + if (!expanded) { + backdropEl.classList.remove('hide'); + } else { + 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 @@ -81,7 +135,22 @@ 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) { + 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'; + } + + animateInOut(navSublist, !expanded, { display: 'grid' }, { gridTemplateRows: '0fr' }, { gridTemplateRows: '1fr' }); navSection.setAttribute('aria-expanded', expanded ? 'false' : 'true'); } @@ -100,7 +169,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`; } @@ -110,6 +179,41 @@ 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; + + const changeToTransparentIfNeeded = (scrollY) => { + if (useTransparentVariant) { + header.classList.add('transparent', 'can-be-transparent'); + + if (scrollY > 100) { + header.classList.remove('transparent'); + } else { + header.classList.add('transparent'); + } + } + }; + + document.addEventListener('scroll', () => { + const { scrollY } = window; + + changeToTransparentIfNeeded(scrollY); + + if (scrollY - prevScrollingPosition > 0 && scrollY > 200) { + header.classList.add('fade-out'); + } else if (prevScrollingPosition - scrollY > 0) { + header.classList.remove('fade-out'); + } + + prevScrollingPosition = scrollY; + }); + + changeToTransparentIfNeeded(window.scrollY); +} + /** * loads and decorates the header, mainly the nav * @param {Element} block The header block element @@ -126,7 +230,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 +244,55 @@ 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 sublist = navSection.querySelector('ul'); + if (sublist) { const textWrapper = document.createElement('a'); textWrapper.classList.add('nav-drop-text'); textWrapper.append(navSection.firstChild); + textWrapper.innerHTML += ''; 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 pictures = link.parentElement.querySelectorAll('picture'); + + if (pictures.length === 2) { + link.classList.add('swipe-on-hover'); + } + + link.prepend(...pictures); + }); + + // 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(` + + `).children[0]; + + sublist.replaceWith(navSublist); } - navSection.addEventListener('click', () => toggleSubNav(navSection, navSections)); + navSection.addEventListener('click', (event) => { + if ( + event.target.classList.contains('nav-drop-text') + || event.target.classList.contains('nav-drop') + || event.target.closest('.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'); @@ -171,26 +301,51 @@ 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' : 'it'; + const listItemLang = item.textContent.trim().toLowerCase(); + + if (urlLang === listItemLang) { + item.classList.add('active'); + } }); } + 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 = ''; + const closeEl = document.createElement('button'); + closeEl.classList.add('nav-close-button'); + closeEl.innerHTML = ''; + 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,19 +355,10 @@ 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); - - 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); } 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); diff --git a/styles/styles.css b/styles/styles.css index 2620f91..a9ea218 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); @@ -491,6 +494,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);