weg-shared-layout 0.0.20 → 0.0.22

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.
@@ -36,9 +36,9 @@ function normalizeLinks(input) {
36
36
  return result;
37
37
  }
38
38
 
39
- const sharedCss$1 = () => `*,*::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}.container{width:100%;margin-inline:auto;padding-inline:1rem;padding-block:12px}@media (width >= 40rem){.container{max-width:40rem}}@media (width >= 48rem){.container{max-width:48rem;padding-inline:2rem;padding-block:20px}}@media (width >= 64rem){.container{max-width:64rem}}@media (width >= 80rem){.container{max-width:80rem;padding-block:28px}}@media (width >= 86rem){.container{max-width:86rem}}.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}`;
39
+ const sharedCss$1 = () => `:host{--weg-breakpoint-sm:640px;--weg-breakpoint-md:768px;--weg-breakpoint-lg:1024px;--weg-breakpoint-xl:1280px}*,*::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}.container{width:100%;margin-inline:auto;padding-inline:1rem;padding-block:12px}@media (width >= 640px){.container{max-width:var(--weg-breakpoint-sm)}}@media (width >= 768px){.container{max-width:var(--weg-breakpoint-md);padding-inline:2rem;padding-block:20px}}@media (width >= 1024px){.container{max-width:var(--weg-breakpoint-lg)}}@media (width >= 1280px){.container{max-width:var(--weg-breakpoint-xl);padding-block:28px}}.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}`;
40
40
 
41
- const wegFooterCss = () => `.footer{background:#030712;color:#ffffff;font-family:var(--weg-font-family);font-weight:300}.footer__inner{display:flex;flex-direction:column;align-items:center;gap:20px;padding-block:32px}@media (min-width: 768px){.footer__inner{gap:36px;padding-block:56px}}.social{display:flex;align-items:center;justify-content:center;gap:16px}@media (min-width: 768px){.social{gap:28px}}.social__link{width:48px;height:48px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;background:transparent;color:inherit;text-decoration:none;transition:opacity 150ms ease;outline:none}.social__link:hover{opacity:0.9}.social__link:focus-visible{outline:2px solid rgba(255, 255, 255, 0.9);outline-offset:4px}.social__icon{display:inline-flex;width:48px;height:48px}.footer-link{color:#ffffff;font-family:'Open Sans', var(--weg-font-family);font-size:16px;font-style:normal;font-weight:300;line-height:24px;display:block;width:100%;text-align:center;text-decoration-line:underline;text-decoration-style:solid;text-decoration-skip-ink:none;text-decoration-thickness:auto;text-underline-offset:auto;text-underline-position:from-font;outline:none}@media (min-width: 768px){.footer-link{display:inline;width:auto;text-align:left}}.footer-link:hover{opacity:0.9}.footer-link:focus-visible{outline:2px solid rgba(255, 255, 255, 0.9);outline-offset:4px}.legal{width:100%;max-width:860px;text-align:center;font-size:16px;line-height:24px}@media (min-width: 768px){.legal{font-size:18px;line-height:28px}}.legal__p{margin:0}.standard{width:100%;display:flex;flex-direction:column;align-items:center;gap:36px;text-align:center;font-size:16px;line-height:24px}@media (min-width: 768px){.standard{font-size:18px;line-height:28px}}.columns{width:100%;display:grid;gap:0;grid-template-columns:1fr}@media (min-width: 768px){.columns{display:flex;flex-direction:row;align-items:stretch;justify-content:center;gap:0}}.columns__col{display:flex;flex:1 1 0;min-width:0;width:100%;align-items:stretch;flex-direction:column}.columns__col:not(:first-child){gap:32px}@media (min-width: 768px){.columns__col{flex-direction:row;align-items:stretch}.columns__col:not(:first-child){gap:0}}.columns__divider{display:block;background:rgba(255, 255, 255, 0.35);flex-shrink:0;width:100%;height:1px;align-self:stretch;margin-top:32px;margin-bottom:0}@media (min-width: 768px){.columns__divider{width:1px;height:auto;margin:0 12px}}.columns__links{display:flex;flex-direction:column;align-items:stretch;gap:12px;flex:1;width:100%;min-width:0;padding:0 4px;text-align:center}@media (min-width: 768px){.columns__links{align-items:flex-start;padding:0 12px;text-align:left}}`;
41
+ const wegFooterCss = () => `.footer{background:#030712;color:#ffffff;font-family:var(--weg-font-family);font-weight:300}.footer__inner{display:flex;flex-direction:column;align-items:center;gap:20px;padding-block:32px}.social{display:flex;align-items:center;justify-content:center;gap:16px}.social__link{width:48px;height:48px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;background:transparent;color:inherit;text-decoration:none;transition:opacity 150ms ease;outline:none}.social__link:hover{opacity:0.9}.social__link:focus-visible{outline:2px solid rgba(255, 255, 255, 0.9);outline-offset:4px}.social__icon{display:inline-flex;width:48px;height:48px}.footer-link{color:#ffffff;font-family:'Open Sans', var(--weg-font-family);font-size:16px;font-style:normal;font-weight:300;line-height:24px;display:block;width:100%;text-align:center;text-decoration-line:underline;text-decoration-style:solid;text-decoration-skip-ink:none;text-decoration-thickness:auto;text-underline-offset:auto;text-underline-position:from-font;outline:none}.footer-link:hover{opacity:0.9}.footer-link:focus-visible{outline:2px solid rgba(255, 255, 255, 0.9);outline-offset:4px}.legal{width:100%;max-width:860px;text-align:center;font-size:16px;line-height:24px}.legal__p{margin:0}.standard{width:100%;display:flex;flex-direction:column;align-items:center;gap:36px;text-align:center;font-size:16px;line-height:24px}.columns{width:100%;display:grid;gap:0;grid-template-columns:1fr}.columns__col{display:flex;flex:1 1 0;min-width:0;width:100%;align-items:stretch;flex-direction:column}.columns__col:not(:first-child){gap:32px}.columns__divider{display:block;background:rgba(255, 255, 255, 0.35);flex-shrink:0;width:100%;height:1px;align-self:stretch;margin-top:32px;margin-bottom:0}.columns__links{display:flex;flex-direction:column;align-items:stretch;gap:12px;flex:1;width:100%;min-width:0;padding:0 4px;text-align:center}@media (width >= 768px){.footer__inner{gap:36px;padding-block:56px}.social{gap:28px}.footer-link{display:inline;width:auto;text-align:left}.legal{font-size:18px;line-height:28px}.standard{font-size:18px;line-height:28px}.columns{display:flex;flex-direction:row;align-items:stretch;justify-content:center;gap:0}.columns__col{flex-direction:row;align-items:stretch}.columns__col:not(:first-child){gap:0}.columns__divider{width:1px;height:auto;margin:0 12px}.columns__links{align-items:flex-start;padding:0 12px;text-align:left}}`;
42
42
 
