From 227bb8f10061d376301649dd3b7ddc3af9a7a0b7 Mon Sep 17 00:00:00 2001 From: Bartek Szopka Date: Wed, 26 Feb 2020 11:46:25 +0100 Subject: [PATCH 1/8] Move some of navigation styles to placeholders --- scss/_patterns_navigation.scss | 186 ++++++++++++++++++--------------- 1 file changed, 102 insertions(+), 84 deletions(-) diff --git a/scss/_patterns_navigation.scss b/scss/_patterns_navigation.scss index f336b2d0a4..2fa7ca6b6e 100644 --- a/scss/_patterns_navigation.scss +++ b/scss/_patterns_navigation.scss @@ -3,86 +3,109 @@ $navigation-hover-opacity: 0.58; @mixin vf-p-navigation { - // no colours - .p-navigation { + // placeholders + %navigation-row { display: flex; flex-direction: column; - flex-shrink: 0; - position: relative; - z-index: 10; @media (min-width: $breakpoint-navigation-threshold) { flex-direction: row; } + } - &__banner { - display: flex; - flex: 0 0 auto; - justify-content: space-between; - } + %navigation-link { + $properties: #{background-color, color, opacity}; + @include vf-animation($properties); + display: block; + line-height: map-get($line-heights, default-text); + margin-bottom: 0; + overflow: hidden; + padding: $spv-inner--medium 0; + position: relative; + text-overflow: ellipsis; + white-space: nowrap; - &__image { - align-self: center; - max-height: 2rem; - min-height: 1.5rem; + @media (min-width: $breakpoint-navigation-threshold) { + padding: $spv-inner--medium $sph-inner; } - &__link { + &::before { + content: ''; + height: 1px; + left: 0; + position: absolute; + right: 0; + top: 0; + @media (min-width: $breakpoint-navigation-threshold) { - $nav-link-max-width: 20em !default; - max-width: $nav-link-max-width; + content: none; } + } - & > a { - $properties: #{background-color, color, opacity}; - @include vf-animation($properties); - display: block; - line-height: map-get($line-heights, default-text); - margin-bottom: 0; - overflow: hidden; - padding: $spv-inner--medium 0; - position: relative; - text-overflow: ellipsis; - white-space: nowrap; + &, + &:visited, + &:focus, + &:hover { + text-decoration: none; + } + } - @media (min-width: $breakpoint-navigation-threshold) { - padding: $spv-inner--medium $sph-inner; - } + %navigation-items { + list-style: none; + margin: -1px 0 0 0; + padding: 0; - &::before { - content: ''; - height: 1px; - left: 0; - position: absolute; - right: 0; - top: 0; - - @media (min-width: $breakpoint-navigation-threshold) { - content: none; - } - } + @media (min-width: $breakpoint-navigation-threshold) { + display: flex; + flex-wrap: wrap; + margin-top: 0; // prevents bottom border of nav from moving 1px + } + } - &, - &:visited, - &:focus, - &:hover { - text-decoration: none; - } - } + %navigation-item { + @media (min-width: $breakpoint-navigation-threshold) { + $nav-link-max-width: 20em !default; + max-width: $nav-link-max-width; } + } - &__links { - list-style: none; - margin: -1px 0 0 0; - padding: 0; + // no colours + .p-navigation { + display: flex; + flex-direction: column; + flex-shrink: 0; + position: relative; + z-index: 10; - @media (min-width: $breakpoint-navigation-threshold) { - display: flex; - flex-wrap: wrap; - margin-top: 0; // prevents bottom border of nav from moving 1px + @media (min-width: $breakpoint-navigation-threshold) { + flex-direction: row; + } + + // navigation row + &__row { + @extend %fixed-width-container; + @extend %navigation-row; + + &--full-width { + @extend %vf-grid-container-padding; + @extend %navigation-row; + width: 100%; } } + @include deprecate('3.0.0', 'Use .p-navigation__row / .p-navigation__row--full-width instead') { + &.row { + @extend %navigation-row; + } + } + + // navigation logo + &__banner { + display: flex; + flex: 0 0 auto; + justify-content: space-between; + } + &__logo { display: flex; flex: 0 0 auto; @@ -94,6 +117,13 @@ $navigation-hover-opacity: 0.58; } } + &__image { + align-self: center; + max-height: 2rem; + min-height: 1.5rem; + } + + // navigation items &__nav { display: none; flex-direction: column; @@ -106,6 +136,19 @@ $navigation-hover-opacity: 0.58; } } + &__link { + @extend %navigation-item; + + & > a { + @extend %navigation-link; + } + } + + &__links { + @extend %navigation-items; + } + + // p-search-box overrides .p-search-box { flex: 1 0 auto; margin: -1px 0 $spv-inner--small 0; @@ -124,32 +167,7 @@ $navigation-hover-opacity: 0.58; } } - %navigation-row { - display: flex; - flex-direction: column; - - @media (min-width: $breakpoint-navigation-threshold) { - flex-direction: row; - } - } - - &__row { - @extend %fixed-width-container; - @extend %navigation-row; - - &--full-width { - @extend %vf-grid-container-padding; - @extend %navigation-row; - width: 100%; - } - } - - @include deprecate('3.0.0', 'Use .p-navigation__row / .p-navigation__row--full-width instead') { - &.row { - @extend %navigation-row; - } - } - + // small screen navigation toggles &:target { &::after { display: none; From 5c79872e888c6f776a2ac163c0830727f81406b8 Mon Sep 17 00:00:00 2001 From: Bartek Szopka Date: Wed, 26 Feb 2020 14:46:46 +0100 Subject: [PATCH 2/8] Move subnav script to separate file --- docs/examples/patterns/navigation/_script.js | 81 ++++++++++++++++++ .../patterns/navigation/subnav-dark.html | 85 +------------------ docs/examples/patterns/navigation/subnav.html | 85 +------------------ 3 files changed, 83 insertions(+), 168 deletions(-) create mode 100644 docs/examples/patterns/navigation/_script.js diff --git a/docs/examples/patterns/navigation/_script.js b/docs/examples/patterns/navigation/_script.js new file mode 100644 index 0000000000..9f96d9ba02 --- /dev/null +++ b/docs/examples/patterns/navigation/_script.js @@ -0,0 +1,81 @@ +/** + Opens a given subnav by applying is-active class to it + and setting aria-hidden attribute on dropdown contents. + @param {HTMLElement} subnav Root element of subnavigation to open. +*/ +function openSubnav(subnav) { + subnav.classList.add('is-active'); + var toggle = subnav.querySelector('.p-subnav__toggle'); + var dropdown = document.getElementById(toggle.getAttribute('aria-controls')); + dropdown.setAttribute('aria-hidden', 'true'); +} + +/** + Closes a given subnav by removing is-active class to it + and setting aria-hidden attribute on dropdown contents. + @param {HTMLElement} subnav Root element of subnavigation to open. +*/ +function closeSubnav(subnav) { + subnav.classList.remove('is-active'); + var toggle = subnav.querySelector('.p-subnav__toggle'); + var dropdown = document.getElementById(toggle.getAttribute('aria-controls')); + dropdown.setAttribute('aria-hidden', 'false'); +} + +/** + Closes all subnavs on the page. +*/ +function closeAllSubnavs() { + var subnavs = document.querySelectorAll('.p-subnav'); + for (var i = 0, l = subnavs.length; i < l; i++) { + closeSubnav(subnavs[i]); + } +} + +/** + Attaches click event listener to subnav toggle. + @param {HTMLElement} subnavToggle Toggle element of subnavigation. +*/ +function setupSubnavToggle(subnavToggle) { + subnavToggle.addEventListener('click', function(event) { + event.preventDefault(); + event.stopPropagation(); + + var subnav = subnavToggle.parentElement; + var isActive = subnav.classList.contains('is-active'); + + closeAllSubnavs(); + if (!isActive) { + openSubnav(subnav); + } + }); +} + +// Setup all subnav toggles on the page +var subnavToggles = document.querySelectorAll('.p-subnav__toggle'); + +for (var i = 0, l = subnavToggles.length; i < l; i++) { + setupSubnavToggle(subnavToggles[i]); +} + +// Close all menus if anything else on the page is clicked +document.addEventListener('click', function(event) { + var target = event.target; + + if (target.closest) { + if (!target.closest('.p-subnav__toggle') && !target.closest('.p-subnav__item')) { + closeAllSubnavs(); + } + } else if (target.msMatchesSelector) { + // IE friendly `Element.closest` equivalent + // as in https://developer.mozilla.org/en-US/docs/Web/API/Element/closest + do { + if (target.msMatchesSelector('.p-subnav__toggle') || target.msMatchesSelector('.p-subnav__item')) { + return; + } + target = target.parentElement || target.parentNode; + } while (target !== null && target.nodeType === 1); + + closeAllSubnavs(); + } +}); diff --git a/docs/examples/patterns/navigation/subnav-dark.html b/docs/examples/patterns/navigation/subnav-dark.html index 718182c315..85aec9dd39 100644 --- a/docs/examples/patterns/navigation/subnav-dark.html +++ b/docs/examples/patterns/navigation/subnav-dark.html @@ -86,89 +86,6 @@ {% endblock %} diff --git a/docs/examples/patterns/navigation/subnav.html b/docs/examples/patterns/navigation/subnav.html index e006cce7b3..ba383c02c8 100644 --- a/docs/examples/patterns/navigation/subnav.html +++ b/docs/examples/patterns/navigation/subnav.html @@ -86,89 +86,6 @@ {% endblock %} From 6808e1ce1ab06a99405dc6d5e31d60864e72cdf5 Mon Sep 17 00:00:00 2001 From: Bartek Szopka Date: Wed, 26 Feb 2020 16:27:27 +0100 Subject: [PATCH 3/8] Adds support for new p-navigation__items, __item and __link classes Deprecates p-navigation__links, p-navigation__link and > a selectors. Updates default example to use new classes, adds new deprecated example to make sure we keep support. --- .../examples/patterns/navigation/default.html | 18 +-- .../patterns/navigation/deprecated.html | 55 ++++++++ scss/_patterns_navigation.scss | 121 ++++++++++++++---- scss/_patterns_subnav.scss | 16 ++- 4 files changed, 174 insertions(+), 36 deletions(-) create mode 100644 docs/examples/patterns/navigation/deprecated.html diff --git a/docs/examples/patterns/navigation/default.html b/docs/examples/patterns/navigation/default.html index fd2829bc9d..35c191ce17 100644 --- a/docs/examples/patterns/navigation/default.html +++ b/docs/examples/patterns/navigation/default.html @@ -8,7 +8,7 @@
@@ -19,18 +19,18 @@ Jump to main content -