update styles and ui-chrome
This commit is contained in:
173
app/ui-chrome.js
173
app/ui-chrome.js
@@ -6,6 +6,7 @@
|
||||
const DEFAULT_DATASET_ENTRY_COLLAPSED = false;
|
||||
const DEFAULT_DATASET_DETAIL_COLLAPSED = true;
|
||||
const sidebarControllers = new WeakMap();
|
||||
const sidebarControllerRegistry = new Map();
|
||||
const detailControllers = new WeakMap();
|
||||
const AUTO_COLLAPSE_ENTRY_SELECTOR = [
|
||||
".planet-list-item",
|
||||
@@ -162,6 +163,131 @@
|
||||
return resolveLayoutTarget(panel);
|
||||
}
|
||||
|
||||
function isLayoutVisible(layout) {
|
||||
if (!(layout instanceof HTMLElement)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (layout.hidden || layout.closest("[hidden]")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const section = layout.closest("section");
|
||||
if (section instanceof HTMLElement && section.hidden) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getActiveVisibleSidebarController() {
|
||||
for (const controller of sidebarControllerRegistry.values()) {
|
||||
if (!isLayoutVisible(controller.layout)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return controller;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getTopbarPanelToggleButton() {
|
||||
const { topbarEl, menuToggleEl } = getTopbarElements();
|
||||
if (!(topbarEl instanceof HTMLElement) || !(menuToggleEl instanceof HTMLButtonElement)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const existingButton = topbarEl.querySelector("#topbar-panel-toggle");
|
||||
if (existingButton instanceof HTMLButtonElement) {
|
||||
return existingButton;
|
||||
}
|
||||
|
||||
const panelToggleEl = document.createElement("button");
|
||||
panelToggleEl.id = "topbar-panel-toggle";
|
||||
panelToggleEl.type = "button";
|
||||
panelToggleEl.className = "topbar-panel-toggle sidebar-popout-open";
|
||||
panelToggleEl.textContent = "Show Detail";
|
||||
panelToggleEl.setAttribute("aria-label", "Show detail view");
|
||||
panelToggleEl.hidden = true;
|
||||
panelToggleEl.addEventListener("click", () => {
|
||||
const controller = getActiveVisibleSidebarController();
|
||||
if (!controller) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (controller.layout.classList.contains("layout-sidebar-collapsed")) {
|
||||
showSidebarOnly(controller.layout);
|
||||
return;
|
||||
}
|
||||
|
||||
if (detailControllers.has(controller.layout)) {
|
||||
showDetailOnly(controller.layout);
|
||||
}
|
||||
});
|
||||
|
||||
topbarEl.insertBefore(panelToggleEl, menuToggleEl);
|
||||
return panelToggleEl;
|
||||
}
|
||||
|
||||
function syncTopbarPanelToggleButton() {
|
||||
const panelToggleEl = getTopbarPanelToggleButton();
|
||||
if (!(panelToggleEl instanceof HTMLButtonElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const controller = getActiveVisibleSidebarController();
|
||||
if (!controller) {
|
||||
panelToggleEl.hidden = true;
|
||||
panelToggleEl.removeAttribute("aria-controls");
|
||||
panelToggleEl.setAttribute("aria-expanded", "false");
|
||||
return;
|
||||
}
|
||||
|
||||
const sidebarCollapsed = controller.layout.classList.contains("layout-sidebar-collapsed");
|
||||
const hasDetailController = detailControllers.has(controller.layout);
|
||||
if (!sidebarCollapsed && !hasDetailController) {
|
||||
panelToggleEl.hidden = true;
|
||||
panelToggleEl.removeAttribute("aria-controls");
|
||||
panelToggleEl.setAttribute("aria-expanded", "false");
|
||||
return;
|
||||
}
|
||||
|
||||
panelToggleEl.hidden = false;
|
||||
panelToggleEl.setAttribute("aria-controls", controller.panel.id);
|
||||
panelToggleEl.setAttribute("aria-expanded", sidebarCollapsed ? "false" : "true");
|
||||
panelToggleEl.textContent = sidebarCollapsed ? "Show Panel" : "Show Detail";
|
||||
panelToggleEl.setAttribute("aria-label", sidebarCollapsed ? "Show entry panel" : "Show detail view");
|
||||
}
|
||||
|
||||
function initializeTopbarPanelToggle() {
|
||||
if (!document.body || document.body.dataset.topbarPanelToggleReady === "1") {
|
||||
syncTopbarPanelToggleButton();
|
||||
return;
|
||||
}
|
||||
|
||||
document.body.dataset.topbarPanelToggleReady = "1";
|
||||
getTopbarPanelToggleButton();
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
window.requestAnimationFrame(() => {
|
||||
syncTopbarPanelToggleButton();
|
||||
});
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
subtree: true,
|
||||
attributes: true,
|
||||
attributeFilter: ["hidden", "class"]
|
||||
});
|
||||
|
||||
window.addEventListener("resize", () => {
|
||||
syncTopbarPanelToggleButton();
|
||||
});
|
||||
|
||||
syncTopbarPanelToggleButton();
|
||||
}
|
||||
|
||||
function scheduleAutoCollapse(layout) {
|
||||
if (!(layout instanceof HTMLElement)) {
|
||||
return;
|
||||
@@ -221,11 +347,6 @@
|
||||
return;
|
||||
}
|
||||
|
||||
const header = panel.querySelector(".planet-list-header, .tarot-list-header");
|
||||
if (!(header instanceof HTMLElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
panel.dataset.sidebarPopoutReady = "1";
|
||||
|
||||
const sectionId = layout.closest("section")?.id || `layout-${index + 1}`;
|
||||
@@ -234,53 +355,30 @@
|
||||
|
||||
const storageKey = `${SIDEBAR_COLLAPSE_STORAGE_PREFIX}${sectionId}`;
|
||||
|
||||
const collapseBtn = document.createElement("button");
|
||||
collapseBtn.type = "button";
|
||||
collapseBtn.className = "sidebar-toggle-inline";
|
||||
collapseBtn.textContent = "Hide Panel";
|
||||
collapseBtn.setAttribute("aria-label", "Hide entry panel");
|
||||
collapseBtn.setAttribute("aria-controls", panelId);
|
||||
header.appendChild(collapseBtn);
|
||||
|
||||
const openBtn = document.createElement("button");
|
||||
openBtn.type = "button";
|
||||
openBtn.className = "sidebar-popout-open";
|
||||
openBtn.textContent = "Show Panel";
|
||||
openBtn.setAttribute("aria-label", "Show entry panel");
|
||||
openBtn.setAttribute("aria-controls", panelId);
|
||||
openBtn.hidden = true;
|
||||
layout.appendChild(openBtn);
|
||||
|
||||
const applyCollapsedState = (collapsed, persist = true) => {
|
||||
layout.classList.toggle("layout-sidebar-collapsed", collapsed);
|
||||
collapseBtn.setAttribute("aria-expanded", collapsed ? "false" : "true");
|
||||
openBtn.setAttribute("aria-expanded", collapsed ? "false" : "true");
|
||||
openBtn.hidden = !collapsed;
|
||||
syncTopbarPanelToggleButton();
|
||||
|
||||
if (persist) {
|
||||
saveSidebarCollapsedState(storageKey, collapsed);
|
||||
}
|
||||
};
|
||||
|
||||
sidebarControllers.set(layout, {
|
||||
const controller = {
|
||||
layout,
|
||||
applyCollapsedState,
|
||||
panel,
|
||||
collapseBtn,
|
||||
openBtn,
|
||||
storageKey
|
||||
});
|
||||
};
|
||||
|
||||
collapseBtn.addEventListener("click", () => {
|
||||
showDetailOnly(layout);
|
||||
});
|
||||
|
||||
openBtn.addEventListener("click", () => {
|
||||
showSidebarOnly(layout);
|
||||
});
|
||||
sidebarControllers.set(layout, controller);
|
||||
sidebarControllerRegistry.set(layout, controller);
|
||||
|
||||
const storedCollapsed = loadSidebarCollapsedState(storageKey);
|
||||
applyCollapsedState(storedCollapsed == null ? DEFAULT_DATASET_ENTRY_COLLAPSED : storedCollapsed, false);
|
||||
});
|
||||
|
||||
syncTopbarPanelToggleButton();
|
||||
}
|
||||
|
||||
function initializeDetailPopouts() {
|
||||
@@ -322,6 +420,7 @@
|
||||
|
||||
layout.classList.toggle("layout-detail-collapsed", collapsed);
|
||||
detailPanel.setAttribute("aria-hidden", collapsed ? "true" : "false");
|
||||
syncTopbarPanelToggleButton();
|
||||
|
||||
if (persist) {
|
||||
saveSidebarCollapsedState(detailStorageKey, collapsed);
|
||||
@@ -503,6 +602,7 @@
|
||||
initializeSidebarAutoCollapse();
|
||||
bindTopbarMobileMenu();
|
||||
bindTopbarDropdownInteractions();
|
||||
initializeTopbarPanelToggle();
|
||||
}
|
||||
|
||||
window.TarotChromeUi = {
|
||||
@@ -512,6 +612,7 @@
|
||||
initializeDetailPopouts,
|
||||
initializeSidebarAutoCollapse,
|
||||
bindTopbarMobileMenu,
|
||||
initializeTopbarPanelToggle,
|
||||
setSidebarCollapsed,
|
||||
setDetailCollapsed,
|
||||
showDetailOnly,
|
||||
|
||||
Reference in New Issue
Block a user