diff --git a/libs/blocks/global-navigation/global-navigation.css b/libs/blocks/global-navigation/global-navigation.css index aaee255a65..f2bacb6dfe 100644 --- a/libs/blocks/global-navigation/global-navigation.css +++ b/libs/blocks/global-navigation/global-navigation.css @@ -991,6 +991,10 @@ header + .feds-localnav { z-index: 2; } +.feds-localnav a { + text-decoration: unset; +} + .feds-localnav-title { width: 100%; height: 53px; @@ -1011,6 +1015,10 @@ header + .feds-localnav { box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25); } +.feds-localnav-items .feds-navItem:first-child { + font-weight: 600; +} + .feds-localnav-items .feds-navLink { border: 0; } diff --git a/libs/blocks/global-navigation/global-navigation.js b/libs/blocks/global-navigation/global-navigation.js index 0c47abbca0..7269a0754c 100644 --- a/libs/blocks/global-navigation/global-navigation.js +++ b/libs/blocks/global-navigation/global-navigation.js @@ -39,7 +39,6 @@ import { darkIcons, setDisableAEDState, getDisableAEDState, - newNavEnabled, animateInSequence, transformTemplateToMobile, } from './utilities/utilities.js'; @@ -281,7 +280,7 @@ const convertToPascalCase = (str) => str .join(' '); class Gnav { - constructor({ content, block } = {}) { + constructor({ content, block, newMobileNav } = {}) { this.content = content; this.block = block; this.customLinks = getConfig()?.customLinks?.split(',') || []; @@ -297,8 +296,12 @@ class Gnav { this.setupUniversalNav(); this.elements = {}; + this.newMobileNav = newMobileNav; } + // eslint-disable-next-line no-return-assign + getOriginalTitle = (localNavItems) => this.originalTitle ||= localNavItems[0].querySelector('a').textContent.split('|'); + setupUniversalNav = () => { const meta = getMetadata('universal-nav')?.toLowerCase(); this.universalNavComponents = meta?.split(',').map((option) => option.trim()) @@ -367,26 +370,26 @@ class Gnav { `; }; - decorateLocalNav = () => { + decorateLocalNav = async () => { const localNavItems = this.elements.navWrapper.querySelector('.feds-nav').querySelectorAll('.feds-navItem:not(.feds-navItem--section)'); - const [title, navTitle = ''] = localNavItems[0].querySelector('a').textContent.split('|'); - if (this.elements.localNav || !newNavEnabled || !this.isLocalNav() || isDesktop.matches) { + const [title, navTitle = ''] = this.getOriginalTitle(localNavItems); + + if (this.elements.localNav || !this.newMobileNav || !this.isLocalNav() || isDesktop.matches) { localNavItems[0].querySelector('a').textContent = title.trim(); } else { - const localNav = toFragment` -
- -
-
`; + const localNav = document.querySelector('.feds-localnav'); + localNav.append(toFragment``, toFragment`
`); const itemWrapper = localNav.querySelector('.feds-localnav-items'); + const titleLabel = await replaceKey('overview', getFedsPlaceholderConfig()); + localNavItems.forEach((elem, idx) => { const clonedItem = elem.cloneNode(true); const link = clonedItem.querySelector('a'); if (idx === 0) { localNav.querySelector('.feds-localnav-title').innerText = title.trim(); - link.textContent = navTitle.trim() || title.trim(); + link.textContent = navTitle.trim() || titleLabel; } itemWrapper.appendChild(clonedItem); @@ -396,7 +399,6 @@ class Gnav { localNav.classList.toggle('active'); }); this.elements.localNav = localNav; - this.block.after(localNav); } }; @@ -737,7 +739,7 @@ class Gnav { toggleMenuMobile = () => { const toggle = this.elements.mobileToggle; const isExpanded = this.isToggleExpanded(); - if (!isExpanded && newNavEnabled) { + if (!isExpanded && this.newMobileNav) { const sections = document.querySelectorAll('header.new-nav .feds-nav > section.feds-navItem > button.feds-navLink'); animateInSequence(sections, 0.075); if (this.isLocalNav()) { @@ -1003,14 +1005,14 @@ class Gnav { type: itemType, }); - if (this.isLocalNav() && newNavEnabled) { + if (this.isLocalNav() && this.newMobileNav) { decorateLocalNavItems(item, template); } const popup = template.querySelector('.feds-popup'); let originalContent = popup.innerHTML; - if (!isDesktop.matches && newNavEnabled && popup) { + if (!isDesktop.matches && this.newMobileNav && popup) { originalContent = transformTemplateToMobile(popup, item, this.isLocalNav()); popup.querySelector('.close-icon')?.addEventListener('click', this.toggleMenuMobile); makeTabActive(popup); @@ -1054,7 +1056,7 @@ class Gnav { // Toggle trigger's dropdown on click dropdownTrigger.addEventListener('click', (e) => { - if (!isDesktop.matches && newNavEnabled && isSectionMenu) { + if (!isDesktop.matches && this.newMobileNav && isSectionMenu) { const popup = dropdownTrigger.nextElementSibling; makeTabActive(popup); } @@ -1184,6 +1186,7 @@ const getSource = async () => { export default async function init(block) { const { mep } = getConfig(); const sourceUrl = await getSource(); + const newMobileNav = getMetadata('mobile-gnav-v2') !== 'false'; const [url, hash = ''] = sourceUrl.split('#'); if (hash === '_noActiveItem') { setDisableAEDState(); @@ -1199,8 +1202,9 @@ export default async function init(block) { const gnav = new Gnav({ content, block, + newMobileNav, }); - if (newNavEnabled && !isDesktop.matches) block.classList.add('new-nav'); + if (newMobileNav && !isDesktop.matches) block.classList.add('new-nav'); await gnav.init(); if (gnav.isLocalNav()) block.classList.add('local-nav'); block.setAttribute('daa-im', 'true'); diff --git a/libs/blocks/global-navigation/utilities/utilities.js b/libs/blocks/global-navigation/utilities/utilities.js index 798579cc58..c51c462756 100644 --- a/libs/blocks/global-navigation/utilities/utilities.js +++ b/libs/blocks/global-navigation/utilities/utilities.js @@ -235,7 +235,6 @@ export function setCurtainState(state) { export const isDesktop = window.matchMedia('(min-width: 900px)'); export const isTangentToViewport = window.matchMedia('(min-width: 900px) and (max-width: 1440px)'); -export const newNavEnabled = new URL(window.location.href).searchParams.get('newNav') === 'true'; export function setActiveDropdown(elem) { const activeClass = selectors.activeDropdown.replace('.', ''); diff --git a/libs/navigation/bootstrapper.js b/libs/navigation/bootstrapper.js index 4f19bb3ffd..42968e24d6 100644 --- a/libs/navigation/bootstrapper.js +++ b/libs/navigation/bootstrapper.js @@ -26,6 +26,7 @@ export default async function bootstrapBlock(miloLibs, blockConfig) { const metaTags = [ { key: 'unavComponents', name: 'universal-nav' }, { key: 'redirect', name: 'adobe-home-redirect' }, + { key: 'useNewMobileNav', name: 'mobile-gnav-v2' }, ]; metaTags.forEach((tag) => { const { key } = tag; @@ -37,6 +38,10 @@ export default async function bootstrapBlock(miloLibs, blockConfig) { document.head.append(metaTag); } }); + if (blockConfig.isLocalNav) { + const localNavWrapper = createTag('div', { class: 'feds-localnav' }); + document.querySelector('header').after(localNavWrapper); + } } await initBlock(document.querySelector(targetEl)); diff --git a/libs/navigation/navigation.js b/libs/navigation/navigation.js index d54e439eaa..2cb7bbf4d4 100644 --- a/libs/navigation/navigation.js +++ b/libs/navigation/navigation.js @@ -60,6 +60,7 @@ export default async function loadBlock(configs, customLib) { locale = '', theme, stageDomainsMap = {}, + allowedOrigins = [], } = configs || {}; const branch = new URLSearchParams(window.location.search).get('navbranch'); const miloLibs = branch ? `https://${branch}--milo--adobecom.aem.page` : customLib || envMap[env]; @@ -77,14 +78,15 @@ export default async function loadBlock(configs, customLib) { const paramConfigs = getParamsConfigs(configs, miloLibs); const clientConfig = { + theme, + allowedOrigins, clientEnv: env, + ...paramConfigs, origin: `https://main--federal--adobecom.aem.${env === 'prod' ? 'live' : 'page'}`, miloLibs: `${miloLibs}/libs`, pathname: `/${locale}`, locales: configs.locales || locales, contentRoot: authoringPath || footer.authoringPath, - theme, - ...paramConfigs, stageDomainsMap: getStageDomainsMap(stageDomainsMap), }; setConfig(clientConfig); @@ -100,6 +102,8 @@ export default async function loadBlock(configs, customLib) { layout: configBlock.layout, noBorder: configBlock.noBorder, jarvis: configBlock.jarvis, + isLocalNav: configBlock.isLocalNav, + useNewMobileNav: configBlock.useNewMobileNav, }), }); configBlock.onReady?.(); diff --git a/libs/styles/styles.css b/libs/styles/styles.css index f5073cce6f..591535b4ed 100644 --- a/libs/styles/styles.css +++ b/libs/styles/styles.css @@ -724,6 +724,10 @@ header.global-navigation a { text-decoration: unset; } +.feds-localnav { + height: 53px; +} + @media (min-width: 900px) { header.global-navigation.has-breadcrumbs { padding-bottom: var(--global-height-breadcrumbs); diff --git a/libs/utils/utils.js b/libs/utils/utils.js index 13ecb1d7fb..c097af17d8 100644 --- a/libs/utils/utils.js +++ b/libs/utils/utils.js @@ -772,6 +772,11 @@ function decorateHeader() { const dynamicNavActive = getMetadata('dynamic-nav') === 'on' && window.sessionStorage.getItem('gnavSource') !== null; if (!dynamicNavActive && (baseBreadcrumbs || breadcrumbs || autoBreadcrumbs)) header.classList.add('has-breadcrumbs'); + if (getMetadata('is-localnav') === 'true' && getMetadata('mobile-gnav-v2') !== 'false') { + // Preserving space to avoid CLS issue + const localNavWrapper = createTag('div', { class: 'feds-localnav' }); + header.after(localNavWrapper); + } if (breadcrumbs) header.append(breadcrumbs); const promo = getMetadata('gnav-promo-source'); if (promo?.length) header.classList.add('has-promo');