export class TabList extends HTMLElement { static get observedAttributes() {} constructor() { super(); this._showall = false; this.shown = -1; this._headings = []; this._contents = []; this._checkbox = null; } connectedCallback() { this._headings = Array.from(this.querySelectorAll(".tab-list-head")); this._contents = Array.from(this.querySelectorAll(".tab-list-panel")); this.hookupEvtHandlers(); this.hideDependent(); if (this._headings.length === 1) { this.expand(0); } } expand(index) { if (index < 0 || index >= this._headings.length) { return; } this.shown = index; this._contents.forEach((content, i) => { if (i === index) { content.classList.remove("hidden"); this._headings[i].setAttribute("aria-pressed", "true"); } else { content.classList.add("hidden"); this._headings[i].setAttribute("aria-pressed", "false"); } }); } hookupShowAll(checkbox) { if (checkbox) { this._checkbox = checkbox; checkbox.addEventListener("change", (event) => { if (event.target.checked) { this.showAll(); } else { this.default(); } }); } } hookupEvtHandlers() { for (let heading of this._headings) { heading.addEventListener("click", this.handleTabClick.bind(this)); heading.classList.add("cursor-pointer"); heading.classList.add("select-none"); heading.setAttribute("role", "button"); heading.setAttribute("aria-pressed", "false"); heading.setAttribute("tabindex", "0"); } for (let content of this._contents) { content.classList.add("hidden"); } } restore() { for (let heading of this._headings) { heading.classList.add("cursor-pointer"); heading.classList.add("select-none"); heading.setAttribute("role", "button"); heading.setAttribute("aria-pressed", "false"); heading.setAttribute("tabindex", "0"); heading.classList.remove("pointer-events-none"); heading.classList.remove("!text-slate-900"); } for (let content of this._contents) { content.classList.add("hidden"); } } disable() { for (let heading of this._headings) { heading.classList.remove("cursor-pointer"); heading.classList.remove("select-none"); heading.removeAttribute("role"); heading.removeAttribute("aria-pressed"); heading.removeAttribute("tabindex"); heading.classList.add("pointer-events-none"); heading.classList.add("!text-slate-900"); } } showAll() { this._showall = true; this.shown = -1; this.disable(); this._contents.forEach((content, i) => { content.classList.remove("hidden"); let heading = this._headings[i]; let showopened = heading.querySelectorAll(".show-opened"); for (let e of showopened) { e.classList.add("hidden"); } let showclosed = heading.querySelectorAll(".show-closed"); for (let e of showclosed) { e.classList.add("hidden"); } }); } default() { this._showall = false; this.restore(); this.hideDependent(); } hideDependent() { if (this.shown < 0) { for (const el of this._headings) { this._hideAllDep(el, false); } } else { this._headings.forEach((el, i) => { this._hideAllDep(el, i === this.shown); }); } } _hideAllDep(element, opened) { const el = element.querySelectorAll(".show-closed"); for (let e of el) { if (opened) { e.classList.add("hidden"); } else { e.classList.remove("hidden"); } } const oel = Array.from(element.querySelectorAll(".show-opened")); for (let e of oel) { if (opened) { e.classList.remove("hidden"); } else { e.classList.add("hidden"); } } } handleTabClick(event) { if (!event.target) { console.warn("Invalid event target"); return; } const parent = this.findParentWithClass(event.target, "tab-list-head"); if (!parent) { console.warn("No parent found with class 'tab-list-head'"); return; } const index = this._headings.indexOf(parent); if (index === this.shown) { this._contents[index].classList.toggle("hidden"); this._headings[index].setAttribute("aria-pressed", "false"); this.shown = -1; } else { this.expand(index); } this.hideDependent(); } findParentWithClass(element, className) { while (element) { if (element.classList && element.classList.contains(className)) { return element; } element = element.parentElement; } return null; } }