Skip to content
This repository has been archived by the owner on Dec 2, 2020. It is now read-only.

Commit

Permalink
Merge pull request #263 from WordPress/primary-nav
Browse files Browse the repository at this point in the history
Update primary navigation
  • Loading branch information
aristath committed Oct 5, 2020
2 parents d5c1168 + 534d05e commit 2a420e0
Show file tree
Hide file tree
Showing 10 changed files with 310 additions and 153 deletions.
63 changes: 43 additions & 20 deletions assets/css/ie.css
Original file line number Diff line number Diff line change
Expand Up @@ -5078,7 +5078,7 @@ h1.page-title {
.primary-navigation #toggle-menu {
display: none;
}
.primary-navigation > .primary-menu-container > ul > li > ul {
.primary-navigation > .primary-menu-container ul > li:not(.hover) .sub-menu-toggle[aria-expanded="false"] ~ ul {
display: none;
}
.admin-bar .primary-navigation {
Expand Down Expand Up @@ -5114,34 +5114,58 @@ h1.page-title {
margin: 13px 0;
position: relative;
width: 100%;
z-index: 1;
}

.primary-navigation > div > .menu-wrapper li:hover, .primary-navigation > div > .menu-wrapper li:focus-within {
cursor: pointer;
z-index: 99999;
}

@media only screen and (min-width: 482px) {
.primary-navigation > div > .menu-wrapper li {
display: inherit;
margin: 0;
width: inherit;
/* Submenu display in the responsive menu */
}
.primary-navigation > div > .menu-wrapper li:hover > ul,
.primary-navigation > div > .menu-wrapper li:focus-within > ul,
.primary-navigation > div > .menu-wrapper li ul:hover,
.primary-navigation > div > .menu-wrapper li ul:focus {
visibility: visible;
opacity: 1;
display: block;
}
.primary-navigation > div > .menu-wrapper li:last-child {
margin-right: 0;
}
}

.primary-navigation > div > .menu-wrapper .sub-menu-toggle {
display: flex;
height: 44px;
width: 44px;
padding: 0;
justify-content: center;
align-items: center;
background: transparent;
color: currentColor;
border: none;
}

.primary-navigation > div > .menu-wrapper .sub-menu-toggle:focus {
outline: 2px solid #28303d;
}

@media only screen and (max-width: 481px) {
.primary-navigation > div > .menu-wrapper .sub-menu-toggle {
display: none;
}
}

.primary-navigation > div > .menu-wrapper .sub-menu-toggle[aria-expanded="false"] {
/* stylelint-disable */
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='18' height='18'><path d='M18 11.2h-5.2V6h-1.6v5.2H6v1.6h5.2V18h1.6v-5.2H18z' fill='%2328303d'/></svg>") no-repeat center center;
/* stylelint-enable */
}

.primary-navigation > div > .menu-wrapper .sub-menu-toggle[aria-expanded="true"] {
/* stylelint-disable */
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='18' height='18'><path d='M4 9h12v2H4V9z' fill='%2328303d'/></svg>") no-repeat center center;
/* stylelint-enable */
}

.primary-navigation > div > .menu-wrapper .hover .sub-menu-toggle {
/* stylelint-disable */
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='18' height='18'><path d='M4 9h12v2H4V9z' fill='%2328303d'/></svg>") no-repeat center center;
/* stylelint-enable */
}

.primary-navigation > div > .menu-wrapper > li > .sub-menu {
position: relative;
}
Expand All @@ -5152,11 +5176,10 @@ h1.page-title {
left: 0;
margin: 0;
min-width: max-content;
opacity: 0;
position: absolute;
top: calc(100% - 13px);
top: 100%;
transition: all 0.5s ease;
visibility: hidden;
z-index: 99999;
}
}

Expand Down
41 changes: 41 additions & 0 deletions assets/js/polyfills.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* File primary-navigation.js.
*
* Required to open and close the mobile navigation.
*/

/**
* Polyfill for Element.closest() because we need to support IE11.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
*/
if ( ! Element.prototype.matches ) {
Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
}

if ( ! Element.prototype.closest ) {
Element.prototype.closest = function( s ) {
var el = this;
do {
if ( Element.prototype.matches.call( el, s ) ) {
return el;
}
el = el.parentElement || el.parentNode;
} while ( el !== null && el.nodeType === 1 );
return null;
};
}

/**
* Polyfill for NodeList.foreach() because we need to support IE11.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach
*/
if ( window.NodeList && ! NodeList.prototype.forEach ) {
NodeList.prototype.forEach = function( callback, thisArg ) {
thisArg = thisArg || window;
for ( var i = 0; i < this.length; i++ ) {
callback.call( thisArg, this[i], i, this );
}
};
}
99 changes: 70 additions & 29 deletions assets/js/primary-navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,58 +3,90 @@
*
* Required to open and close the mobile navigation.
*/
( function() {

/**
* Toggle an attribute's value
*
* @param {Element} element
* @param {Attribute} attribute
* @param {String} trueVal
* @param {String} falseVal
* @since 1.0.0
*/
var toggleAttribute = function ( element, attribute, trueVal, falseVal ) {
if ( undefined === trueVal ) {
trueVal = true;
}
if ( undefined === falseVal ) {
falseVal = false;
/**
* Toggle an attribute's value
*
* @param {Element} el - The element.
* @since 1.0.0
*/
function twentytwentyoneToggleAriaExpanded( el, withListeners ) {
if ( 'true' !== el.getAttribute( 'aria-expanded' ) ) {
el.setAttribute( 'aria-expanded', 'true' );
if ( withListeners ) {
document.addEventListener( 'click', twentytwentyoneCollapseMenuOnClickOutside );
}
if ( trueVal !== element.getAttribute( attribute ) ) {
element.setAttribute( attribute, trueVal );
} else {
element.setAttribute( attribute, falseVal );
} else {
el.setAttribute( 'aria-expanded', 'false' );
if ( withListeners ) {
document.removeEventListener( 'click', twentytwentyoneCollapseMenuOnClickOutside );
}
}
}

function twentytwentyoneCollapseMenuOnClickOutside( event ) {
if ( ! document.getElementById( 'site-navigation' ).contains( event.target ) ) {
document.getElementById( 'site-navigation' ).querySelectorAll( '.sub-menu-toggle' ).forEach( function( button ) {
button.setAttribute( 'aria-expanded', 'false' );
} );
}
}

/**
* Handle clicks on submenu toggles.
*
* @param {Element} el - The element.
*/
function twentytwentyoneExpandSubMenu( el ) {

// Close other expanded items.
el.closest( 'nav' ).querySelectorAll( '.sub-menu-toggle' ).forEach( function( button ) {
if ( button !== el ) {
button.setAttribute( 'aria-expanded', 'false' );
}
} );

// Toggle aria-expanded on the button.
twentytwentyoneToggleAriaExpanded( el, true );

// On tab-away collapse the menu.
el.parentNode.querySelectorAll( 'ul > li:last-child > a' ).forEach( function( linkEl ) {
linkEl.addEventListener( 'blur', function( event ) {
if ( ! el.parentNode.contains( event.relatedTarget ) ) {
el.setAttribute( 'aria-expanded', 'false' );
}
} );
} );
}

( function() {

/**
* Menu Toggle Behaviors
*
* @param {Element} element
*/
var navMenu = function ( id ){
var wrapper = document.body; // this is the element to which a CSS class is added when a mobile nav menu is open
var mobileButton = document.getElementById( `${ id }-mobile-menu` );
var wrapper = document.body, // this is the element to which a CSS class is added when a mobile nav menu is open
mobileButton = document.getElementById( `${ id }-mobile-menu` );

if ( mobileButton ){
mobileButton.onclick = function() {
wrapper.classList.toggle( `${ id }-navigation-open` );
wrapper.classList.toggle( 'lock-scrolling' );
toggleAttribute( mobileButton, 'aria-expanded', 'true', 'false' );
twentytwentyoneToggleAriaExpanded( mobileButton );
mobileButton.focus();
}
}

/**
* Trap keyboard navigation in the menu modal.
* Adapted from TwentyTwenty
*/
document.addEventListener( 'keydown', function( event ) {
var modal, elements, selectors, lastEl, firstEl, activeEl, tabKey, shiftKey, escKey;
if ( ! wrapper.classList.contains( `${ id }-navigation-open` ) ){
return;
}
var modal, elements, selectors, lastEl, firstEl, activeEl, tabKey, shiftKey, escKey;
}

modal = document.querySelector( `.${ id }-navigation` );
selectors = "input, a, button";
Expand All @@ -70,7 +102,7 @@
if ( escKey ) {
event.preventDefault();
wrapper.classList.remove( `${ id }-navigation-open`, 'lock-scrolling' );
toggleAttribute( mobileButton, 'aria-expanded', 'true', 'false' );
twentytwentyoneToggleAriaExpanded( mobileButton );
mobileButton.focus();
}

Expand All @@ -88,10 +120,19 @@
if ( tabKey && firstEl === lastEl ) {
event.preventDefault();
}
});
} );

document.getElementById( 'site-navigation' ).querySelectorAll( '.menu-wrapper > .menu-item-has-children' ).forEach( function( li ) {
li.addEventListener( 'mouseenter', function() {
this.classList.add( 'hover' );
} );
li.addEventListener( 'mouseleave', function() {
this.classList.remove( 'hover' );
} );
} );
}

window.addEventListener( 'load', function() {
new navMenu( 'primary' );
});
} )();
} )();
69 changes: 46 additions & 23 deletions assets/sass/06-components/navigation.scss
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@
}

