Issue #3186349 by mherchel, anmolgoyal74, bnjmnm, andrewmacpherson, jwitkowski79, rainbreaw, proeung, benjifisher, lauriii: Major accessibility problems with Olivero header show/hide feature
parent
c2241ab659
commit
bc8ea2e8fb
|
@ -1,3 +1,6 @@
|
||||||
|
const buttonSelector = 'button.sticky-header-toggle';
|
||||||
|
const mainMenuSelector = '#block-olivero-main-menu';
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
'@tags': ['core', 'olivero'],
|
'@tags': ['core', 'olivero'],
|
||||||
before(browser) {
|
before(browser) {
|
||||||
|
@ -18,14 +21,19 @@ module.exports = {
|
||||||
'#block-olivero-content h2',
|
'#block-olivero-content h2',
|
||||||
'Congratulations and welcome to the Drupal community!',
|
'Congratulations and welcome to the Drupal community!',
|
||||||
)
|
)
|
||||||
.assert.not.visible('button.wide-nav-expand')
|
.assert.not.visible(buttonSelector)
|
||||||
.getLocationInView('footer.site-footer', () => {
|
.getLocationInView('footer.site-footer', () => {
|
||||||
browser.assert.visible('button.wide-nav-expand');
|
browser.assert.visible(buttonSelector);
|
||||||
browser.assert.not.visible('#site-header__inner');
|
browser.assert.not.visible('#site-header__inner');
|
||||||
})
|
})
|
||||||
.assert.not.visible('#block-olivero-main-menu')
|
.assert.not.visible(mainMenuSelector)
|
||||||
.click('button.wide-nav-expand', () => {
|
.click(buttonSelector)
|
||||||
browser.assert.visible('#block-olivero-main-menu');
|
.assert.visible(mainMenuSelector)
|
||||||
});
|
.assert.attributeEquals(buttonSelector, 'aria-checked', 'true')
|
||||||
|
|
||||||
|
// Sticky header should remain open after page reload in open state.
|
||||||
|
.drupalRelativeURL('/node')
|
||||||
|
.assert.visible(mainMenuSelector)
|
||||||
|
.assert.attributeEquals(buttonSelector, 'aria-checked', 'true');
|
||||||
},
|
},
|
||||||
};
|
};
|
|
@ -0,0 +1,145 @@
|
||||||
|
/*
|
||||||
|
* DO NOT EDIT THIS FILE.
|
||||||
|
* See the following change record for more information,
|
||||||
|
* https://www.drupal.org/node/3084859
|
||||||
|
* @preserve
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Sticky Header Toggle Button.
|
||||||
|
*
|
||||||
|
* This button shows on the left hand side of the header (in LTR layouts), and
|
||||||
|
* toggles fixing the header to the top of the viewport.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.sticky-header-toggle {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 75rem) {
|
||||||
|
|
||||||
|
.sticky-header-toggle {
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 5.625rem;
|
||||||
|
height: 6.75rem;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
border: 0;
|
||||||
|
outline: 0;
|
||||||
|
background-color: #2494db
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticky-header-toggle:focus {
|
||||||
|
cursor: pointer;
|
||||||
|
pointer-events: auto;
|
||||||
|
opacity: 1;
|
||||||
|
outline: solid 2px #fff;
|
||||||
|
outline-offset: -4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 75rem) {
|
||||||
|
|
||||||
|
body:not(.is-always-mobile-nav) .js-fixed .sticky-header-toggle {
|
||||||
|
visibility: visible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 75rem) {
|
||||||
|
|
||||||
|
body.is-always-mobile-nav .sticky-header-toggle {
|
||||||
|
visibility: hidden
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticky-header-toggle__icon {
|
||||||
|
position: relative;
|
||||||
|
width: 2.25rem;
|
||||||
|
height: 1.3125rem;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
pointer-events: none;
|
||||||
|
transform-style: preserve-3d
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticky-header-toggle__icon > span {
|
||||||
|
display: block;
|
||||||
|
height: 0;
|
||||||
|
/* Intentionally not using CSS logical properties. */
|
||||||
|
border-top: solid 3px #fff
|
||||||
|
}
|
||||||
|
|
||||||
|
[dir="ltr"] .sticky-header-toggle__icon > span:nth-child(1) {
|
||||||
|
left: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
[dir="rtl"] .sticky-header-toggle__icon > span:nth-child(1) {
|
||||||
|
right: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticky-header-toggle__icon > span:nth-child(1) {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 0;
|
||||||
|
transition: transform 0.2s;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
[dir="ltr"] .sticky-header-toggle__icon > span:nth-child(2) {
|
||||||
|
left: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
[dir="rtl"] .sticky-header-toggle__icon > span:nth-child(2) {
|
||||||
|
right: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticky-header-toggle__icon > span:nth-child(2) {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.5625rem;
|
||||||
|
width: 100%;
|
||||||
|
height: 0;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
[dir="ltr"] .sticky-header-toggle__icon > span:nth-child(3) {
|
||||||
|
left: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
[dir="rtl"] .sticky-header-toggle__icon > span:nth-child(3) {
|
||||||
|
right: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticky-header-toggle__icon > span:nth-child(3) {
|
||||||
|
position: absolute;
|
||||||
|
top: auto;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 0;
|
||||||
|
transition: transform 0.2s;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.js-fixed .sticky-header-toggle {
|
||||||
|
cursor: pointer;
|
||||||
|
pointer-events: auto;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
[aria-checked="true"] .sticky-header-toggle__icon > span:nth-child(1) {
|
||||||
|
top: 0.5625rem;
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
[aria-checked="true"] .sticky-header-toggle__icon > span:nth-child(2) {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[aria-checked="true"] .sticky-header-toggle__icon > span:nth-child(3) {
|
||||||
|
top: 0.5625rem;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Sticky Header Toggle Button.
|
||||||
|
*
|
||||||
|
* This button shows on the left hand side of the header (in LTR layouts), and
|
||||||
|
* toggles fixing the header to the top of the viewport.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@import "../base/variables.pcss.css";
|
||||||
|
|
||||||
|
.sticky-header-toggle {
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
@media (--nav) {
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: var(--content-left);
|
||||||
|
height: var(--sp6);
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
border: 0;
|
||||||
|
outline: 0;
|
||||||
|
background-color: var(--color--blue-50);
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
cursor: pointer;
|
||||||
|
pointer-events: auto;
|
||||||
|
opacity: 1;
|
||||||
|
outline: solid 2px var(--color--white);
|
||||||
|
outline-offset: -4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body:not(.is-always-mobile-nav) .js-fixed .sticky-header-toggle {
|
||||||
|
@media (--nav) {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body.is-always-mobile-nav .sticky-header-toggle {
|
||||||
|
@media (--nav) {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticky-header-toggle__icon {
|
||||||
|
position: relative;
|
||||||
|
width: var(--sp2);
|
||||||
|
height: 21px;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
pointer-events: none;
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
|
||||||
|
& > span {
|
||||||
|
display: block;
|
||||||
|
height: 0;
|
||||||
|
/* Intentionally not using CSS logical properties. */
|
||||||
|
border-top: solid 3px var(--color--white);
|
||||||
|
|
||||||
|
&:nth-child(1) {
|
||||||
|
position: absolute;
|
||||||
|
inset-block-start: 0;
|
||||||
|
inset-inline-start: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 0;
|
||||||
|
transition: transform 0.2s;
|
||||||
|
background-color: var(--color--white);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(2) {
|
||||||
|
position: absolute;
|
||||||
|
inset-block-start: 9px;
|
||||||
|
inset-inline-start: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 0;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
background-color: var(--color--white);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(3) {
|
||||||
|
position: absolute;
|
||||||
|
inset-block: auto 0;
|
||||||
|
inset-inline-start: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 0;
|
||||||
|
transition: transform 0.2s;
|
||||||
|
background-color: var(--color--white);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.js-fixed .sticky-header-toggle {
|
||||||
|
cursor: pointer;
|
||||||
|
pointer-events: auto;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
[aria-checked="true"] .sticky-header-toggle__icon {
|
||||||
|
& > span:nth-child(1) {
|
||||||
|
inset-block-start: 9px;
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
& > span:nth-child(2) {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > span:nth-child(3) {
|
||||||
|
inset-block-start: 9px;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
}
|
|
@ -81,20 +81,20 @@
|
||||||
@media (min-width: 75rem) {
|
@media (min-width: 75rem) {
|
||||||
|
|
||||||
html.js body:not(.is-always-mobile-nav) .site-header__inner {
|
html.js body:not(.is-always-mobile-nav) .site-header__inner {
|
||||||
transition: opacity 0.3s, transform 0.3s
|
transition: opacity 0.3s, transform 0.3s, box-shadow 0.3s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 75rem) {
|
@media (min-width: 75rem) {
|
||||||
|
|
||||||
.site-header__fixable.js-fixed .site-header__inner {
|
.site-header__fixable.is-expanded .site-header__inner {
|
||||||
box-shadow: -36px 1px 36px rgba(0, 0, 0, 0.08) /* LTR */
|
box-shadow: -36px 1px 36px rgba(0, 0, 0, 0.08) /* LTR */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 75rem) {
|
@media (min-width: 75rem) {
|
||||||
|
|
||||||
[dir="rtl"] .site-header__fixable.js-fixed .site-header__inner {
|
[dir="rtl"] .site-header__fixable.is-expanded .site-header__inner {
|
||||||
box-shadow: 36px 1px 36px rgba(0, 0, 0, 0.08)
|
box-shadow: 36px 1px 36px rgba(0, 0, 0, 0.08)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,17 +73,17 @@
|
||||||
*/
|
*/
|
||||||
html.js body:not(.is-always-mobile-nav) .site-header__inner {
|
html.js body:not(.is-always-mobile-nav) .site-header__inner {
|
||||||
@media (--nav) {
|
@media (--nav) {
|
||||||
transition: opacity 0.3s, transform 0.3s;
|
transition: opacity 0.3s, transform 0.3s, box-shadow 0.3s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-header__fixable.js-fixed .site-header__inner {
|
.site-header__fixable.is-expanded .site-header__inner {
|
||||||
@media (--nav) {
|
@media (--nav) {
|
||||||
box-shadow: -36px 1px 36px rgba(0, 0, 0, 0.08); /* LTR */
|
box-shadow: -36px 1px 36px rgba(0, 0, 0, 0.08); /* LTR */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[dir="rtl"] .site-header__fixable.js-fixed .site-header__inner {
|
[dir="rtl"] .site-header__fixable.is-expanded .site-header__inner {
|
||||||
@media (--nav) {
|
@media (--nav) {
|
||||||
box-shadow: 36px 1px 36px rgba(0, 0, 0, 0.08);
|
box-shadow: 36px 1px 36px rgba(0, 0, 0, 0.08);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,26 +16,75 @@
|
||||||
|
|
||||||
Drupal.olivero.isDesktopNav = isDesktopNav;
|
Drupal.olivero.isDesktopNav = isDesktopNav;
|
||||||
|
|
||||||
const wideNavButton = document.querySelector('.wide-nav-expand');
|
const stickyHeaderToggleButton = document.querySelector(
|
||||||
|
'.sticky-header-toggle',
|
||||||
|
);
|
||||||
const siteHeaderFixable = document.querySelector('.site-header__fixable');
|
const siteHeaderFixable = document.querySelector('.site-header__fixable');
|
||||||
|
|
||||||
function wideNavIsOpen() {
|
function stickyHeaderIsEnabled() {
|
||||||
return wideNavButton.getAttribute('aria-expanded') === 'true';
|
return stickyHeaderToggleButton.getAttribute('aria-checked') === 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
function showWideNav() {
|
/**
|
||||||
|
* Save the current sticky header expanded state to localStorage, and set
|
||||||
|
* it to expire after two weeks.
|
||||||
|
*
|
||||||
|
* @param {boolean} expandedState - Current state of the sticky header button.
|
||||||
|
*/
|
||||||
|
function setStickyHeaderStorage(expandedState) {
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
const item = {
|
||||||
|
value: expandedState,
|
||||||
|
expiry: now.getTime() + 20160000, // 2 weeks from now.
|
||||||
|
};
|
||||||
|
localStorage.setItem(
|
||||||
|
'Drupal.olivero.stickyHeaderState',
|
||||||
|
JSON.stringify(item),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle the state of the sticky header between always pinned and
|
||||||
|
* only pinned when scrolled to the top of the viewport.
|
||||||
|
*
|
||||||
|
* @param {boolean} pinnedState - State to change the sticky header to.
|
||||||
|
*/
|
||||||
|
function toggleStickyHeaderState(pinnedState) {
|
||||||
if (isDesktopNav()) {
|
if (isDesktopNav()) {
|
||||||
wideNavButton.setAttribute('aria-expanded', 'true');
|
if (pinnedState === true) {
|
||||||
siteHeaderFixable.classList.add('is-expanded');
|
siteHeaderFixable.classList.add('is-expanded');
|
||||||
|
} else {
|
||||||
|
siteHeaderFixable.classList.remove('is-expanded');
|
||||||
|
}
|
||||||
|
|
||||||
|
stickyHeaderToggleButton.setAttribute('aria-checked', pinnedState);
|
||||||
|
setStickyHeaderStorage(pinnedState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resets the wide nav button to be closed (its default state).
|
/**
|
||||||
function hideWideNav() {
|
* Return the sticky header's stored state from localStorage.
|
||||||
if (isDesktopNav()) {
|
*
|
||||||
wideNavButton.setAttribute('aria-expanded', 'false');
|
* @return {boolean} Stored state of the sticky header.
|
||||||
siteHeaderFixable.classList.remove('is-expanded');
|
*/
|
||||||
|
function getStickyHeaderStorage() {
|
||||||
|
const stickyHeaderState = localStorage.getItem(
|
||||||
|
'Drupal.olivero.stickyHeaderState',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!stickyHeaderState) return null;
|
||||||
|
|
||||||
|
const item = JSON.parse(stickyHeaderState);
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
// Compare the expiry time of the item with the current time.
|
||||||
|
if (now.getTime() > item.expiry) {
|
||||||
|
// If the item is expired, delete the item from storage and return null.
|
||||||
|
localStorage.removeItem('Drupal.olivero.stickyHeaderState');
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
return item.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only enable scroll effects if the browser supports Intersection Observer.
|
// Only enable scroll effects if the browser supports Intersection Observer.
|
||||||
|
@ -93,38 +142,27 @@
|
||||||
observer.observe(primaryNav);
|
observer.observe(primaryNav);
|
||||||
}
|
}
|
||||||
|
|
||||||
wideNavButton.addEventListener('click', () => {
|
stickyHeaderToggleButton.addEventListener('click', () => {
|
||||||
if (!wideNavIsOpen()) {
|
toggleStickyHeaderState(!stickyHeaderIsEnabled());
|
||||||
showWideNav();
|
|
||||||
} else {
|
|
||||||
hideWideNav();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
siteHeaderFixable
|
// If header is pinned open and a header element gains focus, scroll to the
|
||||||
.querySelector('.site-header__inner')
|
// top of the page to ensure that the header elements can be seen.
|
||||||
.addEventListener('focusin', showWideNav);
|
document
|
||||||
|
.querySelector('#site-header__inner')
|
||||||
// If skip link is clicked, ensure that the wide navigation closes so the header will not be covered up.
|
.addEventListener('focusin', () => {
|
||||||
document.querySelector('.skip-link').addEventListener('click', hideWideNav);
|
if (isDesktopNav() && !stickyHeaderIsEnabled()) {
|
||||||
|
const header = document.querySelector('#header');
|
||||||
|
const headerNav = header.querySelector('#header-nav');
|
||||||
|
const headerMargin = header.clientHeight - headerNav.clientHeight;
|
||||||
|
if (window.scrollY > headerMargin) {
|
||||||
|
window.scrollTo(0, headerMargin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
monitorNavPosition();
|
monitorNavPosition();
|
||||||
|
setStickyHeaderStorage(getStickyHeaderStorage());
|
||||||
|
toggleStickyHeaderState(getStickyHeaderStorage());
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('keyup', (e) => {
|
|
||||||
if (e.keyCode === 27) {
|
|
||||||
// Close the search form.
|
|
||||||
if (
|
|
||||||
'toggleSearchVisibility' in Drupal.olivero &&
|
|
||||||
'searchIsVisible' in Drupal.olivero &&
|
|
||||||
Drupal.olivero.searchIsVisible()
|
|
||||||
) {
|
|
||||||
Drupal.olivero.toggleSearchVisibility(false);
|
|
||||||
}
|
|
||||||
// Close the wide nav.
|
|
||||||
else {
|
|
||||||
hideWideNav();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})(Drupal);
|
})(Drupal);
|
||||||
|
|
|
@ -14,25 +14,47 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
Drupal.olivero.isDesktopNav = isDesktopNav;
|
Drupal.olivero.isDesktopNav = isDesktopNav;
|
||||||
var wideNavButton = document.querySelector('.wide-nav-expand');
|
var stickyHeaderToggleButton = document.querySelector('.sticky-header-toggle');
|
||||||
var siteHeaderFixable = document.querySelector('.site-header__fixable');
|
var siteHeaderFixable = document.querySelector('.site-header__fixable');
|
||||||
|
|
||||||
function wideNavIsOpen() {
|
function stickyHeaderIsEnabled() {
|
||||||
return wideNavButton.getAttribute('aria-expanded') === 'true';
|
return stickyHeaderToggleButton.getAttribute('aria-checked') === 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
function showWideNav() {
|
function setStickyHeaderStorage(expandedState) {
|
||||||
|
var now = new Date();
|
||||||
|
var item = {
|
||||||
|
value: expandedState,
|
||||||
|
expiry: now.getTime() + 20160000
|
||||||
|
};
|
||||||
|
localStorage.setItem('Drupal.olivero.stickyHeaderState', JSON.stringify(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleStickyHeaderState(pinnedState) {
|
||||||
if (isDesktopNav()) {
|
if (isDesktopNav()) {
|
||||||
wideNavButton.setAttribute('aria-expanded', 'true');
|
if (pinnedState === true) {
|
||||||
siteHeaderFixable.classList.add('is-expanded');
|
siteHeaderFixable.classList.add('is-expanded');
|
||||||
|
} else {
|
||||||
|
siteHeaderFixable.classList.remove('is-expanded');
|
||||||
|
}
|
||||||
|
|
||||||
|
stickyHeaderToggleButton.setAttribute('aria-checked', pinnedState);
|
||||||
|
setStickyHeaderStorage(pinnedState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideWideNav() {
|
function getStickyHeaderStorage() {
|
||||||
if (isDesktopNav()) {
|
var stickyHeaderState = localStorage.getItem('Drupal.olivero.stickyHeaderState');
|
||||||
wideNavButton.setAttribute('aria-expanded', 'false');
|
if (!stickyHeaderState) return null;
|
||||||
siteHeaderFixable.classList.remove('is-expanded');
|
var item = JSON.parse(stickyHeaderState);
|
||||||
|
var now = new Date();
|
||||||
|
|
||||||
|
if (now.getTime() > item.expiry) {
|
||||||
|
localStorage.removeItem('Drupal.olivero.stickyHeaderState');
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return item.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('IntersectionObserver' in window && 'IntersectionObserverEntry' in window && 'intersectionRatio' in window.IntersectionObserverEntry.prototype) {
|
if ('IntersectionObserver' in window && 'IntersectionObserverEntry' in window && 'intersectionRatio' in window.IntersectionObserverEntry.prototype) {
|
||||||
|
@ -79,25 +101,22 @@
|
||||||
observer.observe(primaryNav);
|
observer.observe(primaryNav);
|
||||||
}
|
}
|
||||||
|
|
||||||
wideNavButton.addEventListener('click', function () {
|
stickyHeaderToggleButton.addEventListener('click', function () {
|
||||||
if (!wideNavIsOpen()) {
|
toggleStickyHeaderState(!stickyHeaderIsEnabled());
|
||||||
showWideNav();
|
});
|
||||||
} else {
|
document.querySelector('#site-header__inner').addEventListener('focusin', function () {
|
||||||
hideWideNav();
|
if (isDesktopNav() && !stickyHeaderIsEnabled()) {
|
||||||
|
var header = document.querySelector('#header');
|
||||||
|
var headerNav = header.querySelector('#header-nav');
|
||||||
|
var headerMargin = header.clientHeight - headerNav.clientHeight;
|
||||||
|
|
||||||
|
if (window.scrollY > headerMargin) {
|
||||||
|
window.scrollTo(0, headerMargin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
siteHeaderFixable.querySelector('.site-header__inner').addEventListener('focusin', showWideNav);
|
|
||||||
document.querySelector('.skip-link').addEventListener('click', hideWideNav);
|
|
||||||
monitorNavPosition();
|
monitorNavPosition();
|
||||||
|
setStickyHeaderStorage(getStickyHeaderStorage());
|
||||||
|
toggleStickyHeaderState(getStickyHeaderStorage());
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('keyup', function (e) {
|
|
||||||
if (e.keyCode === 27) {
|
|
||||||
if ('toggleSearchVisibility' in Drupal.olivero && 'searchIsVisible' in Drupal.olivero && Drupal.olivero.searchIsVisible()) {
|
|
||||||
Drupal.olivero.toggleSearchVisibility(false);
|
|
||||||
} else {
|
|
||||||
hideWideNav();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})(Drupal);
|
})(Drupal);
|
|
@ -36,11 +36,11 @@ global-styling:
|
||||||
css/components/header-buttons-mobile.css: {}
|
css/components/header-buttons-mobile.css: {}
|
||||||
css/components/header-navigation.css: {}
|
css/components/header-navigation.css: {}
|
||||||
css/components/header-site-branding.css: {}
|
css/components/header-site-branding.css: {}
|
||||||
|
css/components/header-sticky-toggle.css: {}
|
||||||
css/components/hero.css: {}
|
css/components/hero.css: {}
|
||||||
css/components/links.css: {}
|
css/components/links.css: {}
|
||||||
css/components/messages.css: {}
|
css/components/messages.css: {}
|
||||||
css/components/navigation/nav-button-mobile.css: {}
|
css/components/navigation/nav-button-mobile.css: {}
|
||||||
css/components/navigation/wide-nav-expand.css: {}
|
|
||||||
css/components/navigation/nav-primary-button.css: {}
|
css/components/navigation/nav-primary-button.css: {}
|
||||||
css/components/navigation/nav-primary.css: {}
|
css/components/navigation/nav-primary.css: {}
|
||||||
css/components/navigation/nav-primary-wide.css: {}
|
css/components/navigation/nav-primary-wide.css: {}
|
||||||
|
|
|
@ -52,11 +52,11 @@
|
||||||
{% if page.header or page.primary_menu or page.secondary_menu %}
|
{% if page.header or page.primary_menu or page.secondary_menu %}
|
||||||
<header id="header" class="site-header" role="banner">
|
<header id="header" class="site-header" role="banner">
|
||||||
|
|
||||||
{# Gets fixed by JS at wide widths. #}
|
{# Gets fixed by JavaScript at wide widths. #}
|
||||||
<div class="site-header__fixable fixable">
|
<div class="site-header__fixable fixable">
|
||||||
<div class="site-header__initial">
|
<div class="site-header__initial">
|
||||||
<button class="wide-nav-expand" aria-controls="site-header__inner" aria-label="{{ 'Toggle navigation'|t }}" aria-expanded="false">
|
<button class="sticky-header-toggle" role="switch" aria-controls="site-header__inner" aria-label="{{ 'Sticky header'|t }}" aria-checked="false">
|
||||||
<span class="wide-nav-expand__icon">
|
<span class="sticky-header-toggle__icon">
|
||||||
<span></span>
|
<span></span>
|
||||||
<span></span>
|
<span></span>
|
||||||
<span></span>
|
<span></span>
|
||||||
|
|
Loading…
Reference in New Issue