diff --git a/blocks/header/header.css b/blocks/header/header.css index 741e2da..98ba3ef 100644 --- a/blocks/header/header.css +++ b/blocks/header/header.css @@ -1,51 +1,42 @@ /* header and nav layout */ header .nav-wrapper { - background-color: var(--background-color); + --color-gray: #999; + width: 100%; z-index: 2; - position: fixed; + position: relative; } header nav { box-sizing: border-box; - display: grid; - grid-template: - 'hamburger brand tools' var(--nav-height) - 'sections sections sections' 1fr / auto 1fr auto; - align-items: center; - gap: 0 2em; - margin: auto; - max-width: 1264px; + display: flex; + flex-flow: column; height: var(--nav-height); - padding: 0 1rem; - font-family: var(--body-font-family); + padding: 15px 30px; } header nav[aria-expanded='true'] { - grid-template: - 'hamburger brand' var(--nav-height) - 'sections sections' 1fr - 'tools tools' var(--nav-height) / auto 1fr; overflow-y: auto; min-height: 100vh; + background-color: #222; + color: var(--color-gray); + max-width: 350px; + width: 50%; + position: relative; + min-width: 270px } -@media (width >= 600px) { - header nav { - padding: 0 2rem; - } +header .nav-brand, +.nav-link-section .icon-logo-bimota-h { + display: none; } -@media (width >= 900px) { - header nav { - display: flex; - justify-content: space-between; - } +header .nav-wrapper.hide .nav-brand { + display: none; +} - header nav[aria-expanded='true'] { - min-height: 0; - overflow: visible; - } +header .nav-wrapper.hide nav { + height: 100px; } header nav p { @@ -53,53 +44,163 @@ header nav p { line-height: 1; } -header nav a:any-link { +.nav-logo-mobile { + position: absolute; + top: 10px; + left: 0; + transform: translateX(40vw); +} + +.nav-logo-mobile .icon-logo-bimota-h { + width: 100%; + height: 100%; + max-width: 170px; + max-height: 47px; +} + +header a:any-link, +.nav-drop-text { color: currentcolor; + padding: 5px 0; + display: flex; + align-items: center; + column-gap: .25em; + text-decoration: none; +} + +.nav-sections a.active, +.nav-drop.active .nav-drop-text { + color: var(--c-primary-white); +} + +/* brand */ +header .nav-brand img { + max-width: 100%; + height: auto; +} + +header .nav-link-section { + display: flex; + flex-flow: column; + gap: 30px; +} + +/* sections */ +header .nav-sections { + flex: 1; + display: none; + visibility: hidden; +} + +header nav[aria-expanded='true'] .nav-sections { + display: flex; + visibility: visible; +} + +.nav-tools .default-content-wrapper { + 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; + display: flex; + align-items: flex-start; + column-gap: .25em; + flex-flow: column; +} + +header .nav-sections ul li { + width: 100%; +} + +.nav-sections ul > li > ul { + margin-top: 0; +} + +/* tools */ +header .nav-tools { + display: none; + visibility: hidden; +} + +header nav[aria-expanded='true'] .nav-tools { + display: flex; + visibility: visible; + padding-left: 30px; + align-items: center; +} + +.nav-tools .default-content-wrapper li { + padding: 5px 10px 6px; + line-height: 1; + color: var(--c-primary-white); } /* hamburger */ -header nav .nav-hamburger { - grid-area: hamburger; +header .nav-hamburger { height: 22px; display: flex; - align-items: center; + align-self: start; + justify-content: flex-end; + flex: 1; } -header nav .nav-hamburger button { +header .nav-hamburger button { height: 22px; - margin: 0; + margin: auto; border: 0; border-radius: 0; padding: 0; - background-color: var(--background-color); + background-color: transparent; color: inherit; overflow: initial; text-overflow: initial; white-space: initial; + cursor: pointer; } -header nav .nav-hamburger-icon, -header nav .nav-hamburger-icon::before, -header nav .nav-hamburger-icon::after { +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 .nav-hamburger-icon::before, -header nav .nav-hamburger-icon::after { +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: currentcolor; + background: var(--color-gray); } header nav[aria-expanded='false'] .nav-hamburger-icon::before { @@ -131,145 +232,202 @@ header nav[aria-expanded='true'] .nav-hamburger-icon::after { transform: rotate(-45deg); } -@media (width >= 900px) { - header nav .nav-hamburger { - display: none; - visibility: hidden; - } -} - -/* brand */ -header .nav-brand { - grid-area: brand; - flex-basis: 128px; - font-size: var(--heading-font-size-s); - font-weight: 700; - line-height: 1; +/* nav-drop */ +header .nav-drop { + position: relative; + cursor: pointer; } -header nav .nav-brand img { - width: 128px; - height: auto; +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; } -/* sections */ -header nav .nav-sections { - grid-area: sections; - flex: 1 1 auto; +header .nav-drop[aria-expanded='false'] ul { display: none; - visibility: hidden; - background-color: var(--overlay-color); } -header nav[aria-expanded='true'] .nav-sections { - display: block; - visibility: visible; - align-self: start; +header .nav-drop[aria-expanded='true'] ul { + display: flex; + flex-flow: column; + padding: 5px 0 5px 15px; } -header nav .nav-sections ul { - list-style: none; - padding-left: 0; - font-size: var(--body-font-size-s); - font-weight: 500; +header .nav-drop[aria-expanded='true']::after { + bottom: 0.5em; + transform: rotate(315deg); } -header nav .nav-sections ul > li { - font-weight: 700; +.nav-sections .nav-drop-text:hover { + text-decoration: none; } -header nav .nav-sections ul > li > ul { - margin-top: 0; +.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 .nav-sections ul > li > ul > li { - font-weight: 500; +@media (width >= 640px) { + header .nav-drop::after { + top: 8px; + } } -@media (width >= 900px) { - header nav .nav-sections { +@media (width >= 992px) { + header { + --nav-height: 130px; + } + + header nav { + display: flex; + justify-content: space-between; + } + + 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-wrapper { + max-width: 100%; + background-color: var(--c-primary-white); + position: fixed; + } + + 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 .nav-hamburger { + display: none; + visibility: hidden; + } + + header .nav-brand { display: block; + align-self: flex-end; + } + + header .nav-link-section { + flex-flow: row; + } + + header .nav-sections { + display: flex; visibility: visible; white-space: nowrap; + align-items: center; } - header nav[aria-expanded='true'] .nav-sections { - align-self: unset; + header .nav-sections .default-content-wrapper { + display: flex; + flex-flow: row; + justify-content: space-between; + flex: 1; + align-items: center; } - header nav .nav-sections .nav-drop { - position: relative; - padding-right: 16px; - cursor: pointer; + .nav-logo-mobile .icon-logo-bimota-h { + display: none; } - header nav .nav-sections .nav-drop::after { - content: ''; - display: inline-block; - position: absolute; - top: 0.5em; - right: 2px; - 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-sections .icon-logo-bimota-h { + display: block; + height: 100%; + width: 100%; + max-width: 250px; + max-height: 70px; } - header nav .nav-sections .nav-drop[aria-expanded='true']::after { - top: unset; - bottom: 0.5em; - transform: rotate(315deg); + .nav-sections a:hover, + .nav-sections a.active, + .nav-drop.active .nav-drop-text { + color: var(--link-color); } - header nav .nav-sections ul { + header .nav-sections ul { display: flex; - gap: 2em; + gap: 30px; margin: 0; - font-size: var(--body-font-size-xs); + flex-flow: row; + align-items: center; + justify-content: center; + } + + .nav-tools .default-content-wrapper li { + cursor: pointer; } - header nav .nav-sections .default-content-wrapper > ul > li { + header .nav-sections .default-content-wrapper > ul > li { flex: 0 1 auto; position: relative; font-weight: 500; + min-height: 80px; + display: flex; } - header nav .nav-sections .default-content-wrapper > ul > li > ul { + header .nav-sections .default-content-wrapper > ul > li > ul { display: none; position: relative; } - header nav .nav-sections .default-content-wrapper > ul > li[aria-expanded='true'] > ul { + header .nav-sections .default-content-wrapper > ul > li[aria-expanded='true'] > ul { display: block; position: absolute; - left: -1em; - width: 200px; - margin-top: 12px; - padding: 1em; - background-color: var(--light-color); + 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 .nav-sections .default-content-wrapper > ul > li > ul::before { - content: ''; - position: absolute; - top: -8px; - left: 8px; - width: 0; - height: 0; - border-left: 8px solid transparent; - border-right: 8px solid transparent; - border-bottom: 8px solid var(--light-color); + .nav-tools .default-content-wrapper a, + .nav-drop-text { + color: var(--text-color); } - header nav .nav-sections .default-content-wrapper > ul > li > ul > li { + .nav-tools a:any-link:hover { + color: var(--text-color); + } + + .nav-sections .nav-drop ul a:any-link { + color: var(--color-gray); + } + + .nav-sections .nav-drop ul a:hover { + color: var(--link-hover-color); + } + + header .nav-sections .default-content-wrapper > ul > li > ul > li { padding: 8px 0; } -} -/* tools */ -header nav .nav-tools { - grid-area: tools; -} + header .nav-drop::after { + display: none; + } + + header nav[aria-expanded='true'] .nav-tools { + padding-left: 0; + } +} \ No newline at end of file diff --git a/blocks/header/header.js b/blocks/header/header.js index f7f719d..4ebced2 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -2,7 +2,7 @@ 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: 900px)'); +const isDesktop = window.matchMedia('(min-width: 992px)'); function closeOnEscape(e) { if (e.code === 'Escape') { @@ -58,25 +58,18 @@ function toggleMenu(nav, navSections, forceExpanded = null) { const button = nav.querySelector('.nav-hamburger button'); document.body.style.overflowY = (expanded || isDesktop.matches) ? '' : 'hidden'; nav.setAttribute('aria-expanded', expanded ? 'false' : 'true'); - toggleAllNavSections(navSections, expanded || isDesktop.matches ? 'false' : 'true'); + toggleAllNavSections(navSections, false); button.setAttribute('aria-label', expanded ? 'Open navigation' : 'Close navigation'); // enable nav dropdown keyboard accessibility const navDrops = navSections.querySelectorAll('.nav-drop'); - if (isDesktop.matches) { - navDrops.forEach((drop) => { - if (!drop.hasAttribute('tabindex')) { - drop.setAttribute('role', 'button'); - drop.setAttribute('tabindex', 0); - drop.addEventListener('focus', focusNavSection); - } - }); - } else { - navDrops.forEach((drop) => { - drop.removeAttribute('role'); - drop.removeAttribute('tabindex'); - drop.removeEventListener('focus', focusNavSection); - }); - } + navDrops.forEach((drop) => { + if (!drop.hasAttribute('tabindex')) { + drop.setAttribute('role', 'button'); + drop.setAttribute('tabindex', 0); + drop.addEventListener('focus', focusNavSection); + } + }); + // enable menu collapse on escape keypress if (!expanded || isDesktop.matches) { // collapse menu on escape press @@ -86,6 +79,37 @@ 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'); +} + +function checkForActiveLink(navSections) { + navSections.querySelectorAll(':scope .default-content-wrapper a').forEach((link) => { + const href = link.getAttribute('href'); + if (href === window.location.pathname || href === window.location.href) { + const navParent = link.closest('.nav-drop'); + navParent?.classList.add('active'); + link.classList.add('active'); + } + }); +} + +function redirectPage(event) { + const currentUrl = window.location; + let redirectUrl = currentUrl.origin; + + if (event.target.innerHTML === 'ENG') { + if (!currentUrl.pathname.includes('/en/')) { + redirectUrl = `${redirectUrl}/en`; + } + redirectUrl = `${redirectUrl}${currentUrl.pathname}`; + } else { + redirectUrl = `${redirectUrl}${currentUrl.pathname.replace(/\/en\//, '/')}`; + } + window.location.replace(redirectUrl); +} /** * loads and decorates the header, mainly the nav * @param {Element} block The header block element @@ -116,34 +140,79 @@ 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')) navSection.classList.add('nav-drop'); - navSection.addEventListener('click', () => { - if (isDesktop.matches) { - const expanded = navSection.getAttribute('aria-expanded') === 'true'; - toggleAllNavSections(navSections); - navSection.setAttribute('aria-expanded', expanded ? 'false' : 'true'); - } - }); + if (navSection.querySelector('ul')) { + const textWrapper = document.createElement('a'); + textWrapper.classList.add('nav-drop-text'); + textWrapper.append(navSection.firstChild); + navSection.prepend(textWrapper); + navSection.classList.add('nav-drop'); + } + + navSection.addEventListener('click', () => 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'); + if (navTools) { + const toolsWrapper = navTools.querySelector('ul'); + toolsWrapper.classList.add('default-content-wrapper'); + navTools.append(toolsWrapper); + navTools.firstElementChild.remove(); + toolsWrapper.querySelectorAll('li').forEach((list) => { + list.addEventListener('click', redirectPage); }); } + if (navSections && navTools) { + const navLinksWrapper = document.createElement('div'); + navLinksWrapper.classList.add('nav-link-section'); + navLinksWrapper.append(navSections, navTools); + nav.append(navLinksWrapper); + } + // 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.setAttribute('aria-expanded', 'false'); // prevent mobile nav behavior on window resize toggleMenu(nav, navSections, isDesktop.matches); - isDesktop.addEventListener('change', () => toggleMenu(nav, navSections, isDesktop.matches)); + isDesktop.addEventListener('change', () => { + toggleMenu(nav, navSections, isDesktop.matches); + }); const navWrapper = document.createElement('div'); navWrapper.className = 'nav-wrapper'; - navWrapper.append(nav); + navWrapper.append(mobileLogoWrapper, 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')); } diff --git a/icons/logo-biomota-W.svg b/icons/logo-bimota-W.svg similarity index 100% rename from icons/logo-biomota-W.svg rename to icons/logo-bimota-W.svg diff --git a/icons/logo-bimota-h.svg b/icons/logo-bimota-h.svg new file mode 100644 index 0000000..d32e1d3 --- /dev/null +++ b/icons/logo-bimota-h.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/styles/styles.css b/styles/styles.css index 7056d3e..0f5e9fa 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -26,7 +26,7 @@ --body-font-size: 16px; /* nav height */ - --nav-height: 64px; + --nav-height: 80px; /* section paddings */ --section-y-padding: 15px;