improve navbar
This commit is contained in:
@@ -58,10 +58,11 @@ function initDropdowns(navLinks) {
|
||||
|
||||
function closeAll() {
|
||||
if (activeDropdown) {
|
||||
const btn = activeDropdown.querySelector(".nav-dd-group-btn");
|
||||
const btn = activeDropdown._activeBtn || activeDropdown.querySelector(".nav-dd-group-btn, .user-actions-trigger");
|
||||
const menu = activeDropdown.querySelector(".nav-dd-menu");
|
||||
if (btn) btn.setAttribute("aria-expanded", "false");
|
||||
if (menu) menu.classList.remove("nav-dd-open");
|
||||
activeDropdown._activeBtn = null;
|
||||
activeDropdown = null;
|
||||
}
|
||||
}
|
||||
@@ -80,7 +81,7 @@ function initDropdowns(navLinks) {
|
||||
return;
|
||||
}
|
||||
const menu = wrapper.querySelector(".nav-dd-menu");
|
||||
const btn = wrapper.querySelector(".nav-dd-group-btn");
|
||||
const btn = wrapper.querySelector(".nav-dd-group-btn, .user-actions-trigger");
|
||||
if (!menu || !btn) return;
|
||||
|
||||
e.preventDefault();
|
||||
@@ -93,6 +94,7 @@ function initDropdowns(navLinks) {
|
||||
btn.setAttribute("aria-expanded", "true");
|
||||
menu.classList.add("nav-dd-open");
|
||||
activeDropdown = wrapper;
|
||||
activeDropdown._activeBtn = btn;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -109,6 +111,28 @@ function initDropdowns(navLinks) {
|
||||
});
|
||||
}
|
||||
|
||||
/* ──────────────────────────────────────────────
|
||||
NOTIFY BADGE MIRROR (utility dropdown)
|
||||
────────────────────────────────────────────── */
|
||||
|
||||
function initNotifyBadgeMirror(scope) {
|
||||
if (!scope) return;
|
||||
const badge = scope.querySelector("#notify-badge");
|
||||
const dot = scope.querySelector("#user-actions-dot");
|
||||
if (!badge || !dot) return;
|
||||
|
||||
const sync = () => {
|
||||
const visible = !badge.classList.contains("hidden");
|
||||
dot.classList.toggle("hidden", !visible);
|
||||
};
|
||||
|
||||
sync();
|
||||
new MutationObserver(sync).observe(badge, {
|
||||
attributes: true,
|
||||
attributeFilter: ["class"],
|
||||
});
|
||||
}
|
||||
|
||||
/* ──────────────────────────────────────────────
|
||||
SIDEBAR TREE EXPAND / COLLAPSE
|
||||
────────────────────────────────────────────── */
|
||||
@@ -141,107 +165,18 @@ function initSidebarTree(navLinks) {
|
||||
────────────────────────────────────────────── */
|
||||
|
||||
function createTopbarController(host, refs) {
|
||||
const { toggle, panel, navLinks, navUtility } = refs;
|
||||
if (!toggle || !panel || !navLinks || !navUtility) {
|
||||
const { panel, navLinks, navUtility } = refs;
|
||||
if (!panel || !navLinks || !navUtility) {
|
||||
return { applyAdaptiveNavLayout: () => {} };
|
||||
}
|
||||
|
||||
// Init dropdowns
|
||||
// Dropdowns + notify-badge mirror; layout itself is pure CSS now.
|
||||
initDropdowns(navLinks);
|
||||
initDropdowns(navUtility);
|
||||
initNotifyBadgeMirror(navUtility);
|
||||
|
||||
const navOverflows = () =>
|
||||
panel.scrollWidth > panel.clientWidth + 1 || host.scrollWidth > host.clientWidth + 1;
|
||||
|
||||
function resetInlineStyles() {
|
||||
panel.style.display = "";
|
||||
panel.style.flexDirection = "";
|
||||
panel.style.alignItems = "";
|
||||
panel.style.gap = "";
|
||||
navLinks.style.flexDirection = "";
|
||||
navLinks.style.flexWrap = "";
|
||||
navLinks.style.alignItems = "";
|
||||
navLinks.style.justifyContent = "";
|
||||
navUtility.style.display = "";
|
||||
navUtility.style.width = "";
|
||||
navUtility.style.justifyContent = "";
|
||||
navUtility.style.flexWrap = "";
|
||||
}
|
||||
|
||||
function applyAdaptiveNavLayout() {
|
||||
if (window.innerWidth < MOBILE_BP) {
|
||||
host.dataset.navMode = "mobile";
|
||||
panel.classList.add("hidden");
|
||||
resetInlineStyles();
|
||||
panel.dataset.open = "false";
|
||||
toggle.style.display = "";
|
||||
toggle.setAttribute("aria-expanded", "false");
|
||||
return;
|
||||
}
|
||||
|
||||
host.dataset.navMode = "desktop";
|
||||
panel.classList.remove("hidden");
|
||||
panel.style.display = "flex";
|
||||
panel.dataset.open = "true";
|
||||
navUtility.style.display = "flex";
|
||||
toggle.style.display = "none";
|
||||
toggle.setAttribute("aria-expanded", "false");
|
||||
|
||||
if (navOverflows()) {
|
||||
host.dataset.navMode = "desktop-compact";
|
||||
navUtility.style.display = "none";
|
||||
if (navOverflows()) {
|
||||
host.dataset.navMode = "compact";
|
||||
panel.style.display = "none";
|
||||
panel.dataset.open = "false";
|
||||
toggle.style.display = "inline-flex";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function openCompactPanel() {
|
||||
panel.dataset.open = "true";
|
||||
panel.classList.remove("hidden");
|
||||
panel.style.display = "flex";
|
||||
panel.style.flexDirection = "column";
|
||||
panel.style.alignItems = "stretch";
|
||||
panel.style.gap = "10px";
|
||||
navLinks.style.flexDirection = "row";
|
||||
navLinks.style.flexWrap = "wrap";
|
||||
navLinks.style.alignItems = "center";
|
||||
navLinks.style.justifyContent = "flex-start";
|
||||
navUtility.style.display = "flex";
|
||||
navUtility.style.width = "100%";
|
||||
navUtility.style.justifyContent = "space-between";
|
||||
navUtility.style.flexWrap = "wrap";
|
||||
toggle.setAttribute("aria-expanded", "true");
|
||||
}
|
||||
|
||||
function closeCompactPanel() {
|
||||
panel.dataset.open = "false";
|
||||
panel.style.display = "none";
|
||||
if (host.dataset.navMode === "mobile") panel.classList.add("hidden");
|
||||
toggle.setAttribute("aria-expanded", "false");
|
||||
}
|
||||
|
||||
toggle.addEventListener("click", () => {
|
||||
const compact =
|
||||
host.dataset.navMode === "compact" || host.dataset.navMode === "mobile";
|
||||
if (!compact) return;
|
||||
if (panel.dataset.open === "true") {
|
||||
closeCompactPanel();
|
||||
} else {
|
||||
openCompactPanel();
|
||||
}
|
||||
});
|
||||
|
||||
let resizeRaf = null;
|
||||
window.addEventListener("resize", () => {
|
||||
if (resizeRaf) cancelAnimationFrame(resizeRaf);
|
||||
resizeRaf = requestAnimationFrame(applyAdaptiveNavLayout);
|
||||
});
|
||||
|
||||
applyAdaptiveNavLayout();
|
||||
return { applyAdaptiveNavLayout };
|
||||
host.dataset.navMode = "desktop";
|
||||
return { applyAdaptiveNavLayout: () => {} };
|
||||
}
|
||||
|
||||
/* ──────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user