Issue #3246755 by mherchel, yogeshmpawar, Libbna, cindytwilliams, zenimagine: Olivero main/user account menu layout struggles with long menus
(cherry picked from commit 9fe14155e4
)
merge-requests/2316/head
parent
e057e13319
commit
b2a4aafbb6
|
@ -32,3 +32,13 @@ olivero_test.anchor_link:
|
|||
url: "internal:#footer"
|
||||
menu_name: main
|
||||
weight: 200
|
||||
olivero_test.long_item_1:
|
||||
title: Long long long long
|
||||
route_name: <front>
|
||||
menu_name: main
|
||||
weight: 200
|
||||
olivero_test.long_item_2:
|
||||
title: Long long long long
|
||||
route_name: <front>
|
||||
menu_name: main
|
||||
weight: 200
|
||||
|
|
|
@ -66,7 +66,7 @@ module.exports = {
|
|||
.waitForElementVisible(headerNavSelector)
|
||||
.assert.visible(headerNavSelector)
|
||||
.assert.not.visible(`#${linkSubMenuId}`)
|
||||
.moveToElement(`[aria-controls="${linkSubMenuId}"]`, 0, 0)
|
||||
.moveToElement(`[aria-controls="${linkSubMenuId}"]`, 1, 1)
|
||||
.assert.visible(`#${linkSubMenuId}`)
|
||||
.assert.attributeEquals(
|
||||
`[aria-controls="${linkSubMenuId}"]`,
|
||||
|
@ -74,7 +74,7 @@ module.exports = {
|
|||
'true',
|
||||
)
|
||||
.assert.not.visible(`#${buttonSubMenuId}`)
|
||||
.moveToElement(`[aria-controls="${buttonSubMenuId}"]`, 0, 0)
|
||||
.moveToElement(`[aria-controls="${buttonSubMenuId}"]`, 1, 1)
|
||||
.assert.visible(`#${buttonSubMenuId}`)
|
||||
.assert.attributeEquals(
|
||||
`[aria-controls="${buttonSubMenuId}"]`,
|
||||
|
@ -82,4 +82,17 @@ module.exports = {
|
|||
'true',
|
||||
);
|
||||
},
|
||||
'Verify desktop menu converts to mobile if it gets too long': (browser) => {
|
||||
browser
|
||||
.drupalRelativeURL('/node')
|
||||
.waitForElementVisible('body')
|
||||
.assert.not.elementPresent('body.is-always-mobile-nav')
|
||||
.resizeWindow(1320, 800)
|
||||
.execute(() => {
|
||||
// Directly modify the width of the site branding name so that it causes
|
||||
// the primary navigation to be too long, and switch into mobile mode.
|
||||
document.querySelector('.site-branding__name').style.width = '350px';
|
||||
}, [])
|
||||
.assert.elementPresent('body.is-always-mobile-nav');
|
||||
},
|
||||
};
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
* @file
|
||||
* This script watches the desktop version of the primary navigation. If it
|
||||
* wraps to two lines, it will automatically transition to a mobile navigation
|
||||
* and remember where it wrapped so it can transition back.
|
||||
*/
|
||||
((Drupal, once) => {
|
||||
/**
|
||||
* Handles the transition from mobile navigation to desktop navigation.
|
||||
*
|
||||
* @param {Element} navWrapper - The primary navigation's top-level <ul> element.
|
||||
* @param {Element} navItem - The first item within the primary navigation.
|
||||
*/
|
||||
function transitionToDesktopNavigation(navWrapper, navItem) {
|
||||
document.body.classList.remove('is-always-mobile-nav');
|
||||
|
||||
// Double check to see if the navigation is wrapping, and if so, re-enable
|
||||
// mobile navigation. This solves an edge cases where if the amount of
|
||||
// navigation items always causes the primary navigation to wrap, and the
|
||||
// page is loaded at a narrower viewport and then widened, the mobile nav
|
||||
// may not be enabled.
|
||||
if (navWrapper.clientHeight > navItem.clientHeight) {
|
||||
document.body.classList.add('is-always-mobile-nav');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback from Resize Observer. This checks if the primary navigation is
|
||||
* wrapping, and if so, transitions to the mobile navigation.
|
||||
*
|
||||
* @param {ResizeObserverEntry} entries - Object passed from ResizeObserver.
|
||||
*/
|
||||
function checkIfDesktopNavigationWraps(entries) {
|
||||
const navItem = document.querySelector('.primary-nav__menu-item');
|
||||
|
||||
if (
|
||||
Drupal.olivero.isDesktopNav() &&
|
||||
entries[0].contentRect.height > navItem.clientHeight
|
||||
) {
|
||||
const navMediaQuery = window.matchMedia(
|
||||
`(max-width: ${window.innerWidth + 5}px)`, // 5px adds a small buffer before switching back.
|
||||
);
|
||||
document.body.classList.add('is-always-mobile-nav');
|
||||
|
||||
// In the event that the viewport was resized, we remember the viewport
|
||||
// width with a one-time event listener ,so we can attempt to transition
|
||||
// from mobile navigation to desktop navigation.
|
||||
navMediaQuery.addEventListener(
|
||||
'change',
|
||||
() => {
|
||||
transitionToDesktopNavigation(entries[0].target, navItem);
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up Resize Observer to listen for changes to the size of the primary
|
||||
* navigation.
|
||||
*
|
||||
* @param {Element} primaryNav - The primary navigation's top-level <ul> element.
|
||||
*/
|
||||
function init(primaryNav) {
|
||||
if ('ResizeObserver' in window) {
|
||||
const resizeObserver = new ResizeObserver(checkIfDesktopNavigationWraps);
|
||||
resizeObserver.observe(primaryNav);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the automatic navigation transition.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attach context and settings for navigation.
|
||||
*/
|
||||
Drupal.behaviors.automaticMobileNav = {
|
||||
attach(context) {
|
||||
once(
|
||||
'olivero-automatic-mobile-nav',
|
||||
'[data-drupal-selector="primary-nav-menu--level-1"]',
|
||||
context,
|
||||
).forEach(init);
|
||||
},
|
||||
};
|
||||
})(Drupal, once);
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* DO NOT EDIT THIS FILE.
|
||||
* See the following change record for more information,
|
||||
* https://www.drupal.org/node/2815083
|
||||
* @preserve
|
||||
**/
|
||||
|
||||
(function (Drupal, once) {
|
||||
function transitionToDesktopNavigation(navWrapper, navItem) {
|
||||
document.body.classList.remove('is-always-mobile-nav');
|
||||
|
||||
if (navWrapper.clientHeight > navItem.clientHeight) {
|
||||
document.body.classList.add('is-always-mobile-nav');
|
||||
}
|
||||
}
|
||||
|
||||
function checkIfDesktopNavigationWraps(entries) {
|
||||
var navItem = document.querySelector('.primary-nav__menu-item');
|
||||
|
||||
if (Drupal.olivero.isDesktopNav() && entries[0].contentRect.height > navItem.clientHeight) {
|
||||
var navMediaQuery = window.matchMedia("(max-width: ".concat(window.innerWidth + 5, "px)"));
|
||||
document.body.classList.add('is-always-mobile-nav');
|
||||
navMediaQuery.addEventListener('change', function () {
|
||||
transitionToDesktopNavigation(entries[0].target, navItem);
|
||||
}, {
|
||||
once: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function init(primaryNav) {
|
||||
if ('ResizeObserver' in window) {
|
||||
var resizeObserver = new ResizeObserver(checkIfDesktopNavigationWraps);
|
||||
resizeObserver.observe(primaryNav);
|
||||
}
|
||||
}
|
||||
|
||||
Drupal.behaviors.automaticMobileNav = {
|
||||
attach: function attach(context) {
|
||||
once('olivero-automatic-mobile-nav', '[data-drupal-selector="primary-nav-menu--level-1"]', context).forEach(init);
|
||||
}
|
||||
};
|
||||
})(Drupal, once);
|
|
@ -220,6 +220,10 @@ navigation-primary:
|
|||
js:
|
||||
js/navigation.js: {}
|
||||
js/second-level-navigation.js: {}
|
||||
js/nav-resize.js: {}
|
||||
dependencies:
|
||||
- core/drupal
|
||||
- core/once
|
||||
|
||||
navigation-secondary:
|
||||
version: VERSION
|
||||
|
|
Loading…
Reference in New Issue