Version 5.0.0 beta 1
This commit is contained in:
1 parent
25ddeb65d6
commit
15c7beabc5
6736 files changed
+627902
-497943
No files matched your search
@@ -0,0 +1,92 @@
|
||||
customElements.define('i-navigation-menu', class extends HTMLElement {
|
||||
|
||||
constructor () {
|
||||
super();
|
||||
this.menu = this.querySelector('.ipsNavBar');
|
||||
this.moreLi = this.menu.querySelector("[data-el='nav-more']");
|
||||
this.moreMenu = this.moreLi.querySelector(".ipsNav__dropdown");
|
||||
}
|
||||
|
||||
emptyMoreMenu() {
|
||||
// Move all children back into main
|
||||
this.moreLi.before(...this.moreMenu.children);
|
||||
// Then hide the More menu
|
||||
this.moreLi.hidden = true;
|
||||
}
|
||||
|
||||
fillMoreMenu(clientWidth){
|
||||
|
||||
let scrollWidth = this.menu.scrollWidth;
|
||||
|
||||
// If there's no overflow, return early
|
||||
if(scrollWidth <= clientWidth) return;
|
||||
// Show More menu
|
||||
this.moreLi.hidden = false;
|
||||
// While the navigation list overflows, move items into the More menu
|
||||
while(scrollWidth > clientWidth){
|
||||
// If the More menu is the first element, end the while loop
|
||||
if(!this.moreLi.previousElementSibling){ break; }
|
||||
// Move last link into More menu
|
||||
this.moreMenu.prepend(this.moreLi.previousElementSibling);
|
||||
|
||||
scrollWidth = this.menu.scrollWidth;
|
||||
}
|
||||
}
|
||||
|
||||
updateAttributes(){
|
||||
|
||||
// Reapply the light-dismiss functionality to items which have been moved from the More menu back to the main menu
|
||||
this.menu.querySelectorAll('[data-ips-hidden-light-dismiss-disabled]').forEach(el => {
|
||||
el.removeAttribute('data-ips-hidden-light-dismiss-disabled');
|
||||
el.setAttribute('data-ips-hidden-light-dismiss', '');
|
||||
});
|
||||
|
||||
// Then loop through menus inside More menu and remove their light-dismiss feature, and add a -disabled variant so we can reapply the correct attribute later
|
||||
this.moreMenu.querySelectorAll('[data-ips-hidden-light-dismiss]').forEach(el => {
|
||||
el.removeAttribute('data-ips-hidden-light-dismiss');
|
||||
el.setAttribute('data-ips-hidden-light-dismiss-disabled', '');
|
||||
});
|
||||
|
||||
// If the active link is inside the More menu...
|
||||
if(this.moreMenu.querySelector("[aria-current]")){
|
||||
// ..add [data-active] to "More"
|
||||
this.moreLi.setAttribute("data-active", "");
|
||||
// ..and expand the active dropdown
|
||||
this.moreMenu.querySelectorAll(':scope > [data-active]').forEach(el => {
|
||||
const button = el.querySelector(":scope > [aria-expanded]");
|
||||
if(button){
|
||||
button.setAttribute("aria-expanded", "true");
|
||||
}
|
||||
const menu = el.querySelector(":scope > .ipsNav__dropdown");
|
||||
if(menu){
|
||||
menu.hidden = false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Otherwise remove [data-active] from the More menu
|
||||
this.moreLi.removeAttribute("data-active");
|
||||
}
|
||||
}
|
||||
|
||||
connectedCallback(){
|
||||
|
||||
// Empty More menu and refill it on resize
|
||||
this.ro = new ResizeObserver(entries => {
|
||||
for (let entry of entries) {
|
||||
|
||||
let entryWidth = Math.ceil(entry.contentRect.width);
|
||||
|
||||
if(this.lastWidth && entryWidth > this.lastWidth){
|
||||
this.emptyMoreMenu();
|
||||
}
|
||||
|
||||
this.fillMoreMenu(entryWidth);
|
||||
this.updateAttributes();
|
||||
|
||||
this.lastWidth = entryWidth;
|
||||
}
|
||||
});
|
||||
|
||||
this.ro.observe(this.menu);
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user