43
43
  const EMPTY_FOOTER = {
44
44
  social: [],
@@ -214,9 +214,9 @@ const SIGNED_IN_HEADER = {
214
214
  signOut: HEADER_SIGN_OUT,
215
215
  };
216
216
 
217
- const sharedCss = () => `*,*::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}.container{width:100%;margin-inline:auto;padding-inline:1rem;padding-block:12px}@media (width >= 40rem){.container{max-width:40rem}}@media (width >= 48rem){.container{max-width:48rem;padding-inline:2rem;padding-block:20px}}@media (width >= 64rem){.container{max-width:64rem}}@media (width >= 80rem){.container{max-width:80rem;padding-block:28px}}@media (width >= 86rem){.container{max-width:86rem}}.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}`;
217
+ const sharedCss = () => `:host{--weg-breakpoint-sm:640px;--weg-breakpoint-md:768px;--weg-breakpoint-lg:1024px;--weg-breakpoint-xl:1280px}*,*::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}.container{width:100%;margin-inline:auto;padding-inline:1rem;padding-block:12px}@media (width >= 640px){.container{max-width:var(--weg-breakpoint-sm)}}@media (width >= 768px){.container{max-width:var(--weg-breakpoint-md);padding-inline:2rem;padding-block:20px}}@media (width >= 1024px){.container{max-width:var(--weg-breakpoint-lg)}}@media (width >= 1280px){.container{max-width:var(--weg-breakpoint-xl);padding-block:28px}}.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}`;
218
218
 
219
- const wegHeaderCss = () => `.header{width:100%;border-bottom:2px solid var(--weg-color-accent);background:#ffffff;color:#0f172a;font-family:var(--weg-font-family)}:host{position:relative;z-index:20}@media (min-width: 768px){.header{border-bottom-width:4px}}.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:40px;width:auto}@media (min-width: 768px){.logo{height:80px}}.desktop{display:none}@media (min-width: 768px){.desktop{display:flex;width:100%;align-items:center;justify-content:space-between;gap:24px}}.desktop-nav{display:flex;align-items:center;justify-content:flex-end;flex-wrap:wrap;gap:16px}.desktop-nav__list{display:flex;align-items:center;flex-wrap:wrap;gap:16px;list-style:none;margin:0;padding:0}.desktop-nav__item{position:relative}.nav-link{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:4px;border-radius:4px}.dropdown-trigger{display:inline-flex;align-items:center;gap:8px;padding:8px 12px;border:none;border-radius:8px;background:transparent;font:inherit;font-weight:600;color:inherit;cursor:pointer;outline:none}.dropdown-trigger:hover{opacity:0.85}.dropdown-trigger:focus-visible{outline:2px solid var(--weg-color-accent);outline-offset:2px}.dropdown-trigger--open{background:#f1f5f9}.toggle-icon{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:999px;background:#312e81;color:#ffffff;flex-shrink:0}.dropdown-panel{position:absolute;top:calc(100% + 8px);left:0;z-index:50;min-width:280px;padding:12px 0 12px 12px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc;box-shadow:0 4px 16px rgba(15, 23, 42, 0.08)}.dropdown-panel__accent{border-left:4px solid var(--weg-color-accent);padding-left:12px}.dropdown-panel__links{display:flex;flex-direction:column;gap:4px}.dropdown-panel__link{display:block;padding:8px 12px 8px 0;font-weight:600;color:inherit;text-decoration:none;outline:none}.dropdown-panel__link:hover{opacity:0.85}.dropdown-panel__link:focus-visible{outline:2px solid var(--weg-color-accent);outline-offset:2px;border-radius:4px}.sign-in-link,.sign-out-link,.auth-button{display:inline-flex;align-items:center;gap:8px;font-weight:600;color:inherit;text-decoration:none;outline:none}.sign-out-link.mobile-nav__row{justify-content:flex-start;gap:8px}.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}.mobile{display:flex;width:100%;min-width:0;align-items:center;justify-content:space-between;gap:12px}.mobile .logo-link{flex:1 1 auto;min-width:0;justify-content:center}.mobile .logo{max-width:100%}@media (min-width: 768px){.mobile{display:none}}.icon-button{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border:none;border-radius:8px;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}.mobile-overlay{position:fixed;inset:0;z-index:100;background:#ffffff;overflow-y:auto}.mobile-overlay__header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 16px;border-bottom:2px solid var(--weg-color-accent)}.mobile-overlay__logo{flex:1;display:flex;justify-content:center}.mobile-overlay__logo .logo{height:40px}.mobile-nav{padding:0 16px 24px}.mobile-nav__section{border-bottom:1px solid #d8d4f7}.mobile-nav__row{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;padding:16px 0;border:none;background:transparent;font:inherit;font-weight:600;color:inherit;text-align:left;text-decoration:none;cursor:pointer;outline:none}.mobile-nav__row:focus-visible{outline:2px solid var(--weg-color-accent);outline-offset:2px;border-radius:4px}.mobile-nav__sub{padding:0 0 12px 0}.mobile-nav__sub-link{display:block;padding:10px 0;font-weight:400;color:inherit;text-decoration:none;outline:none}.mobile-nav__sub-link:focus-visible{outline:2px solid var(--weg-color-accent);outline-offset:2px;border-radius:4px}.mobile-nav__sub-link:hover{opacity:0.85}`;
219
+ const wegHeaderCss = () => `.header{width:100%;border-bottom:2px solid var(--weg-color-accent);background:#ffffff;color:#0f172a;font-family:var(--weg-font-family)}:host{position:relative;z-index:20}.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:40px;width:auto}.desktop{display:none}.desktop-nav{display:flex;align-items:center;justify-content:flex-end;flex-wrap:wrap;gap:16px}.desktop-nav__list{display:flex;align-items:center;flex-wrap:wrap;gap:16px;list-style:none;margin:0;padding:0}.desktop-nav__item{position:relative}.nav-link{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:4px;border-radius:4px}.dropdown-trigger{display:inline-flex;align-items:center;gap:8px;padding:8px 12px;border:none;border-radius:8px;background:transparent;font:inherit;font-weight:600;color:inherit;cursor:pointer;outline:none}.dropdown-trigger:hover{opacity:0.85}.dropdown-trigger:focus-visible{outline:2px solid var(--weg-color-accent);outline-offset:2px}.dropdown-trigger--open{background:#f1f5f9}.toggle-icon{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:999px;background:#312e81;color:#ffffff;flex-shrink:0}.dropdown-panel{position:absolute;top:calc(100% + 8px);left:0;z-index:50;min-width:280px;padding:12px 0 12px 12px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc;box-shadow:0 4px 16px rgba(15, 23, 42, 0.08)}.dropdown-panel::before{content:'';position:absolute;top:-8px;left:0;right:0;height:8px}.dropdown-panel__accent{border-left:4px solid var(--weg-color-accent);padding-left:12px}.dropdown-panel__links{display:flex;flex-direction:column;gap:4px}.dropdown-panel__link{display:block;padding:8px 12px;margin-right:12px;border-radius:6px;font-weight:600;color:inherit;text-decoration:none;outline:none}.dropdown-panel__link:hover{background:#cdcff8}.dropdown-panel__link:focus-visible{background:#cdcff8;outline:2px solid var(--weg-color-accent);outline-offset:2px}.sign-in-link,.sign-out-link,.auth-button{display:inline-flex;align-items:center;gap:8px;font-weight:600;color:inherit;text-decoration:none;outline:none}.sign-out-link.mobile-nav__row{justify-content:flex-start;gap:8px}.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}.mobile{display:flex;width:100%;min-width:0;align-items:center;justify-content:space-between;gap:12px}.mobile .logo-link{flex:1 1 auto;min-width:0;justify-content:center}.mobile .logo{max-width:100%}.icon-button{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border:none;border-radius:8px;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}.mobile-overlay{position:fixed;inset:0;z-index:100;background:#ffffff;overflow-y:auto}.mobile-overlay__header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 16px;border-bottom:2px solid var(--weg-color-accent)}.mobile-overlay__logo{flex:1;display:flex;justify-content:center}.mobile-overlay__logo .logo{height:40px}.mobile-nav{padding:0 16px 24px}.mobile-nav__section{border-bottom:1px solid #d8d4f7}.mobile-nav__row{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;padding:16px 0;border:none;background:transparent;font:inherit;font-weight:600;color:inherit;text-align:left;text-decoration:none;cursor:pointer;outline:none}.mobile-nav__row:focus-visible{outline:2px solid var(--weg-color-accent);outline-offset:2px;border-radius:4px}.mobile-nav__sub{padding:0 0 12px 0}.mobile-nav__sub-link{display:block;padding:10px 0;font-weight:400;color:inherit;text-decoration:none;outline:none}.mobile-nav__sub-link:focus-visible{outline:2px solid var(--weg-color-accent);outline-offset:2px;border-radius:4px}.mobile-nav__sub-link:hover{opacity:0.85}@media (width >= 768px){.header{border-bottom-width:4px}.logo{height:80px}.desktop{display:flex;width:100%;align-items:center;justify-content:space-between;gap:24px}.mobile{display:none}}@media (width >= 1280px){.desktop-nav__list{gap:35px}}`;
220
220
 
221
221
  const EMPTY_HEADER = {
222
222
  logoHref: DEFAULT_LOGO_HREF,
@@ -337,6 +337,8 @@ const WegHeader = class {
337
337
  openDropdown = null;
338
338
  expandedSection = null;
339
339
  boundHandleDocumentClick = this.handleDocumentClick.bind(this);
340
+ hoverCloseTimer = null;
341
+ hoverOpenEnabled = false;
340
342
  resolve() {
341
343
  if (this.layout === undefined || this.layout === null) {
342
344
  this.resolved = EMPTY_HEADER;
@@ -346,12 +348,14 @@ const WegHeader = class {
346
348
  }
347
349
  componentWillLoad() {
348
350
  this.resolve();
351
+ this.hoverOpenEnabled = window.matchMedia('(hover: hover) and (pointer: fine)').matches;
349
352
  }
350
353
  connectedCallback() {
351
354
  document.addEventListener('click', this.boundHandleDocumentClick);
352
355
  }
353
356
  disconnectedCallback() {
354
357
  document.removeEventListener('click', this.boundHandleDocumentClick);
358
+ this.cancelScheduledDropdownClose();
355
359
  }
356
360
  watchLayout() {
357
361
  this.resolve();
@@ -360,16 +364,79 @@ const WegHeader = class {
360
364
  if (event.key !== 'Escape')
361
365
  return;
362
366
  this.menuOpen = false;
363
- this.openDropdown = null;
367
+ this.closeDropdown();
364
368
  }
365
369
  handleDocumentClick(event) {
366
370
  const target = event.target;
367
371
  if (!target || !this.el.contains(target)) {
368
- this.openDropdown = null;
372
+ this.closeDropdown();
369
373
  }
370
374
  }
375
+ cancelScheduledDropdownClose() {
376
+ if (!this.hoverCloseTimer)
377
+ return;
378
+ clearTimeout(this.hoverCloseTimer);
379
+ this.hoverCloseTimer = null;
380
+ }
381
+ openDropdownMenu(label) {
382
+ this.cancelScheduledDropdownClose();
383
+ this.openDropdown = label;
384
+ }
385
+ closeDropdown() {
386
+ this.cancelScheduledDropdownClose();
387
+ this.openDropdown = null;
388
+ }
389
+ scheduleDropdownClose() {
390
+ this.cancelScheduledDropdownClose();
391
+ this.hoverCloseTimer = setTimeout(() => {
392
+ this.openDropdown = null;
393
+ this.hoverCloseTimer = null;
394
+ }, 200);
395
+ }
371
396
  toggleDropdown(label) {
372
- this.openDropdown = this.openDropdown === label ? null : label;
397
+ if (this.openDropdown === label) {
398
+ this.closeDropdown();
399
+ return;
400
+ }
401
+ this.openDropdownMenu(label);
402
+ }
403
+ getDropdownPanelId(label) {
404
+ return `weg-header-dropdown-${label.trim().toLowerCase().replace(/\s+/g, '-')}`;
405
+ }
406
+ handleDropdownPointerEnter(label) {
407
+ if (!this.hoverOpenEnabled)
408
+ return;
409
+ this.openDropdownMenu(label);
410
+ }
411
+ handleDropdownPointerLeave() {
412
+ if (!this.hoverOpenEnabled)
413
+ return;
414
+ this.scheduleDropdownClose();
415
+ }
416
+ handleDropdownFocusIn(label) {
417
+ this.openDropdownMenu(label);
418
+ }
419
+ handleDropdownFocusOut(event, label) {
420
+ const related = event.relatedTarget;
421
+ const currentTarget = event.currentTarget;
422
+ if (related && currentTarget.contains(related))
423
+ return;
424
+ if (this.openDropdown === label) {
425
+ this.closeDropdown();
426
+ }
427
+ }
428
+ handleDropdownTriggerKeyDown(event, label, itemEl) {
429
+ if (event.key !== 'ArrowDown')
430
+ return;
431
+ event.preventDefault();
432
+ this.openDropdownMenu(label);
433
+ this.focusFirstDropdownLink(itemEl);
434
+ }
435
+ focusFirstDropdownLink(itemEl) {
436
+ setTimeout(() => {
437
+ const firstLink = itemEl.querySelector('.dropdown-panel__link');
438
+ firstLink?.focus();
439
+ }, 0);
373
440
  }
374
441
  toggleAccordion(label) {
375
442
  this.expandedSection = this.expandedSection === label ? null : label;
@@ -460,13 +527,17 @@ const WegHeader = class {
460
527
  const { dropdowns, links } = this.getActiveHeaderData();
461
528
  return (index.h("div", { class: "desktop" }, index.h(Logo, { href: this.getLogoHref() }), index.h("nav", { class: "desktop-nav", "aria-label": "Main" }, index.h("ul", { class: "desktop-nav__list" }, dropdowns.map((dropdown) => {
462
529
  const isOpen = this.openDropdown === dropdown.label;
463
- return (index.h("li", { class: "desktop-nav__item", key: dropdown.label }, index.h("button", { type: "button", class: {
530
+ const panelId = this.getDropdownPanelId(dropdown.label);
531
+ return (index.h("li", { class: "desktop-nav__item desktop-nav__item--dropdown", key: dropdown.label, onMouseEnter: () => this.handleDropdownPointerEnter(dropdown.label), onMouseLeave: () => this.handleDropdownPointerLeave(), onFocusin: () => this.handleDropdownFocusIn(dropdown.label), onFocusout: (event) => this.handleDropdownFocusOut(event, dropdown.label) }, index.h("button", { type: "button", class: {
464
532
  'dropdown-trigger': true,
465
533
  'dropdown-trigger--open': isOpen,
466
- }, "aria-expanded": isOpen ? 'true' : 'false', "aria-haspopup": "true", onClick: (event) => {
534
+ }, "aria-expanded": isOpen ? 'true' : 'false', "aria-haspopup": "true", "aria-controls": panelId, id: `${panelId}-trigger`, onClick: (event) => {
467
535
  event.stopPropagation();
468
536
  this.toggleDropdown(dropdown.label);
469
- } }, dropdown.label, index.h(ToggleIcon, { expanded: isOpen })), isOpen ? (index.h("div", { class: "dropdown-panel", role: "region", "aria-label": dropdown.label }, index.h("div", { class: "dropdown-panel__accent" }, index.h("div", { class: "dropdown-panel__links" }, dropdown.items.map((item) => (index.h("a", { class: "dropdown-panel__link", href: item.href, key: `${dropdown.label}:${item.label}` }, item.label))))))) : null));
537
+ }, onKeyDown: (event) => {
538
+ const itemEl = event.currentTarget.closest('.desktop-nav__item--dropdown');
539
+ this.handleDropdownTriggerKeyDown(event, dropdown.label, itemEl);
540
+ } }, dropdown.label, index.h(ToggleIcon, { expanded: isOpen })), isOpen ? (index.h("div", { class: "dropdown-panel", id: panelId, role: "region", "aria-labelledby": `${panelId}-trigger` }, index.h("div", { class: "dropdown-panel__accent" }, index.h("div", { class: "dropdown-panel__links" }, dropdown.items.map((item) => (index.h("a", { class: "dropdown-panel__link", href: item.href, key: `${dropdown.label}:${item.label}` }, item.label))))))) : null));
470
541
  }), links.map((link) => (index.h("li", { class: "desktop-nav__item", key: link.label }, index.h("a", { class: "nav-link", href: link.href }, link.label)))), this.signedIn
471
542
  ? this.renderSignedInAuthControls({})
472
543
  : this.getAuthControl()
@@ -490,7 +561,7 @@ const WegHeader = class {
490
561
  }), links.map((link) => (index.h("div", { class: "mobile-nav__section", key: link.label }, index.h("a", { class: "mobile-nav__row", href: link.href, onClick: () => this.closeMenu() }, link.label)))), this.signedIn ? (index.h("div", { class: "mobile-nav__section" }, index.h("a", { class: "mobile-nav__row manage-account-link", href: SIGNED_IN_HEADER.manageAccount.href, onClick: () => this.closeMenu() }, this.getManageAccountLabel()), index.h("a", { class: "mobile-nav__row sign-out-link", href: SIGNED_IN_HEADER.signOut.href, onClick: (event) => this.handleAuthClick(event, () => this.closeMenu()) }, index.h(SignOutIcon, null), SIGNED_IN_HEADER.signOut.label))) : null)));
491
562
  }
492
563
  render() {
493
- return (index.h("header", { key: '0f20e384f9185157d95ece52ec48ec013d745162', class: "header" }, index.h("div", { key: 'a5ca65e830a86583050fab3c04e68b8818baac00', class: "container" }, this.renderDesktop(), this.renderMobileBar()), this.renderMobileOverlay()));
564
+ return (index.h("header", { key: 'fc00e4afd015b291311939ba30f4ae3070957864', class: "header" }, index.h("div", { key: 'f2c8ed2c4e702e0a85acfbccd91165f5a2e1ff7a', class: "container" }, this.renderDesktop(), this.renderMobileBar()), this.renderMobileOverlay()));
494
565
  }
495
566
  static get watchers() { return {
496
567
  "layout": [{
@@ -13,13 +13,6 @@
13
13
  padding-block: 32px;
14
14
  }
15
15
 
16
- @media (min-width: 768px) {
17
- .footer__inner {
18
- gap: 36px;
19
- padding-block: 56px;
20
- }
21
- }
22
-
23
16
  .social {
24
17
  display: flex;
25
18
  align-items: center;
@@ -27,12 +20,6 @@
27
20
  gap: 16px;
28
21
  }
29
22
 
30
- @media (min-width: 768px) {
31
- .social {
32
- gap: 28px;
33
- }
34
- }
35
-
36
23
  .social__link {
37
24
  width: 48px;
38
25
  height: 48px;
@@ -81,14 +68,6 @@
81
68
  outline: none;
82
69
  }
83
70
 
84
- @media (min-width: 768px) {
85
- .footer-link {
86
- display: inline;
87
- width: auto;
88
- text-align: left;
89
- }
90
- }
91
-
92
71
  .footer-link:hover {
93
72
  opacity: 0.9;
94
73
  }
@@ -106,13 +85,6 @@
106
85
  line-height: 24px;
107
86
  }
108
87
 
109
- @media (min-width: 768px) {
110
- .legal {
111
- font-size: 18px;
112
- line-height: 28px;
113
- }
114
- }
115
-
116
88
  .legal__p {
117
89
  margin: 0;
118
90
  }
@@ -128,13 +100,6 @@
128
100
  line-height: 24px;
129
101
  }
130
102
 
131
- @media (min-width: 768px) {
132
- .standard {
133
- font-size: 18px;
134
- line-height: 28px;
135
- }
136
- }
137
-
138
103
  .columns {
139
104
  width: 100%;
140
105
  display: grid;
@@ -142,16 +107,6 @@
142
107
  grid-template-columns: 1fr;
143
108
  }
144
109
 
145
- @media (min-width: 768px) {
146
- .columns {
147
- display: flex;
148
- flex-direction: row;
149
- align-items: stretch;
150
- justify-content: center;
151
- gap: 0;
152
- }
153
- }
154
-
155
110
  .columns__col {
156
111
  display: flex;
157
112
  flex: 1 1 0;
@@ -165,17 +120,6 @@
165
120
  gap: 32px;
166
121
  }
167
122
 
168
- @media (min-width: 768px) {
169
- .columns__col {
170
- flex-direction: row;
171
- align-items: stretch;
172
- }
173
-
174
- .columns__col:not(:first-child) {
175
- gap: 0;
176
- }
177
- }
178
-
179
123
  .columns__divider {
180
124
  display: block;
181
125
  background: rgba(255, 255, 255, 0.35);
@@ -187,14 +131,6 @@
187
131
  margin-bottom: 0;
188
132
  }
189
133
 
190
- @media (min-width: 768px) {
191
- .columns__divider {
192
- width: 1px;
193
- height: auto;
194
- margin: 0 12px;
195
- }
196
- }
197
-
198
134
  .columns__links {
199
135
  display: flex;
200
136
  flex-direction: column;
@@ -207,7 +143,56 @@
207
143
  text-align: center;
208
144
  }
209
145
 
210
- @media (min-width: 768px) {
146
+ /* md: matches --weg-breakpoint-md */
147
+ @media (width >= 768px) {
148
+ .footer__inner {
149
+ gap: 36px;
150
+ padding-block: 56px;
151
+ }
152
+
153
+ .social {
154
+ gap: 28px;
155
+ }
156
+
157
+ .footer-link {
158
+ display: inline;
159
+ width: auto;
160
+ text-align: left;
161
+ }
162
+
163
+ .legal {
164
+ font-size: 18px;
165
+ line-height: 28px;
166
+ }
167
+
168
+ .standard {
169
+ font-size: 18px;
170
+ line-height: 28px;
171
+ }
172
+
173
+ .columns {
174
+ display: flex;
175
+ flex-direction: row;
176
+ align-items: stretch;
177
+ justify-content: center;
178
+ gap: 0;
179
+ }
180
+
181
+ .columns__col {
182
+ flex-direction: row;
183
+ align-items: stretch;
184
+ }
185
+
186
+ .columns__col:not(:first-child) {
187
+ gap: 0;
188
+ }
189
+
190
+ .columns__divider {
191
+ width: 1px;
192
+ height: auto;
193
+ margin: 0 12px;
194
+ }
195
+
211
196
  .columns__links {
212
197
  align-items: flex-start;
213
198
  padding: 0 12px;
@@ -66,6 +66,18 @@ describe('weg-header', () => {
66
66
  signOutLink?.click();
67
67
  expect(detail).toEqual({ action: 'sign-out' });
68
68
  });
69
+ it('opens desktop dropdown on trigger focus with accessible wiring', async () => {
70
+ const { root } = await render(h("weg-header", { layout: SAMPLE_HEADER_LAYOUT }));
71
+ const trigger = root.shadowRoot?.querySelector('.dropdown-trigger');
72
+ expect(trigger).toBeTruthy();
73
+ expect(trigger?.getAttribute('aria-haspopup')).toBe('true');
74
+ expect(trigger?.getAttribute('aria-expanded')).toBe('false');
75
+ expect(trigger?.getAttribute('aria-controls')).toBeTruthy();
76
+ trigger?.focus();
77
+ await new Promise((r) => setTimeout(r, 0));
78
+ expect(trigger?.getAttribute('aria-expanded')).toBe('true');
79
+ expect(root.shadowRoot?.querySelector('.dropdown-panel')).toBeTruthy();
80
+ });
69
81
  it('toggles mobile accordion aria-expanded', async () => {
70
82
  const { root } = await render(h("weg-header", { layout: SAMPLE_HEADER_LAYOUT }));
71
83
  const openButton = root.shadowRoot?.querySelector('.mobile .icon-button');
@@ -11,12 +11,6 @@
11
11
  z-index: 20;
12
12
  }
13
13
 
14
- @media (min-width: 768px) {
15
- .header {
16
- border-bottom-width: 4px;
17
- }
18
- }
19
-
20
14
  .logo-link {
21
15
  display: inline-flex;
22
16
  align-items: center;
@@ -35,27 +29,11 @@
35
29
  width: auto;
36
30
  }
37
31
 
38
- @media (min-width: 768px) {
39
- .logo {
40
- height: 80px;
41
- }
42
- }
43
-
44
32
  /* Desktop */
45
33
  .desktop {
46
34
  display: none;
47
35
  }
48
36
 
49
- @media (min-width: 768px) {
50
- .desktop {
51
- display: flex;
52
- width: 100%;
53
- align-items: center;
54
- justify-content: space-between;
55
- gap: 24px;
56
- }
57
- }
58
-
59
37
  .desktop-nav {
60
38
  display: flex;
61
39
  align-items: center;
@@ -148,6 +126,16 @@
148
126
  box-shadow: 0 4px 16px rgba(15, 23, 42, 0.08);
149
127
  }
150
128
 
129
+ /* Invisible bridge so pointer travel from trigger to panel does not close hover menu */
130
+ .dropdown-panel::before {
131
+ content: '';
132
+ position: absolute;
133
+ top: -8px;
134
+ left: 0;
135
+ right: 0;
136
+ height: 8px;
137
+ }
138
+
151
139
  .dropdown-panel__accent {
152
140
  border-left: 4px solid var(--weg-color-accent);
153
141
  padding-left: 12px;
@@ -161,7 +149,9 @@
161
149
 
162
150
  .dropdown-panel__link {
163
151
  display: block;
164
- padding: 8px 12px 8px 0;
152
+ padding: 8px 12px;
153
+ margin-right: 12px;
154
+ border-radius: 6px;
165
155
  font-weight: 600;
166
156
  color: inherit;
167
157
  text-decoration: none;
@@ -169,13 +159,13 @@
169
159
  }
170
160
 
171
161
  .dropdown-panel__link:hover {
172
- opacity: 0.85;
162
+ background: #cdcff8;
173
163
  }
174
164
 
175
165
  .dropdown-panel__link:focus-visible {
166
+ background: #cdcff8;
176
167
  outline: 2px solid var(--weg-color-accent);
177
168
  outline-offset: 2px;
178
- border-radius: 4px;
179
169
  }
180
170
 
181
171
  .sign-in-link,
@@ -237,12 +227,6 @@
237
227
  max-width: 100%;
238
228
  }
239
229
 
240
- @media (min-width: 768px) {
241
- .mobile {
242
- display: none;
243
- }
244
- }
245
-
246
230
  .icon-button {
247
231
  display: inline-flex;
248
232
  align-items: center;
@@ -349,3 +333,33 @@
349
333
  .mobile-nav__sub-link:hover {
350
334
  opacity: 0.85;
351
335
  }
336
+
337
+ /* md: matches --weg-breakpoint-md */
338
+ @media (width >= 768px) {
339
+ .header {
340
+ border-bottom-width: 4px;
341
+ }
342
+
343
+ .logo {
344
+ height: 80px;
345
+ }
346
+
347
+ .desktop {
348
+ display: flex;
349
+ width: 100%;
350
+ align-items: center;
351
+ justify-content: space-between;
352
+ gap: 24px;
353
+ }
354
+
355
+ .mobile {
356
+ display: none;
357
+ }
358
+ }
359
+
360
+ /* xl: matches --weg-breakpoint-xl */
361
+ @media (width >= 1280px) {
362
+ .desktop-nav__list {
363
+ gap: 35px;
364
+ }
365
+ }
@@ -117,6 +117,8 @@ export class WegHeader {
117
117
  openDropdown = null;
118
118
  expandedSection = null;
119
119
  boundHandleDocumentClick = this.handleDocumentClick.bind(this);
120
+ hoverCloseTimer = null;
121
+ hoverOpenEnabled = false;
120
122
  resolve() {
121
123
  if (this.layout === undefined || this.layout === null) {
122
124
  this.resolved = EMPTY_HEADER;
@@ -126,12 +128,14 @@ export class WegHeader {
126
128
  }
127
129
  componentWillLoad() {
128
130
  this.resolve();
131
+ this.hoverOpenEnabled = window.matchMedia('(hover: hover) and (pointer: fine)').matches;
129
132
  }
130
133
  connectedCallback() {
131
134
  document.addEventListener('click', this.boundHandleDocumentClick);
132
135
  }
133
136
  disconnectedCallback() {
134
137
  document.removeEventListener('click', this.boundHandleDocumentClick);
138
+ this.cancelScheduledDropdownClose();
135
139
  }
136
140
  watchLayout() {
137
141
  this.resolve();
@@ -140,16 +144,79 @@ export class WegHeader {
140
144
  if (event.key !== 'Escape')
141
145
  return;
142
146
  this.menuOpen = false;
143
- this.openDropdown = null;
147
+ this.closeDropdown();
144
148
  }
145
149
  handleDocumentClick(event) {
146
150
  const target = event.target;
147
151
  if (!target || !this.el.contains(target)) {
148
- this.openDropdown = null;
152
+ this.closeDropdown();
149
153
  }
150
154
  }
155
+ cancelScheduledDropdownClose() {
156
+ if (!this.hoverCloseTimer)
157
+ return;
158
+ clearTimeout(this.hoverCloseTimer);
159
+ this.hoverCloseTimer = null;
160
+ }
161
+ openDropdownMenu(label) {
162
+ this.cancelScheduledDropdownClose();
163
+ this.openDropdown = label;
164
+ }
165
+ closeDropdown() {
166
+ this.cancelScheduledDropdownClose();
167
+ this.openDropdown = null;
168
+ }
169
+ scheduleDropdownClose() {
170
+ this.cancelScheduledDropdownClose();
171
+ this.hoverCloseTimer = setTimeout(() => {
172
+ this.openDropdown = null;
173
+ this.hoverCloseTimer = null;
174
+ }, 200);
175
+ }
151
176
  toggleDropdown(label) {
152
- this.openDropdown = this.openDropdown === label ? null : label;
177
+ if (this.openDropdown === label) {
178
+ this.closeDropdown();
179
+ return;
180
+ }
181
+ this.openDropdownMenu(label);
182
+ }
183
+ getDropdownPanelId(label) {
184
+ return `weg-header-dropdown-${label.trim().toLowerCase().replace(/\s+/g, '-')}`;
185
+ }
186
+ handleDropdownPointerEnter(label) {
187
+ if (!this.hoverOpenEnabled)
188
+ return;
189
+ this.openDropdownMenu(label);
190
+ }
191
+ handleDropdownPointerLeave() {
192
+ if (!this.hoverOpenEnabled)
193
+ return;
194
+ this.scheduleDropdownClose();
195
+ }
196
+ handleDropdownFocusIn(label) {
197
+ this.openDropdownMenu(label);
198
+ }
199
+ handleDropdownFocusOut(event, label) {
200
+ const related = event.relatedTarget;
201
+ const currentTarget = event.currentTarget;
202
+ if (related && currentTarget.contains(related))
203
+ return;
204
+ if (this.openDropdown === label) {
205
+ this.closeDropdown();
206
+ }
207
+ }
208
+ handleDropdownTriggerKeyDown(event, label, itemEl) {
209
+ if (event.key !== 'ArrowDown')
210
+ return;
211
+ event.preventDefault();
212
+ this.openDropdownMenu(label);
213
+ this.focusFirstDropdownLink(itemEl);
214
+ }
215
+ focusFirstDropdownLink(itemEl) {
216
+ setTimeout(() => {
217
+ const firstLink = itemEl.querySelector('.dropdown-panel__link');
218
+ firstLink?.focus();
219
+ }, 0);
153
220
  }
154
221
  toggleAccordion(label) {
155
222
  this.expandedSection = this.expandedSection === label ? null : label;
@@ -241,13 +308,17 @@ export class WegHeader {
241
308
  const { dropdowns, links } = this.getActiveHeaderData();
242
309
  return (h("div", { class: "desktop" }, h(Logo, { href: this.getLogoHref() }), h("nav", { class: "desktop-nav", "aria-label": "Main" }, h("ul", { class: "desktop-nav__list" }, dropdowns.map((dropdown) => {
243
310
  const isOpen = this.openDropdown === dropdown.label;
244
- return (h("li", { class: "desktop-nav__item", key: dropdown.label }, h("button", { type: "button", class: {
311
+ const panelId = this.getDropdownPanelId(dropdown.label);
312
+ return (h("li", { class: "desktop-nav__item desktop-nav__item--dropdown", key: dropdown.label, onMouseEnter: () => this.handleDropdownPointerEnter(dropdown.label), onMouseLeave: () => this.handleDropdownPointerLeave(), onFocusin: () => this.handleDropdownFocusIn(dropdown.label), onFocusout: (event) => this.handleDropdownFocusOut(event, dropdown.label) }, h("button", { type: "button", class: {
245
313
  'dropdown-trigger': true,
246
314
  'dropdown-trigger--open': isOpen,
247
- }, "aria-expanded": isOpen ? 'true' : 'false', "aria-haspopup": "true", onClick: (event) => {
315
+ }, "aria-expanded": isOpen ? 'true' : 'false', "aria-haspopup": "true", "aria-controls": panelId, id: `${panelId}-trigger`, onClick: (event) => {
248
316
  event.stopPropagation();
249
317
  this.toggleDropdown(dropdown.label);
250
- } }, dropdown.label, h(ToggleIcon, { expanded: isOpen })), isOpen ? (h("div", { class: "dropdown-panel", role: "region", "aria-label": dropdown.label }, h("div", { class: "dropdown-panel__accent" }, h("div", { class: "dropdown-panel__links" }, dropdown.items.map((item) => (h("a", { class: "dropdown-panel__link", href: item.href, key: `${dropdown.label}:${item.label}` }, item.label))))))) : null));
318
+ }, onKeyDown: (event) => {
319
+ const itemEl = event.currentTarget.closest('.desktop-nav__item--dropdown');
320
+ this.handleDropdownTriggerKeyDown(event, dropdown.label, itemEl);
321
+ } }, dropdown.label, h(ToggleIcon, { expanded: isOpen })), isOpen ? (h("div", { class: "dropdown-panel", id: panelId, role: "region", "aria-labelledby": `${panelId}-trigger` }, h("div", { class: "dropdown-panel__accent" }, h("div", { class: "dropdown-panel__links" }, dropdown.items.map((item) => (h("a", { class: "dropdown-panel__link", href: item.href, key: `${dropdown.label}:${item.label}` }, item.label))))))) : null));
251
322
  }), links.map((link) => (h("li", { class: "desktop-nav__item", key: link.label }, h("a", { class: "nav-link", href: link.href }, link.label)))), this.signedIn
252
323
  ? this.renderSignedInAuthControls({})
253
324
  : this.getAuthControl()
@@ -271,7 +342,7 @@ export class WegHeader {
271
342
  }), links.map((link) => (h("div", { class: "mobile-nav__section", key: link.label }, h("a", { class: "mobile-nav__row", href: link.href, onClick: () => this.closeMenu() }, link.label)))), this.signedIn ? (h("div", { class: "mobile-nav__section" }, h("a", { class: "mobile-nav__row manage-account-link", href: SIGNED_IN_HEADER.manageAccount.href, onClick: () => this.closeMenu() }, this.getManageAccountLabel()), h("a", { class: "mobile-nav__row sign-out-link", href: SIGNED_IN_HEADER.signOut.href, onClick: (event) => this.handleAuthClick(event, () => this.closeMenu()) }, h(SignOutIcon, null), SIGNED_IN_HEADER.signOut.label))) : null)));
272
343
  }
273
344
  render() {
274
- return (h("header", { key: '0f20e384f9185157d95ece52ec48ec013d745162', class: "header" }, h("div", { key: 'a5ca65e830a86583050fab3c04e68b8818baac00', class: "container" }, this.renderDesktop(), this.renderMobileBar()), this.renderMobileOverlay()));
345
+ return (h("header", { key: 'fc00e4afd015b291311939ba30f4ae3070957864', class: "header" }, h("div", { key: 'f2c8ed2c4e702e0a85acfbccd91165f5a2e1ff7a', class: "container" }, this.renderDesktop(), this.renderMobileBar()), this.renderMobileOverlay()));
275
346
  }
276
347
  static get is() { return "weg-header"; }
277
348
  static get encapsulation() { return "shadow"; }