interface HTMLElementWithExpander extends HTMLDetailsElement { ODS_Expander?: Expander; } export default class Expander { private element: HTMLElementWithExpander; constructor(element: HTMLElement) { this.element = element as HTMLElementWithExpander; this.toggle = this.toggle.bind(this); this.element.ODS_Expander = this; this.init(); } toggle() { const toggleGroup = this.element.getAttribute("data-toggle-group"); if (toggleGroup) { this.syncGroup(toggleGroup); } } private syncGroup(groupName: string) { const isOpen = this.element.open; const groupElements = document.querySelectorAll( `[data-toggle-group="${groupName}"][data-expander]`, ) as NodeListOf; groupElements.forEach((element) => { if (element !== this.element) { if (element.open !== isOpen) { element.open = isOpen; } } }); } init() { this.element.addEventListener("toggle", this.toggle); } update() { this.destroy(); this.init(); } destroy() { this.element.removeEventListener("toggle", this.toggle); } static getInstance(el: HTMLElementWithExpander | null): Expander | null { return el && el.ODS_Expander ? el.ODS_Expander : null; } }