import toggle from "../../scripts/modules/toggleUtil"; interface FeatureAccordionConfig { bodiesSelector: string; buttonSelector: string; } const defaultConfig: FeatureAccordionConfig = { bodiesSelector: ".accordion__body", buttonSelector: "[data-feature-accordion-toggle]", }; export default class FeatureAccordion { private element: HTMLElement; private config: FeatureAccordionConfig; private bodies: HTMLElement[] = []; private buttons: HTMLElement[] = []; private images: HTMLElement[] = []; constructor(element: HTMLElement, config?: Partial) { this.element = element; this.config = { ...defaultConfig, ...config }; (this.element as any).ODS_FeatureAccordion = this; this.init(); return this; } private init(): void { this.bodies = Array.from( this.element.querySelectorAll(this.config.bodiesSelector), ); this.buttons = Array.from( this.element.querySelectorAll(this.config.buttonSelector), ); this.images = Array.from( this.element.querySelectorAll("[data-feature-accordion-image]"), ) as HTMLElement[]; this.setActive(0); this.buttons.forEach((button) => { button.addEventListener("click", this.onClick); }); } private onClick = (e: Event): void => { const button = e.currentTarget as HTMLElement; const index = this.buttons.indexOf(button); this.setActive(index); }; private setActive(index: number): void { if (index < 0 || index >= this.buttons.length) return; this.bodies.forEach((body) => { body.setAttribute("hidden", ""); body.classList.remove("is-active"); }); this.buttons.forEach((btn) => { const item = btn.closest(".feature-accordion__item"); item?.classList.remove("is-active"); toggle({ element: btn, attribute: "aria-expanded", value: "false", }); }); const activeBtn = this.buttons[index]; const activeControls = activeBtn.getAttribute("aria-controls"); const activeBody = activeControls ? document.getElementById(activeControls) : null; const activeItem = activeBtn.closest(".feature-accordion__item"); if (activeBody) { activeBody.removeAttribute("hidden"); activeBody.classList.add("is-active"); } if (activeItem) { activeItem.classList.add("is-active"); } toggle({ element: activeBtn, attribute: "aria-expanded", value: "true", }); this.images.forEach((img, imgIndex) => { img.classList.toggle("hide", imgIndex !== index); }); } destroy(): void { this.buttons.forEach((button) => { button.removeEventListener("click", this.onClick); }); } update(): void { this.destroy(); this.init(); } static getInstance(el: HTMLElement): FeatureAccordion | null { return el && (el as any).ODS_FeatureAccordion ? (el as any).ODS_FeatureAccordion : null; } }