|
1 | 1 | import {Header} from '@google/glue/lib/header'; |
2 | 2 |
|
| 3 | +const enum Classes { |
| 4 | + isOpen = 'is-open', |
| 5 | +} |
| 6 | + |
| 7 | +const enum Selectors { |
| 8 | + dropdown = '[data-js-dropdown]', |
| 9 | + dropdownTrigger = '[data-js-dropdown-trigger]', |
| 10 | + dropdownTarget = '[data-js-dropdown-target]', |
| 11 | +} |
| 12 | + |
3 | 13 | module HeaderModule { |
4 | 14 | function init(): void { |
5 | 15 | const headerEl = document.querySelector<HTMLElement>('.glue-header'); |
6 | 16 | if (headerEl) new Header(headerEl); |
| 17 | + |
| 18 | + const dropdownEls = headerEl?.querySelectorAll(Selectors.dropdown); |
| 19 | + |
| 20 | + dropdownEls?.forEach(el => bindDropdown(el as HTMLElement)); |
| 21 | + } |
| 22 | + |
| 23 | + function bindDropdown(dropdown: HTMLElement) { |
| 24 | + const trigger = dropdown.querySelector(Selectors.dropdownTrigger); |
| 25 | + const target = dropdown.querySelector(Selectors.dropdownTarget); |
| 26 | + |
| 27 | + trigger?.addEventListener('click', e => { |
| 28 | + e.preventDefault(); |
| 29 | + e.stopPropagation(); |
| 30 | + |
| 31 | + target?.classList.toggle(Classes.isOpen); |
| 32 | + |
| 33 | + if (target?.classList.contains(Classes.isOpen)) { |
| 34 | + trigger.setAttribute('aria-expanded', 'true'); |
| 35 | + document.body.addEventListener('click', onClickOutside); |
| 36 | + } else { |
| 37 | + trigger.setAttribute('aria-expanded', 'false'); |
| 38 | + document.body.removeEventListener('click', onClickOutside); |
| 39 | + } |
| 40 | + }); |
| 41 | + } |
| 42 | + |
| 43 | + function onClickOutside(e: MouseEvent) { |
| 44 | + if (!(e.target as HTMLElement)?.closest(Selectors.dropdown)) { |
| 45 | + const dropdowns = document.querySelectorAll(Selectors.dropdown); |
| 46 | + dropdowns.forEach(el => { |
| 47 | + el.querySelector(Selectors.dropdownTarget)?.classList.remove(Classes.isOpen); |
| 48 | + el.querySelector(Selectors.dropdownTrigger)?.setAttribute('aria-expanded', 'false'); |
| 49 | + document.body.removeEventListener('click', onClickOutside); |
| 50 | + }); |
| 51 | + } |
7 | 52 | } |
8 | 53 |
|
9 | 54 | init(); |
|
0 commit comments