1class AbtDropdown extends HTMLElement { 2 open = false; 3 constructor() { 4 super(); 5 6 this.button = this.querySelector('.btn-dropdown'); 7 this.buttonSpan = this.querySelector('.btn-dropdown span'); 8 9 this.button.addEventListener('click', this.toggle.bind(this)); 10 11 this.menu = this.querySelector('.dropdown-menu'); 12 this.radioList = this.querySelectorAll('input[type="radio"]'); 13 14 if (this.radioList.length) 15 this.addEventListener('change', this.onChange.bind(this)); 16 } 17 18 connectedCallback() { 19 this.radioList.forEach(radio => { 20 if (radio.checked) radio.dispatchEvent(new Event('change', { bubbles: true })); 21 }); 22 } 23 24 toggle() { 25 if (!this.menu) return; 26 27 this.open = !this.open; 28 29 this.button?.setAttribute('aria-expanded', this.open); 30 } 31 32 onChange(event) { 33 const element = event.target; 34 const span = element.nextElementSibling; 35 36 if (this.buttonSpan === null || span === false) return; 37 38 this.buttonSpan.textContent = span.textContent; 39 40 if (this.radioList.length && this.button.getAttribute('aria-required') === 'true') this.setValidity(); 41 } 42 43 setValidity() { 44 this.parentNode.classList.remove('is-valid', 'is-invalid'); 45 46 let valid = false; 47 48 this.radioList.forEach(radio => { 49 if (radio.checked) { 50 valid = radio.value === '' ? false : radio.checkValidity(); 51 } 52 }); 53 54 if (valid) this.parentNode.classList.add('is-valid'); 55 else this.parentNode.classList.add('is-invalid'); 56 57 const errorMessage = this.parentNode.querySelector('.abt-form-error-message'); 58 59 if (errorMessage) errorMessage.hidden = valid; 60 } 61} 62 63customElements.define('abt-dropdown', AbtDropdown);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.