Skip to content

Commit

Permalink
Localnav design and event listeners (#3164)
Browse files Browse the repository at this point in the history
* Localnav design and event listeners

* Lint fix

* Adding Overview title support
  • Loading branch information
bandana147 authored Nov 11, 2024
1 parent 2c71641 commit 7f05e43
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 29 deletions.
57 changes: 48 additions & 9 deletions libs/blocks/global-navigation/global-navigation.css
Original file line number Diff line number Diff line change
Expand Up @@ -987,28 +987,28 @@ header + .feds-localnav {
display: block;
top: 0;
width: 100%;
background: #fff;
left: 0;
z-index: 2;
}

.feds-localnav-title {
width: 100%;
height: 80px;
font-size: 22px;
font-weight: 600;
height: 53px;
font-size: 16px;
font-weight: 700;
border: 0;
padding: 12px;
padding: 0 20px;
text-align: justify;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
background-color: #fff;
background-color: #F8F8F8;
}

.feds-localnav-items {
background-color: #fff;
background: #F3F3F3;
border-bottom: 1px solid #eee;
display: none;
box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
}

.feds-localnav-items .feds-navLink {
Expand All @@ -1017,14 +1017,53 @@ header + .feds-localnav {

.feds-localnav.active .feds-localnav-items {
display: block;
width: 100%;
position: absolute;
}

.feds-localnav .feds-localnav-items .feds-navLink {
.feds-localnav.active .feds-localnav-items .feds-menu-items {
padding: 0;
border-bottom: 0;
font-size: 16px;
}

.feds-localnav.active .feds-localnav-items .feds-menu-column > ul {
padding: 0;
}

.feds-localnav.active .feds-localnav-items .feds-menu-column > ul .feds-navLink {
padding-left: 38px;
}

.feds-localnav.active .feds-localnav-items .feds-menu-items .feds-navLink {
padding: 12px 56px;
}

.feds-localnav .feds-navLink[aria-expanded="true"] {
font-weight: 600;
}

.feds-localnav .feds-localnav-items .feds-navLink {
border-bottom: 0;
font-size: 14px;
padding: 12px 20px;
background: #F3F3F3;
}

.feds-localnav .feds-localnav-items .feds-menu-headline {
background: #F3F3F3;
font-weight: 400;
border-bottom: 0;
padding: 12px 38px;
}

.feds-localnav .feds-localnav-items .feds-navItem--centered {
padding: 12px 20px;
}

.feds-localnav .feds-dropdown--active::before {
display: none;
}

.feds-localnav.active .feds-localnav-title::after {
transform: rotateZ(-135deg);
}
Expand Down
77 changes: 60 additions & 17 deletions libs/blocks/global-navigation/global-navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -368,23 +368,36 @@ class Gnav {
};

decorateLocalNav = () => {
if (!newNavEnabled || !this.isLocalNav()) return;
const localNav = toFragment`<div class="feds-localnav"><button class="feds-navLink--hoverCaret feds-localnav-title"></button><div class="feds-localnav-items"></div></div>`;
const localNavitems = this.elements.navWrapper.querySelector('.feds-nav').querySelectorAll('.feds-navItem:not(.feds-navItem--section)');
const itemWrapper = localNav.querySelector('.feds-localnav-items');
localNavitems.forEach((elem, idx) => {
if (idx === 0) {
localNav.querySelector('.feds-localnav-title').innerText = elem.textContent.trim();
return;
}
itemWrapper.appendChild(elem.cloneNode(true));
});
localNav.querySelector('.feds-localnav-title').addEventListener('click', () => {
if (localNav.classList.contains('active')) localNav.classList.remove('active');
else localNav.classList.add('active');
});
this.elements.localNav = localNav;
this.block.after(localNav);
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) {
localNavItems[0].querySelector('a').textContent = title.trim();
} else {
const localNav = toFragment`
<div class="feds-localnav">
<button class="feds-navLink--hoverCaret feds-localnav-title"></button>
<div class="feds-localnav-items"></div>
</div>`;

const itemWrapper = localNav.querySelector('.feds-localnav-items');
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();
}

itemWrapper.appendChild(clonedItem);
});

localNav.querySelector('.feds-localnav-title').addEventListener('click', () => {
localNav.classList.toggle('active');
});
this.elements.localNav = localNav;
this.block.after(localNav);
}
};

