// retoor export class OverflowTabs { constructor() { this.instances = []; document.querySelectorAll("[data-overflow-tabs]").forEach((root) => { const instance = this.create(root); if (instance) { this.instances.push(instance); } }); } create(root) { const more = root.querySelector(".overflow-tabs-more"); const strip = root.querySelector(".overflow-tabs-strip"); if (!more || !strip) { return null; } const tabs = Array.from(strip.children).filter( (el) => !el.classList.contains("overflow-tabs-more") ); if (!tabs.length) { return null; } const state = { root, strip, more, tabs, overflow: [], }; state.sync = () => { void strip.offsetWidth; }; state.stripOverflows = () => strip.scrollWidth > strip.clientWidth + 1; state.layout = () => { tabs.forEach((tab) => { tab.hidden = false; }); more.hidden = true; state.sync(); if (!state.stripOverflows()) { state.overflow = []; return; } more.hidden = false; state.sync(); while (state.stripOverflows()) { const victim = tabs .filter((tab) => !tab.hidden && !tab.classList.contains("active")) .pop(); if (!victim) { break; } victim.hidden = true; state.sync(); } state.overflow = tabs.filter((tab) => tab.hidden); if (state.overflow.length > 0 || state.stripOverflows()) { more.hidden = false; } }; state.open = (event) => { event.preventDefault(); event.stopPropagation(); const items = state.overflow.map((tab) => ({ icon: tab.dataset.menuIcon || "", label: tab.dataset.menuLabel || tab.textContent.trim(), onSelect: () => tab.click(), })); if (!items.length) { return; } const rect = more.getBoundingClientRect(); window.app.contextMenu.open(rect.left, rect.bottom + 4, items); }; root.classList.add("tabs-managed"); more.addEventListener("click", (event) => state.open(event)); for (const tab of tabs) { tab.addEventListener("click", () => { requestAnimationFrame(() => state.layout()); }); } const scheduleLayout = () => { requestAnimationFrame(() => state.layout()); }; window.addEventListener("resize", scheduleLayout); if (typeof ResizeObserver !== "undefined") { state.resizeObserver = new ResizeObserver(scheduleLayout); state.resizeObserver.observe(root); state.resizeObserver.observe(strip); } scheduleLayout(); if (document.fonts?.ready) { document.fonts.ready.then(scheduleLayout); } window.addEventListener("load", scheduleLayout, { once: true }); return state; } }