weg-shared-layout 0.0.41 → 0.0.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/weg-footer_2.cjs.entry.js +269 -17
- package/dist/cjs/weg-shared-layout.cjs.js +1 -1
- package/dist/collection/components/weg-header/weg-header.css +25 -0
- package/dist/collection/components/weg-header/weg-header.js +270 -17
- package/dist/components/weg-header.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/weg-footer_2.entry.js +269 -17
- package/dist/esm/weg-shared-layout.js +1 -1
- package/dist/types/components/weg-header/weg-header.d.ts +28 -0
- package/dist/weg-shared-layout/p-877ccc54.entry.js +1 -0
- package/dist/weg-shared-layout/weg-shared-layout.esm.js +1 -1
- package/package.json +1 -1
- package/dist/weg-shared-layout/p-3362febf.entry.js +0 -1
|
@@ -375,13 +375,19 @@ const LOGO_SRC = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA4QAAAFcCAYAAACQ
|
|
|
375
375
|
|
|
376
376
|
const sharedCss = () => `:host{--weg-breakpoint-sm:640px;--weg-breakpoint-md:960px;--weg-breakpoint-lg:1280px;--weg-breakpoint-xl:1440px}:root,:host{--weg-container-breakpoint-sm:40rem;--weg-container-breakpoint-md:48rem;--weg-container-breakpoint-lg:64rem;--weg-container-breakpoint-xl:80rem;--weg-container-breakpoint-2xl:86rem;--weg-container-max-vw:95vw;--weg-container-padding-inline:1rem}@media (width >= 48rem){:root,:host{--weg-container-padding-inline:2rem}}.container{width:100%;max-width:var(--weg-container-max-vw);margin-inline:auto;padding-inline:var(--weg-container-padding-inline)}@media (width >= 40rem){.container{max-width:min(var(--weg-container-breakpoint-sm), var(--weg-container-max-vw))}}@media (width >= 48rem){.container{max-width:min(var(--weg-container-breakpoint-md), var(--weg-container-max-vw))}}@media (width >= 64rem){.container{max-width:min(var(--weg-container-breakpoint-lg), var(--weg-container-max-vw))}}@media (width >= 80rem){.container{max-width:min(var(--weg-container-breakpoint-xl), var(--weg-container-max-vw))}}@media (width >= 86rem){.container{max-width:min(var(--weg-container-breakpoint-xl), var(--weg-container-max-vw))}}*,*::before,*::after{box-sizing:border-box}:host{display:block;--weg-font-family:ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, 'Apple Color Emoji', 'Segoe UI Emoji';--weg-color-accent:#948eeb;--weg-purple-200:#cdcff8}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0}`;
|
|
377
377
|
|
|
378
|
-
const wegHeaderCss = () => `:host{--weg-breakpoint-sm:640px;--weg-breakpoint-md:960px;--weg-breakpoint-lg:1280px;--weg-breakpoint-xl:1440px}.header{width:100%;border-bottom:2px solid var(--weg-color-accent);background:#ffffff;color:#0f172a;font-family:var(--weg-font-family)}@media (width >= 960px){.header{border-bottom-width:0.25rem}}:host{position:relative;z-index:20}.header--menu-open{position:fixed;inset:0;z-index:1000;display:flex;flex-direction:column;overflow:hidden}.header--menu-open .header-inner{flex:1 1 auto;flex-wrap:wrap;align-content:flex-start;min-height:0}.header--menu-open .main-nav-panel{display:block;flex:1 1 100%;width:100%;min-height:0;overflow-y:auto;border-top:1px solid #d8d4f7}@media (width >= 960px){.header--menu-open{position:static;inset:auto;z-index:auto;display:block;overflow:visible}.header--menu-open .header-inner{flex:unset;flex-wrap:nowrap;align-content:unset;min-height:unset}}.logo-link{display:inline-flex;align-items:center;text-decoration:none;outline:none}.logo-link:focus-visible{outline:2px solid var(--weg-color-accent);outline-offset:4px;border-radius:4px}.logo{height:2.5rem;width:auto}@media (width >= 960px){.logo{height:3rem}}@media (width >= 1280px){.logo{height:5rem}}.header-inner{display:flex;width:100%;min-width:0;align-items:center;justify-content:space-between;gap:0.75rem;padding-block:0.75rem;padding-inline:var(--weg-container-padding-inline)}@media (width >= 960px){.header-inner{flex-wrap:nowrap;gap:1.5rem;padding-block:1.25rem}}@media (width >= 1440px){.header-inner{padding-block:1.75rem}}.header-inner .logo-link{flex:1 1 auto;min-width:0;justify-content:center}@media (width >= 960px){.header-inner .logo-link{flex:0 0 auto;justify-content:flex-start}}.header-inner .logo{max-width:100%}.header-actions{display:flex;align-items:center;flex-shrink:0}@media (width >= 960px){.header-actions{display:none}}.main-nav-panel{display:none;margin-inline:-0.5rem}@media (width >= 960px){.main-nav-panel{display:flex;flex:1 1 auto;width:auto;min-width:0;justify-content:flex-end;overflow:visible;border-top:none}}.main-nav{padding:0 1rem 1.5rem}@media (width >= 960px){.main-nav{display:flex;align-items:center;justify-content:flex-end;flex-wrap:wrap;gap:1rem;padding:0}}.main-nav__list{list-style:none;margin:0;padding:0}@media (width >= 960px){.main-nav__list{display:flex;align-items:center;flex-wrap:wrap;gap:0.5rem}}@media (width >= 1280px){.main-nav__list{gap:1.5rem}}.main-nav__item{border-bottom:1px solid #d8d4f7}@media (width >= 960px){.main-nav__item{border-bottom:none}}.main-nav__item--dropdown{position:static}.nav-dropdown{position:relative}.nav-link{display:block;width:100%;padding:1rem 0;font-weight:600;color:inherit;text-decoration:none;outline:none}.nav-link:hover{opacity:0.85}.nav-link:focus-visible{outline:2px solid var(--weg-color-accent);outline-offset:2px;border-radius:4px}.nav-link--active{background:var(--weg-purple-200)}.nav-dropdown__trigger{display:flex;align-items:center;justify-content:space-between;gap:0.75rem;width:100%;padding:1rem 0;border:none;background:transparent;font:inherit;font-weight:600;color:inherit;text-align:left;cursor:pointer;outline:none}.nav-dropdown__trigger:hover{opacity:0.85}.nav-dropdown__trigger:focus-visible{outline:2px solid var(--weg-color-accent);outline-offset:2px;border-radius:4px}.nav-dropdown__trigger--open{background:transparent}.nav-dropdown__trigger--active{background:var(--weg-purple-200)}.toggle-icon{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border-radius:999rem;background:#312e81;color:#ffffff;flex-shrink:0}.nav-dropdown__panel{padding:0 0 0.75rem}@media (width >= 960px){.nav-dropdown__panel{position:absolute;top:calc(100% + 0.5rem);left:0;z-index:500;min-width:17.5rem;padding:0.75rem 0 0.75rem 0.75rem;border:1px solid #e2e8f0;border-radius:0.5rem;background:#f8fafc;box-shadow:0 0.25rem 1rem rgba(15, 23, 42, 0.08)}.nav-dropdown__panel::before{content:'';position:absolute;top:-0.5rem;left:0;right:0;height:0.5rem}}.nav-dropdown__accent{border-left:0.25rem solid var(--weg-color-accent);padding-left:0.75rem}.nav-dropdown__links{display:flex;flex-direction:column;gap:0.25rem}.nav-dropdown__link{display:block;padding:0.625rem 0;font-weight:400;color:inherit;text-decoration:none;outline:none}.nav-dropdown__link:hover{opacity:0.85}.nav-dropdown__link:focus-visible{outline:0.125rem solid var(--weg-color-accent);outline-offset:0.125rem;border-radius:0.25rem}.nav-dropdown__link--active{background:var(--weg-purple-200)}@media (width >= 960px){.nav-dropdown__link{padding:0.5rem;margin-right:0.75rem;border-radius:0.5rem;font-weight:600}.nav-dropdown__link:hover,.nav-dropdown__link:focus-visible{background:var(--weg-purple-200);opacity:1}.nav-dropdown__link--active{opacity:1}}@media (width >= 1280px){.nav-dropdown__link{padding:0.5rem 0.75rem}}.main-nav__item--auth>a{display:flex;align-items:center;gap:0.5rem;width:100%;padding:1rem 0}@media (width >= 960px){.nav-link,.nav-dropdown__trigger,.main-nav__item--auth>a{display:inline-flex;align-items:center;width:auto;padding:0.5rem;border-radius:0.5rem}.nav-link--active,.main-nav__item--auth>a.nav-link--active{background:var(--weg-purple-200)}.nav-dropdown__trigger{gap:0.5rem;cursor:pointer}.nav-dropdown__trigger--open{background:#f1f5f9}.nav-dropdown__trigger--active{background:var(--weg-purple-200)}}@media (width >= 1280px){.main-nav{font-size:1.25rem}.main-nav__item--auth>a{padding:0.5rem 0.75rem}}.sign-in-link,.sign-out-link,.auth-button{display:inline-flex;align-items:center;gap:0.5rem;font-weight:600;color:inherit;text-decoration:none;outline:none}.auth-button{padding:0;border:none;background:transparent;font:inherit;cursor:pointer}.sign-in-link:hover,.sign-out-link:hover,.auth-button:hover{opacity:0.85}.sign-in-link:focus-visible,.sign-out-link:focus-visible,.auth-button:focus-visible{outline:2px solid var(--weg-color-accent);outline-offset:4px;border-radius:4px}.icon-button{display:inline-flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;padding:0;border:none;border-radius:0.5rem;background:transparent;color:inherit;cursor:pointer;text-decoration:none;outline:none}.icon-button:hover{background:#f1f5f9}.icon-button:focus-visible{outline:2px solid var(--weg-color-accent);outline-offset:2px}.menu-toggle{flex-shrink:0}@media (width >= 960px){.menu-toggle{display:none}}`;
|
|
378
|
+
const wegHeaderCss = () => `:host{--weg-breakpoint-sm:640px;--weg-breakpoint-md:960px;--weg-breakpoint-lg:1280px;--weg-breakpoint-xl:1440px}.header{width:100%;border-bottom:2px solid var(--weg-color-accent);background:#ffffff;color:#0f172a;font-family:var(--weg-font-family)}@media (width >= 960px){.header{border-bottom-width:0.25rem}}:host{position:relative;z-index:20;display:block;height:var(--weg-header-height, auto)}.header--fixed{position:fixed;top:0;left:0;right:0;z-index:20;transform:translateY(0);transition:transform 0.25s ease}.header--fixed.header--hidden{transform:translateY(-100%)}@media (prefers-reduced-motion: reduce){.header--fixed{transition:none}}.header--menu-open{position:fixed;inset:0;z-index:1000;display:flex;flex-direction:column;overflow:hidden}.header--menu-open .header-inner{flex:1 1 auto;flex-wrap:wrap;align-content:flex-start;min-height:0}.header--menu-open .main-nav-panel{display:block;flex:1 1 100%;width:100%;min-height:0;overflow-y:auto;border-top:1px solid #d8d4f7}@media (width >= 960px){.header--menu-open{position:static;inset:auto;z-index:auto;display:block;overflow:visible}.header--menu-open .header-inner{flex:unset;flex-wrap:nowrap;align-content:unset;min-height:unset}}.logo-link{display:inline-flex;align-items:center;text-decoration:none;outline:none}.logo-link:focus-visible{outline:2px solid var(--weg-color-accent);outline-offset:4px;border-radius:4px}.logo{height:2.5rem;width:auto}@media (width >= 960px){.logo{height:3rem}}@media (width >= 1280px){.logo{height:5rem}}.header-inner{display:flex;width:100%;min-width:0;align-items:center;justify-content:space-between;gap:0.75rem;padding-block:0.75rem;padding-inline:var(--weg-container-padding-inline)}@media (width >= 960px){.header-inner{flex-wrap:nowrap;gap:1.5rem;padding-block:1.25rem}}@media (width >= 1440px){.header-inner{padding-block:1.75rem}}.header-inner .logo-link{flex:1 1 auto;min-width:0;justify-content:center}@media (width >= 960px){.header-inner .logo-link{flex:0 0 auto;justify-content:flex-start}}.header-inner .logo{max-width:100%}.header-actions{display:flex;align-items:center;flex-shrink:0}@media (width >= 960px){.header-actions{display:none}}.main-nav-panel{display:none;margin-inline:-0.5rem}@media (width >= 960px){.main-nav-panel{display:flex;flex:1 1 auto;width:auto;min-width:0;justify-content:flex-end;overflow:visible;border-top:none}}.main-nav{padding:0 1rem 1.5rem}@media (width >= 960px){.main-nav{display:flex;align-items:center;justify-content:flex-end;flex-wrap:wrap;gap:1rem;padding:0}}.main-nav__list{list-style:none;margin:0;padding:0}@media (width >= 960px){.main-nav__list{display:flex;align-items:center;flex-wrap:wrap;gap:0.5rem}}@media (width >= 1280px){.main-nav__list{gap:1.5rem}}.main-nav__item{border-bottom:1px solid #d8d4f7}@media (width >= 960px){.main-nav__item{border-bottom:none}}.main-nav__item--dropdown{position:static}.nav-dropdown{position:relative}.nav-link{display:block;width:100%;padding:1rem 0;font-weight:600;color:inherit;text-decoration:none;outline:none}.nav-link:hover{opacity:0.85}.nav-link:focus-visible{outline:2px solid var(--weg-color-accent);outline-offset:2px;border-radius:4px}.nav-link--active{background:var(--weg-purple-200)}.nav-dropdown__trigger{display:flex;align-items:center;justify-content:space-between;gap:0.75rem;width:100%;padding:1rem 0;border:none;background:transparent;font:inherit;font-weight:600;color:inherit;text-align:left;cursor:pointer;outline:none}.nav-dropdown__trigger:hover{opacity:0.85}.nav-dropdown__trigger:focus-visible{outline:2px solid var(--weg-color-accent);outline-offset:2px;border-radius:4px}.nav-dropdown__trigger--open{background:transparent}.nav-dropdown__trigger--active{background:var(--weg-purple-200)}.toggle-icon{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border-radius:999rem;background:#312e81;color:#ffffff;flex-shrink:0}.nav-dropdown__panel{padding:0 0 0.75rem}@media (width >= 960px){.nav-dropdown__panel{position:absolute;top:calc(100% + 0.5rem);left:0;z-index:500;min-width:17.5rem;padding:0.75rem 0 0.75rem 0.75rem;border:1px solid #e2e8f0;border-radius:0.5rem;background:#f8fafc;box-shadow:0 0.25rem 1rem rgba(15, 23, 42, 0.08)}.nav-dropdown__panel::before{content:'';position:absolute;top:-0.5rem;left:0;right:0;height:0.5rem}}.nav-dropdown__accent{border-left:0.25rem solid var(--weg-color-accent);padding-left:0.75rem}.nav-dropdown__links{display:flex;flex-direction:column;gap:0.25rem;list-style:none;margin:0;padding:0}.nav-dropdown__link{display:block;padding:0.625rem 0;font-weight:400;color:inherit;text-decoration:none;outline:none}.nav-dropdown__link:hover{opacity:0.85}.nav-dropdown__link:focus-visible{outline:0.125rem solid var(--weg-color-accent);outline-offset:0.125rem;border-radius:0.25rem}.nav-dropdown__link--active{background:var(--weg-purple-200)}@media (width >= 960px){.nav-dropdown__link{padding:0.5rem;margin-right:0.75rem;border-radius:0.5rem;font-weight:600}.nav-dropdown__link:hover,.nav-dropdown__link:focus-visible{background:var(--weg-purple-200);opacity:1}.nav-dropdown__link--active{opacity:1}}@media (width >= 1280px){.nav-dropdown__link{padding:0.5rem 0.75rem}}.main-nav__item--auth>a{display:flex;align-items:center;gap:0.5rem;width:100%;padding:1rem 0}@media (width >= 960px){.nav-link,.nav-dropdown__trigger,.main-nav__item--auth>a{display:inline-flex;align-items:center;width:auto;padding:0.5rem;border-radius:0.5rem}.nav-link--active,.main-nav__item--auth>a.nav-link--active{background:var(--weg-purple-200)}.nav-dropdown__trigger{gap:0.5rem;cursor:pointer}.nav-dropdown__trigger--open{background:#f1f5f9}.nav-dropdown__trigger--active{background:var(--weg-purple-200)}}@media (width >= 1280px){.main-nav{font-size:1.25rem}.main-nav__item--auth>a{padding:0.5rem 0.75rem}}.sign-in-link,.sign-out-link,.auth-button{display:inline-flex;align-items:center;gap:0.5rem;font-weight:600;color:inherit;text-decoration:none;outline:none}.auth-button{padding:0;border:none;background:transparent;font:inherit;cursor:pointer}.sign-in-link:hover,.sign-out-link:hover,.auth-button:hover{opacity:0.85}.sign-in-link:focus-visible,.sign-out-link:focus-visible,.auth-button:focus-visible{outline:2px solid var(--weg-color-accent);outline-offset:4px;border-radius:4px}.icon-button{display:inline-flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;padding:0;border:none;border-radius:0.5rem;background:transparent;color:inherit;cursor:pointer;text-decoration:none;outline:none}.icon-button:hover{background:#f1f5f9}.icon-button:focus-visible{outline:2px solid var(--weg-color-accent);outline-offset:2px}.menu-toggle{flex-shrink:0}@media (width >= 960px){.menu-toggle{display:none}}`;
|
|
379
379
|
|
|
380
380
|
const WEG_HOME = 'https://www.warwickemploymentgroup.com';
|
|
381
381
|
const DEFAULT_ACCOUNT_HOME = 'https://account.warwickemploymentgroup.com';
|
|
382
|
+
/** Stay visible while scrolling down through the first half of the viewport. */
|
|
383
|
+
const HEADER_SCROLL_HIDE_THRESHOLD_VH = 0.5;
|
|
384
|
+
const HEADER_SCROLL_DIRECTION_DELTA = 5;
|
|
382
385
|
const DEFAULT_LOGO_HREF = `${WEG_HOME}/`;
|
|
383
386
|
/** Placeholder href — sign-out is handled via `wegAuthClick`, not navigation. */
|
|
384
387
|
const SIGN_OUT_HREF = '#';
|
|
388
|
+
const MAIN_NAV_LABEL = 'Main navigation';
|
|
389
|
+
const OPEN_MAIN_NAV_LABEL = 'Open main navigation';
|
|
390
|
+
const CLOSE_MAIN_NAV_LABEL = 'Close main navigation';
|
|
385
391
|
function normalizeAccountBase(input) {
|
|
386
392
|
const base = input?.trim() || DEFAULT_ACCOUNT_HOME;
|
|
387
393
|
return base.replace(/\/$/, '');
|
|
@@ -517,9 +523,16 @@ const WegHeader = class {
|
|
|
517
523
|
resolved = EMPTY_HEADER;
|
|
518
524
|
menuOpen = false;
|
|
519
525
|
openDropdown = null;
|
|
526
|
+
headerHidden = false;
|
|
520
527
|
boundHandleDocumentClick = this.handleDocumentClick.bind(this);
|
|
521
528
|
boundHandleViewportChange = this.handleViewportChange.bind(this);
|
|
522
529
|
boundHandleHoverCapabilityChange = this.handleHoverCapabilityChange.bind(this);
|
|
530
|
+
boundHandleScroll = this.handleScroll.bind(this);
|
|
531
|
+
headerResizeObserver;
|
|
532
|
+
lastScrollY = 0;
|
|
533
|
+
scrollTicking = false;
|
|
534
|
+
bodyScrollLocked = false;
|
|
535
|
+
bodyScrollLockY = 0;
|
|
523
536
|
hoverCloseTimer = null;
|
|
524
537
|
hoverOpenEnabled = false;
|
|
525
538
|
desktopMediaQuery;
|
|
@@ -540,15 +553,69 @@ const WegHeader = class {
|
|
|
540
553
|
this.updateHoverDropdownEnabled();
|
|
541
554
|
this.handleViewportChange();
|
|
542
555
|
}
|
|
556
|
+
componentDidLoad() {
|
|
557
|
+
const header = this.el.shadowRoot?.querySelector('.header');
|
|
558
|
+
if (!header)
|
|
559
|
+
return;
|
|
560
|
+
this.headerResizeObserver = new ResizeObserver(() => this.syncHeaderHeight());
|
|
561
|
+
this.headerResizeObserver.observe(header);
|
|
562
|
+
this.syncHeaderHeight();
|
|
563
|
+
this.lastScrollY = window.scrollY;
|
|
564
|
+
this.updateHeaderVisibility();
|
|
565
|
+
}
|
|
543
566
|
connectedCallback() {
|
|
544
567
|
document.addEventListener('click', this.boundHandleDocumentClick);
|
|
568
|
+
window.addEventListener('scroll', this.boundHandleScroll, { passive: true });
|
|
545
569
|
}
|
|
546
570
|
disconnectedCallback() {
|
|
547
571
|
document.removeEventListener('click', this.boundHandleDocumentClick);
|
|
572
|
+
window.removeEventListener('scroll', this.boundHandleScroll);
|
|
573
|
+
this.unlockBodyScroll();
|
|
574
|
+
this.headerResizeObserver?.disconnect();
|
|
548
575
|
this.desktopMediaQuery?.removeEventListener('change', this.boundHandleViewportChange);
|
|
549
576
|
this.hoverCapableMediaQuery?.removeEventListener('change', this.boundHandleHoverCapabilityChange);
|
|
550
577
|
this.cancelScheduledDropdownClose();
|
|
551
578
|
}
|
|
579
|
+
syncHeaderHeight() {
|
|
580
|
+
if (this.isMobileMenuActive())
|
|
581
|
+
return;
|
|
582
|
+
const header = this.el.shadowRoot?.querySelector('.header');
|
|
583
|
+
if (!header)
|
|
584
|
+
return;
|
|
585
|
+
this.el.style.setProperty('--weg-header-height', `${header.offsetHeight}px`);
|
|
586
|
+
}
|
|
587
|
+
handleScroll() {
|
|
588
|
+
if (this.scrollTicking)
|
|
589
|
+
return;
|
|
590
|
+
this.scrollTicking = true;
|
|
591
|
+
requestAnimationFrame(() => {
|
|
592
|
+
this.scrollTicking = false;
|
|
593
|
+
this.updateHeaderVisibility();
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
updateHeaderVisibility() {
|
|
597
|
+
if (this.isMobileMenuActive()) {
|
|
598
|
+
if (this.headerHidden)
|
|
599
|
+
this.headerHidden = false;
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
const scrollY = window.scrollY;
|
|
603
|
+
const delta = scrollY - this.lastScrollY;
|
|
604
|
+
const threshold = window.innerHeight * HEADER_SCROLL_HIDE_THRESHOLD_VH;
|
|
605
|
+
let nextHidden = this.headerHidden;
|
|
606
|
+
if (scrollY <= threshold) {
|
|
607
|
+
nextHidden = false;
|
|
608
|
+
}
|
|
609
|
+
else if (Math.abs(delta) >= HEADER_SCROLL_DIRECTION_DELTA) {
|
|
610
|
+
nextHidden = delta > 0;
|
|
611
|
+
}
|
|
612
|
+
this.lastScrollY = scrollY;
|
|
613
|
+
if (nextHidden === this.headerHidden)
|
|
614
|
+
return;
|
|
615
|
+
if (nextHidden)
|
|
616
|
+
this.closeDropdown();
|
|
617
|
+
this.headerHidden = nextHidden;
|
|
618
|
+
}
|
|
552
619
|
/**
|
|
553
620
|
* Desktop dropdowns open on hover when viewport is md+ and the device reports hover support.
|
|
554
621
|
* Uses (hover: hover) only — not (pointer: fine), which breaks in DevTools and hybrid devices.
|
|
@@ -566,10 +633,74 @@ const WegHeader = class {
|
|
|
566
633
|
}
|
|
567
634
|
handleViewportChange() {
|
|
568
635
|
if (this.desktopMediaQuery?.matches) {
|
|
569
|
-
this.closeMenu();
|
|
636
|
+
this.closeMenu({ announce: false, focusToggle: false });
|
|
570
637
|
}
|
|
571
638
|
this.updateHoverDropdownEnabled();
|
|
572
639
|
}
|
|
640
|
+
announceToScreenReader(message) {
|
|
641
|
+
const region = this.el.shadowRoot?.querySelector('[data-weg-sr-live]');
|
|
642
|
+
if (!region)
|
|
643
|
+
return;
|
|
644
|
+
region.textContent = '';
|
|
645
|
+
requestAnimationFrame(() => {
|
|
646
|
+
region.textContent = message;
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
getMenuToggleButton() {
|
|
650
|
+
return this.el.shadowRoot?.querySelector('.menu-toggle');
|
|
651
|
+
}
|
|
652
|
+
getFirstNavFocusable() {
|
|
653
|
+
const panel = this.el.shadowRoot?.querySelector('#weg-header-main-nav');
|
|
654
|
+
if (!panel)
|
|
655
|
+
return null;
|
|
656
|
+
const focusables = panel.querySelectorAll('a[href], button:not([disabled])');
|
|
657
|
+
return focusables[0] ?? null;
|
|
658
|
+
}
|
|
659
|
+
focusFirstNavItem() {
|
|
660
|
+
setTimeout(() => {
|
|
661
|
+
const attemptFocus = (retries = 8) => {
|
|
662
|
+
const target = this.getFirstNavFocusable();
|
|
663
|
+
if (target) {
|
|
664
|
+
target.focus();
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
if (retries > 0) {
|
|
668
|
+
requestAnimationFrame(() => attemptFocus(retries - 1));
|
|
669
|
+
}
|
|
670
|
+
};
|
|
671
|
+
attemptFocus();
|
|
672
|
+
}, 0);
|
|
673
|
+
}
|
|
674
|
+
focusMenuToggle() {
|
|
675
|
+
const attemptFocus = (retries = 8) => {
|
|
676
|
+
const toggle = this.getMenuToggleButton();
|
|
677
|
+
if (toggle) {
|
|
678
|
+
toggle.focus();
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
if (retries > 0) {
|
|
682
|
+
requestAnimationFrame(() => attemptFocus(retries - 1));
|
|
683
|
+
}
|
|
684
|
+
};
|
|
685
|
+
attemptFocus();
|
|
686
|
+
}
|
|
687
|
+
getMenuGroupLinkCount(label) {
|
|
688
|
+
const group = this.getActiveMenu().find((item) => isMenuGroup(item) && item.label === label);
|
|
689
|
+
return group?.items?.length ?? 0;
|
|
690
|
+
}
|
|
691
|
+
formatLinkCount(count) {
|
|
692
|
+
return count === 1 ? '1 link' : `${count} links`;
|
|
693
|
+
}
|
|
694
|
+
formatItemCount(count) {
|
|
695
|
+
return count === 1 ? '1 item' : `${count} items`;
|
|
696
|
+
}
|
|
697
|
+
announceSubmenuExpanded(label) {
|
|
698
|
+
const linkCount = this.getMenuGroupLinkCount(label);
|
|
699
|
+
this.announceToScreenReader(`${label} submenu expanded. ${this.formatLinkCount(linkCount)}.`);
|
|
700
|
+
}
|
|
701
|
+
announceSubmenuCollapsed(label) {
|
|
702
|
+
this.announceToScreenReader(`${label} submenu collapsed.`);
|
|
703
|
+
}
|
|
573
704
|
isMobileMenuActive() {
|
|
574
705
|
return this.menuOpen && !this.desktopMediaQuery?.matches;
|
|
575
706
|
}
|
|
@@ -579,8 +710,39 @@ const WegHeader = class {
|
|
|
579
710
|
handleKeyDown(event) {
|
|
580
711
|
if (event.key !== 'Escape')
|
|
581
712
|
return;
|
|
582
|
-
this.
|
|
583
|
-
|
|
713
|
+
if (this.openDropdown) {
|
|
714
|
+
event.preventDefault();
|
|
715
|
+
this.closeDropdownAndFocusTrigger(this.openDropdown);
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
if (this.menuOpen) {
|
|
719
|
+
event.preventDefault();
|
|
720
|
+
this.closeMenu({ focusToggle: true });
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
lockBodyScroll() {
|
|
724
|
+
if (this.bodyScrollLocked)
|
|
725
|
+
return;
|
|
726
|
+
this.bodyScrollLockY = window.scrollY;
|
|
727
|
+
document.body.style.overflow = 'hidden';
|
|
728
|
+
document.body.style.position = 'fixed';
|
|
729
|
+
document.body.style.top = `-${this.bodyScrollLockY}px`;
|
|
730
|
+
document.body.style.left = '0';
|
|
731
|
+
document.body.style.right = '0';
|
|
732
|
+
document.body.style.width = '100%';
|
|
733
|
+
this.bodyScrollLocked = true;
|
|
734
|
+
}
|
|
735
|
+
unlockBodyScroll() {
|
|
736
|
+
if (!this.bodyScrollLocked)
|
|
737
|
+
return;
|
|
738
|
+
document.body.style.overflow = '';
|
|
739
|
+
document.body.style.position = '';
|
|
740
|
+
document.body.style.top = '';
|
|
741
|
+
document.body.style.left = '';
|
|
742
|
+
document.body.style.right = '';
|
|
743
|
+
document.body.style.width = '';
|
|
744
|
+
window.scrollTo(0, this.bodyScrollLockY);
|
|
745
|
+
this.bodyScrollLocked = false;
|
|
584
746
|
}
|
|
585
747
|
handleDocumentClick(event) {
|
|
586
748
|
const target = event.target;
|
|
@@ -611,10 +773,12 @@ const WegHeader = class {
|
|
|
611
773
|
}
|
|
612
774
|
toggleDropdown(label) {
|
|
613
775
|
if (this.openDropdown === label) {
|
|
776
|
+
this.announceSubmenuCollapsed(label);
|
|
614
777
|
this.closeDropdown();
|
|
615
778
|
return;
|
|
616
779
|
}
|
|
617
780
|
this.openDropdownMenu(label);
|
|
781
|
+
this.announceSubmenuExpanded(label);
|
|
618
782
|
}
|
|
619
783
|
getDropdownPanelId(label) {
|
|
620
784
|
return `weg-header-dropdown-${label.trim().toLowerCase().replace(/\s+/g, '-')}`;
|
|
@@ -667,29 +831,111 @@ const WegHeader = class {
|
|
|
667
831
|
if (event.key !== 'ArrowDown')
|
|
668
832
|
return;
|
|
669
833
|
event.preventDefault();
|
|
670
|
-
this.
|
|
834
|
+
if (this.openDropdown !== label) {
|
|
835
|
+
this.openDropdownMenu(label);
|
|
836
|
+
this.announceSubmenuExpanded(label);
|
|
837
|
+
}
|
|
671
838
|
this.focusFirstDropdownLink(itemEl);
|
|
672
839
|
}
|
|
840
|
+
getDropdownLinks(container) {
|
|
841
|
+
return Array.from(container.querySelectorAll('.nav-dropdown__link'));
|
|
842
|
+
}
|
|
843
|
+
focusDropdownLink(container, index) {
|
|
844
|
+
const attemptFocus = (retries = 8) => {
|
|
845
|
+
const links = this.getDropdownLinks(container);
|
|
846
|
+
if (links[index]) {
|
|
847
|
+
links[index].focus();
|
|
848
|
+
return;
|
|
849
|
+
}
|
|
850
|
+
if (retries > 0) {
|
|
851
|
+
requestAnimationFrame(() => attemptFocus(retries - 1));
|
|
852
|
+
}
|
|
853
|
+
};
|
|
854
|
+
attemptFocus();
|
|
855
|
+
}
|
|
673
856
|
focusFirstDropdownLink(itemEl) {
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
857
|
+
this.focusDropdownLink(itemEl, 0);
|
|
858
|
+
}
|
|
859
|
+
getDropdownContainer(label) {
|
|
860
|
+
const panelId = this.getDropdownPanelId(label);
|
|
861
|
+
return this.el.shadowRoot?.querySelector(`#${panelId}-trigger`)?.closest('.nav-dropdown') ?? null;
|
|
862
|
+
}
|
|
863
|
+
closeDropdownAndFocusTrigger(labelOrContainer) {
|
|
864
|
+
const container = typeof labelOrContainer === 'string'
|
|
865
|
+
? this.getDropdownContainer(labelOrContainer)
|
|
866
|
+
: labelOrContainer;
|
|
867
|
+
const trigger = container?.querySelector('.nav-dropdown__trigger');
|
|
868
|
+
const label = typeof labelOrContainer === 'string'
|
|
869
|
+
? labelOrContainer
|
|
870
|
+
: (trigger?.querySelector('.nav-dropdown__label')?.textContent?.trim() ?? '');
|
|
871
|
+
if (label && this.openDropdown === label) {
|
|
872
|
+
this.announceSubmenuCollapsed(label);
|
|
873
|
+
}
|
|
874
|
+
this.closeDropdown();
|
|
875
|
+
const attemptFocus = (retries = 8) => {
|
|
876
|
+
if (trigger && this.el.shadowRoot?.contains(trigger)) {
|
|
877
|
+
trigger.focus();
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
if (retries > 0) {
|
|
881
|
+
requestAnimationFrame(() => attemptFocus(retries - 1));
|
|
882
|
+
}
|
|
883
|
+
};
|
|
884
|
+
attemptFocus();
|
|
885
|
+
}
|
|
886
|
+
handleDropdownLinkKeyDown(event, container) {
|
|
887
|
+
const links = this.getDropdownLinks(container);
|
|
888
|
+
const currentIndex = links.indexOf(event.currentTarget);
|
|
889
|
+
if (currentIndex === -1)
|
|
890
|
+
return;
|
|
891
|
+
if (event.key === 'ArrowDown') {
|
|
892
|
+
event.preventDefault();
|
|
893
|
+
links[(currentIndex + 1) % links.length]?.focus();
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
896
|
+
if (event.key === 'ArrowUp') {
|
|
897
|
+
event.preventDefault();
|
|
898
|
+
links[(currentIndex - 1 + links.length) % links.length]?.focus();
|
|
899
|
+
return;
|
|
900
|
+
}
|
|
901
|
+
if (event.key === 'Escape') {
|
|
902
|
+
event.preventDefault();
|
|
903
|
+
event.stopPropagation();
|
|
904
|
+
this.closeDropdownAndFocusTrigger(container);
|
|
905
|
+
}
|
|
678
906
|
}
|
|
679
907
|
toggleMenu() {
|
|
680
908
|
if (this.menuOpen) {
|
|
681
|
-
this.closeMenu();
|
|
909
|
+
this.closeMenu({ focusToggle: false });
|
|
682
910
|
return;
|
|
683
911
|
}
|
|
684
912
|
this.openMenu();
|
|
685
913
|
}
|
|
686
914
|
openMenu() {
|
|
687
915
|
this.menuOpen = true;
|
|
916
|
+
this.headerHidden = false;
|
|
688
917
|
this.closeDropdown();
|
|
918
|
+
if (!this.desktopMediaQuery?.matches) {
|
|
919
|
+
this.lockBodyScroll();
|
|
920
|
+
const itemCount = this.getActiveMenu().length;
|
|
921
|
+
this.announceToScreenReader(`${MAIN_NAV_LABEL} opened. ${this.formatItemCount(itemCount)}.`);
|
|
922
|
+
this.focusFirstNavItem();
|
|
923
|
+
}
|
|
689
924
|
}
|
|
690
|
-
closeMenu() {
|
|
925
|
+
closeMenu(options = {}) {
|
|
926
|
+
const { announce = true, focusToggle = false } = options;
|
|
927
|
+
const wasMobileActive = this.isMobileMenuActive();
|
|
691
928
|
this.menuOpen = false;
|
|
692
929
|
this.closeDropdown();
|
|
930
|
+
this.unlockBodyScroll();
|
|
931
|
+
this.syncHeaderHeight();
|
|
932
|
+
this.updateHeaderVisibility();
|
|
933
|
+
if (announce && wasMobileActive) {
|
|
934
|
+
this.announceToScreenReader(`${MAIN_NAV_LABEL} closed.`);
|
|
935
|
+
}
|
|
936
|
+
if (focusToggle) {
|
|
937
|
+
this.focusMenuToggle();
|
|
938
|
+
}
|
|
693
939
|
}
|
|
694
940
|
getAccountHome() {
|
|
695
941
|
return normalizeAccountBase(this.accountBaseUrl);
|
|
@@ -760,13 +1006,17 @@ const WegHeader = class {
|
|
|
760
1006
|
}, "aria-expanded": isOpen ? 'true' : 'false', "aria-haspopup": "true", "aria-controls": panelId, id: `${panelId}-trigger`, onClick: (event) => this.handleDropdownTriggerClick(event, item.label), onKeyDown: (event) => {
|
|
761
1007
|
const container = event.currentTarget.closest('.nav-dropdown');
|
|
762
1008
|
this.handleDropdownTriggerKeyDown(event, item.label, container);
|
|
763
|
-
} }, h("span", { class: "nav-dropdown__label" }, item.label), h(ToggleIcon, { expanded: isOpen })), isOpen ? (h("div", { class: "nav-dropdown__panel", id: panelId, role: "region", "aria-labelledby": `${panelId}-trigger`, onMouseEnter: () => this.handleDropdownPanelPointerEnter(item.label), onMouseLeave: (event) => this.handleDropdownPanelPointerLeave(event) }, h("div", { class: "nav-dropdown__accent" }, h("
|
|
1009
|
+
} }, h("span", { class: "nav-dropdown__label" }, item.label), h(ToggleIcon, { expanded: isOpen })), isOpen ? (h("div", { class: "nav-dropdown__panel", id: panelId, role: "region", "aria-labelledby": `${panelId}-trigger`, onMouseEnter: () => this.handleDropdownPanelPointerEnter(item.label), onMouseLeave: (event) => this.handleDropdownPanelPointerLeave(event) }, h("div", { class: "nav-dropdown__accent" }, h("ul", { class: "nav-dropdown__links" }, items.map((child, index) => {
|
|
764
1010
|
const childActive = this.isNavItemActive(child.href, 'exact');
|
|
765
1011
|
const ariaCurrent = this.isAriaCurrentHref(child.href, ariaCurrentHref);
|
|
766
|
-
|
|
1012
|
+
const positionLabel = `${child.label}, link ${index + 1} of ${items.length}`;
|
|
1013
|
+
return (h("li", { key: `${item.label}:${child.label}` }, h("a", { class: {
|
|
767
1014
|
'nav-dropdown__link': true,
|
|
768
1015
|
'nav-dropdown__link--active': childActive,
|
|
769
|
-
}, href: child.href,
|
|
1016
|
+
}, href: child.href, "aria-label": positionLabel, "aria-current": ariaCurrent ? 'page' : undefined, onClick: () => onNavigate?.(), onKeyDown: (event) => {
|
|
1017
|
+
const dropdownContainer = event.currentTarget.closest('.nav-dropdown');
|
|
1018
|
+
this.handleDropdownLinkKeyDown(event, dropdownContainer);
|
|
1019
|
+
} }, child.label)));
|
|
770
1020
|
}))))) : null)));
|
|
771
1021
|
}
|
|
772
1022
|
handleAuthClick(event, action, _href, onNavigate) {
|
|
@@ -829,7 +1079,7 @@ const WegHeader = class {
|
|
|
829
1079
|
}
|
|
830
1080
|
renderNav(onNavigate) {
|
|
831
1081
|
const ariaCurrentHref = this.resolveAriaCurrentHref();
|
|
832
|
-
return (h("nav", { class: "main-nav", "aria-label":
|
|
1082
|
+
return (h("nav", { class: "main-nav", "aria-label": MAIN_NAV_LABEL }, h("ul", { class: "main-nav__list" }, this.getActiveMenu().map((item) => this.renderNavItem(item, onNavigate, ariaCurrentHref)))));
|
|
833
1083
|
}
|
|
834
1084
|
renderCompactAuth(onNavigate) {
|
|
835
1085
|
if (this.signedIn) {
|
|
@@ -850,10 +1100,12 @@ const WegHeader = class {
|
|
|
850
1100
|
const logoSrc = this.getLogoSrc();
|
|
851
1101
|
const closeMenu = () => this.closeMenu();
|
|
852
1102
|
const mobileMenuActive = this.isMobileMenuActive();
|
|
853
|
-
return (h("header", { key: '
|
|
1103
|
+
return (h("header", { key: '429d9af0996fa37484ebeea36f1e071fe0ba0789', class: {
|
|
854
1104
|
header: true,
|
|
1105
|
+
'header--fixed': !mobileMenuActive,
|
|
1106
|
+
'header--hidden': this.headerHidden && !mobileMenuActive,
|
|
855
1107
|
'header--menu-open': mobileMenuActive,
|
|
856
|
-
} }, h("div", { key: '
|
|
1108
|
+
} }, h("div", { key: '2c088a3e602ac2c8751d21376872536e35a0ab7d', class: "header-inner" }, h("div", { key: '91089bfc45b2b3274df00b032cad0adaba79b937', class: "sr-only", "aria-live": "polite", "aria-atomic": "true", "data-weg-sr-live": true }), h("button", { key: 'a66e0f0564014f5041a9fa80b39f74ce177f7125', type: "button", class: "menu-toggle icon-button", "aria-label": mobileMenuActive ? CLOSE_MAIN_NAV_LABEL : OPEN_MAIN_NAV_LABEL, "aria-expanded": mobileMenuActive ? 'true' : 'false', "aria-controls": "weg-header-main-nav", onClick: () => this.toggleMenu() }, mobileMenuActive ? h(CloseIcon, null) : h(HamburgerIcon, null)), h(Logo, { key: '917d134565c899e9a25557bafd62bf8b0de75e32', href: logoHref, src: logoSrc }), h("div", { key: '7b6bcd11271e00ddf0ca7d34bc1c8d2ad8342ed4', class: "header-actions" }, this.renderCompactAuth(mobileMenuActive ? closeMenu : undefined)), h("div", { key: '1a6779e99be4704b6f9093501dd230a891b81c17', class: "main-nav-panel", id: "weg-header-main-nav", role: mobileMenuActive ? 'dialog' : undefined, "aria-modal": mobileMenuActive ? 'true' : undefined, "aria-label": mobileMenuActive ? MAIN_NAV_LABEL : undefined }, this.renderNav(mobileMenuActive ? closeMenu : undefined)))));
|
|
857
1109
|
}
|
|
858
1110
|
static get watchers() { return {
|
|
859
1111
|
"layout": [{
|
|
@@ -17,5 +17,5 @@ var patchBrowser = () => {
|
|
|
17
17
|
|
|
18
18
|
patchBrowser().then(async (options) => {
|
|
19
19
|
await globalScripts();
|
|
20
|
-
return bootstrapLazy([["weg-footer_2",[[513,"weg-footer",{"layout":[1],"resolved":[32]},null,{"layout":[{"watchLayout":0}]}],[513,"weg-header",{"layout":[1],"signedIn":[516,"signed-in"],"userName":[1,"user-name"],"accountBaseUrl":[1,"account-base-url"],"currentPath":[1,"current-path"],"resolved":[32],"menuOpen":[32],"openDropdown":[32]},[[8,"keydown","handleKeyDown"]],{"layout":[{"watchLayout":0}]}]]]], options);
|
|
20
|
+
return bootstrapLazy([["weg-footer_2",[[513,"weg-footer",{"layout":[1],"resolved":[32]},null,{"layout":[{"watchLayout":0}]}],[513,"weg-header",{"layout":[1],"signedIn":[516,"signed-in"],"userName":[1,"user-name"],"accountBaseUrl":[1,"account-base-url"],"currentPath":[1,"current-path"],"resolved":[32],"menuOpen":[32],"openDropdown":[32],"headerHidden":[32]},[[8,"keydown","handleKeyDown"]],{"layout":[{"watchLayout":0}]}]]]], options);
|
|
21
21
|
});
|
|
@@ -47,17 +47,28 @@ export declare class WegHeader {
|
|
|
47
47
|
private resolved;
|
|
48
48
|
private menuOpen;
|
|
49
49
|
private openDropdown;
|
|
50
|
+
private headerHidden;
|
|
50
51
|
private boundHandleDocumentClick;
|
|
51
52
|
private boundHandleViewportChange;
|
|
52
53
|
private boundHandleHoverCapabilityChange;
|
|
54
|
+
private boundHandleScroll;
|
|
55
|
+
private headerResizeObserver?;
|
|
56
|
+
private lastScrollY;
|
|
57
|
+
private scrollTicking;
|
|
58
|
+
private bodyScrollLocked;
|
|
59
|
+
private bodyScrollLockY;
|
|
53
60
|
private hoverCloseTimer;
|
|
54
61
|
private hoverOpenEnabled;
|
|
55
62
|
private desktopMediaQuery?;
|
|
56
63
|
private hoverCapableMediaQuery?;
|
|
57
64
|
private resolve;
|
|
58
65
|
componentWillLoad(): void;
|
|
66
|
+
componentDidLoad(): void;
|
|
59
67
|
connectedCallback(): void;
|
|
60
68
|
disconnectedCallback(): void;
|
|
69
|
+
private syncHeaderHeight;
|
|
70
|
+
private handleScroll;
|
|
71
|
+
private updateHeaderVisibility;
|
|
61
72
|
/**
|
|
62
73
|
* Desktop dropdowns open on hover when viewport is md+ and the device reports hover support.
|
|
63
74
|
* Uses (hover: hover) only — not (pointer: fine), which breaks in DevTools and hybrid devices.
|
|
@@ -65,9 +76,21 @@ export declare class WegHeader {
|
|
|
65
76
|
private updateHoverDropdownEnabled;
|
|
66
77
|
private handleHoverCapabilityChange;
|
|
67
78
|
private handleViewportChange;
|
|
79
|
+
private announceToScreenReader;
|
|
80
|
+
private getMenuToggleButton;
|
|
81
|
+
private getFirstNavFocusable;
|
|
82
|
+
private focusFirstNavItem;
|
|
83
|
+
private focusMenuToggle;
|
|
84
|
+
private getMenuGroupLinkCount;
|
|
85
|
+
private formatLinkCount;
|
|
86
|
+
private formatItemCount;
|
|
87
|
+
private announceSubmenuExpanded;
|
|
88
|
+
private announceSubmenuCollapsed;
|
|
68
89
|
private isMobileMenuActive;
|
|
69
90
|
protected watchLayout(): void;
|
|
70
91
|
handleKeyDown(event: KeyboardEvent): void;
|
|
92
|
+
private lockBodyScroll;
|
|
93
|
+
private unlockBodyScroll;
|
|
71
94
|
private handleDocumentClick;
|
|
72
95
|
private cancelScheduledDropdownClose;
|
|
73
96
|
private openDropdownMenu;
|
|
@@ -82,7 +105,12 @@ export declare class WegHeader {
|
|
|
82
105
|
private handleDropdownTriggerClick;
|
|
83
106
|
private handleDropdownFocusOut;
|
|
84
107
|
private handleDropdownTriggerKeyDown;
|
|
108
|
+
private getDropdownLinks;
|
|
109
|
+
private focusDropdownLink;
|
|
85
110
|
private focusFirstDropdownLink;
|
|
111
|
+
private getDropdownContainer;
|
|
112
|
+
private closeDropdownAndFocusTrigger;
|
|
113
|
+
private handleDropdownLinkKeyDown;
|
|
86
114
|
private toggleMenu;
|
|
87
115
|
private openMenu;
|
|
88
116
|
private closeMenu;
|