decorateTopnavWrapper = async () => {
Expand All @@ -400,6 +413,7 @@ class Gnav {
this.elements.aside,
this.elements.topnavWrapper,
);

this.decorateLocalNav();
};

Expand Down Expand Up @@ -431,6 +445,7 @@ class Gnav {
this.elements.navWrapper.prepend(this.elements.breadcrumbsWrapper);
}
}
this.decorateLocalNav();
});

// Add a modifier when the nav is tangent to the viewport and content is partly hidden
Expand Down Expand Up @@ -949,6 +964,29 @@ class Gnav {
}
};

// Copying dropdown contents to localNav items
const decorateLocalNavItems = (navItem, template) => {
const elements = [...document.querySelectorAll('.feds-localnav .feds-navItem')].find(
(el) => el.textContent.trim() === navItem.textContent,
);
if (elements) {
elements.innerHTML = template.innerHTML;
// Reattach click events, as cloned elem don't retain event listeners
elements.querySelector('button')?.addEventListener('click', (e) => {
trigger({ element: e.currentTarget, event: e, type: 'localNavTitle' });
setActiveDropdown(e.currentTarget);
});

elements.querySelectorAll('.feds-menu-headline').forEach((elem) => {
// Reattach click event listener to headlines
elem?.addEventListener('click', (e) => {
trigger({ element: e.currentTarget, event: e, type: 'headline' });
setActiveDropdown(e.currentTarget);
});
});
}
};

// All dropdown decoration is delayed
const delayDropdownDecoration = ({ template } = {}) => {
let decorationTimeout;
Expand All @@ -964,6 +1002,11 @@ class Gnav {
template,
type: itemType,
});

if (this.isLocalNav() && newNavEnabled) {
decorateLocalNavItems(item, template);
}

const popup = template.querySelector('.feds-popup');
let originalContent = popup.innerHTML;

Expand Down
13 changes: 10 additions & 3 deletions libs/blocks/global-navigation/utilities/utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ loadLana();

const FEDERAL_PATH_KEY = 'federal';

const selectorMap = {
headline: '.feds-menu-headline[aria-expanded="true"]',
localNavTitle: '.feds-navLink[aria-expanded="true"]',
};

export const selectors = {
globalNav: '.global-navigation',
curtain: '.feds-curtain',
Expand Down Expand Up @@ -302,9 +307,8 @@ export const [hasActiveLink, setActiveLink, isActiveLink, getActiveLink] = (() =
})();

export function closeAllDropdowns({ type } = {}) {
const selector = type === 'headline'
? '.feds-menu-headline[aria-expanded="true"]'
: `${selectors.globalNav} [aria-expanded='true']`;
const selector = selectorMap[type] || `${selectors.globalNav} [aria-expanded='true']`;

const openElements = document.querySelectorAll(selector);
if (!openElements) return;
[...openElements].forEach((el) => {
Expand Down Expand Up @@ -414,6 +418,9 @@ export const [setUserProfile, getUserProfile] = (() => {
})();

export const transformTemplateToMobile = async (popup, item, localnav = false) => {
const notMegaMenu = popup.parentElement.tagName === 'DIV';
if (notMegaMenu) return;

const originalContent = popup.innerHTML;
const tabs = [...popup.querySelectorAll('.feds-menu-section')]
.filter((section) => !section.querySelector('.feds-promo') && section.textContent)
Expand Down

0 comments on commit 7f05e43

Please sign in to comment.