|
1 | 1 | // Headernav Component // |
2 | 2 |
|
| 3 | +import { popoverSupport } from './popover-support' |
3 | 4 | const headerNav = document.querySelector('.js-headernav') |
4 | 5 | const subNavs = headerNav.querySelectorAll(':scope > ul > li:has(> ul)') |
5 | 6 | const headerNavMediaQuery = window.matchMedia('(min-width: 760px)') |
6 | | -let counter = 1 |
7 | 7 |
|
8 | | -if (document.querySelector('.c-headernav')) { |
| 8 | +if (headerNav && popoverSupport()) { |
9 | 9 | for (const subNav of subNavs) { |
10 | | - const subNavSiblingLink = subNav.querySelector('a') |
| 10 | + const subNavLink = subNav.querySelector('a') |
11 | 11 | const subNavPopover = subNav.querySelector('ul') |
12 | | - subNavPopover.popover = '' |
13 | | - |
14 | | - // Anchor each sibling link to its popover using unique anchor names: |
15 | | - const anchorName = '--anchor' + counter++ |
16 | | - |
17 | | - // The properties 'anchor-name' and 'position-anchor' can't be set using style.setProperty in browsers that don't support them. Instead, use setAttribute to force them to appear in so that the anchor positioning polyfill sees them: |
18 | | - subNavSiblingLink.setAttribute('style', 'anchor-name: ' + anchorName) |
19 | | - subNavPopover.setAttribute('style', 'position-anchor: ' + anchorName) |
| 12 | + subNavPopover.popover = 'auto' |
| 13 | + subNavLink.setAttribute('role', 'button') |
20 | 14 |
|
21 | 15 | const headerNavToggles = mq => { |
| 16 | + // Only a <button> as a popover invoker has built-in accessiblity bindings, so set and toggle the link's aria expanded state: |
22 | 17 | const expandedState = () => { |
23 | 18 | if (subNavPopover.matches(':popover-open')) { |
24 | | - subNavSiblingLink.setAttribute('aria-expanded', 'true') |
| 19 | + subNavLink.setAttribute('aria-expanded', 'true') |
25 | 20 | } else { |
26 | | - subNavSiblingLink.setAttribute('aria-expanded', 'false') |
| 21 | + subNavLink.setAttribute('aria-expanded', 'false') |
27 | 22 | } |
28 | 23 | } |
29 | 24 |
|
30 | 25 | if (mq.matches) { |
31 | | - // Only a <button> as a popover control has built-in accessiblity bindings, so set and toggle sibling link aria expanded state: |
32 | | - subNavSiblingLink.setAttribute('aria-expanded', 'false') // initial state |
| 26 | + // Initial state: |
| 27 | + expandedState() |
33 | 28 |
|
34 | | - // Show/hide subnav on mouse pointer over and out: |
| 29 | + // Show subnav on mouseover: |
35 | 30 | subNav.addEventListener('mouseover', () => { |
36 | 31 | subNavPopover.showPopover() |
37 | 32 | expandedState() |
38 | 33 | }) |
39 | 34 |
|
| 35 | + // Hide subnav on mouseout: |
40 | 36 | subNav.addEventListener('mouseout', () => { |
41 | 37 | subNavPopover.hidePopover() |
42 | 38 | expandedState() |
43 | 39 | }) |
44 | 40 |
|
45 | | - // Toggle subnav if sibling link is clicked by keyboard return key: |
46 | | - subNavSiblingLink.addEventListener('click', (e) => { |
| 41 | + // Toggle subnav if link clicked: |
| 42 | + subNavLink.addEventListener('click', (e) => { |
47 | 43 | subNavPopover.togglePopover() |
48 | | - e.preventDefault() // disable link from going to its URL when clicked |
49 | 44 | expandedState() |
| 45 | + e.preventDefault() // disable link from going to its URL when clicked |
50 | 46 | }) |
51 | 47 |
|
52 | | - // Hide subnav when keyboard focus leaves its popover control: |
| 48 | + // Hide previously opened subnav when keyboard focus leaves it: |
53 | 49 | subNav.addEventListener('focusout', (e) => { |
54 | 50 | if (!e.currentTarget.contains(e.relatedTarget)) { |
55 | 51 | subNavPopover.hidePopover() |
|
0 commit comments