// Hide sub-sub-menus
> .primary-menu-container > ul > li > ul {
> .primary-menu-container ul > li:not(.hover) .sub-menu-toggle[aria-expanded="false"] ~ ul {
display: none;
}

Expand Down Expand Up @@ -200,35 +200,59 @@
margin: var(--primary-nav--padding) 0;
position: relative;
width: 100%;
z-index: 1;

&:hover,
&:focus-within {
cursor: pointer;
z-index: 99999;
}

@include media(mobile) {
display: inherit;
margin: 0;
width: inherit;

/* Submenu display in the responsive menu */
&:hover > ul,
&:focus-within > ul,
ul:hover,
ul:focus {
visibility: visible;
opacity: 1;
display: block;
}

&:last-child() {
margin-right: 0;
}
}
}

// Sub-menu buttons
.sub-menu-toggle {
display: flex;
height: 44px;
width: 44px;
padding: 0;
justify-content: center;
align-items: center;
background: transparent;
color: currentColor;
border: none;

&:focus {
outline: 2px solid var(--wp--style--color--link, var(--global--color-primary));
}

@include media(mobile-only) {
display: none;
}

// When the sub-menu is closed, display the plus icon
&[aria-expanded="false"] {
/* stylelint-disable */
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='18' height='18'><path d='M18 11.2h-5.2V6h-1.6v5.2H6v1.6h5.2V18h1.6v-5.2H18z' fill='%2328303d'/></svg>") no-repeat center center;
/* stylelint-enable */
}

// When the sub-menu is open, display the minus icon
&[aria-expanded="true"] {
/* stylelint-disable */
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='18' height='18'><path d='M4 9h12v2H4V9z' fill='%2328303d'/></svg>") no-repeat center center;
/* stylelint-enable */
}

}

.hover .sub-menu-toggle {
/* stylelint-disable */
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='18' height='18'><path d='M4 9h12v2H4V9z' fill='%2328303d'/></svg>") no-repeat center center;
/* stylelint-enable */
}

// Sub-menus Flyout
> li > .sub-menu {

Expand All @@ -239,11 +263,10 @@
left: 0;
margin: 0;
min-width: max-content;
opacity: 0;
position: absolute;
top: calc(100% - var(--primary-nav--padding));
top: 100%;
transition: all 0.5s ease;
visibility: hidden;
z-index: 99999;
}

.sub-menu {
Expand Down Expand Up @@ -315,7 +338,7 @@
list-style: none;
margin-left: var(--primary-nav--padding);

// Sub menu items om wide screens.
// Sub-menu items om wide screens.
@include media(mobile) {
padding: 0 var(--primary-nav--padding);

Expand Down
Loading

0 comments on commit 2a420e0

Please sign in to comment.