mirror of
https://github.com/Theodor-Springmann-Stiftung/musenalm.git
synced 2025-10-28 16:55:32 +00:00
173 lines
4.0 KiB
JavaScript
173 lines
4.0 KiB
JavaScript
export class TabList extends HTMLElement {
|
|
static get observedAttributes() {}
|
|
|
|
constructor() {
|
|
super();
|
|
this._showall = false;
|
|
this.shown = -1;
|
|
this._headings = [];
|
|
this._contents = [];
|
|
}
|
|
|
|
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");
|
|
}
|
|
});
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|