improve dashboard nav bar view
This commit is contained in:
@@ -4485,6 +4485,26 @@ body.sb-open #sb-backdrop { display: block; }
|
||||
justify-self: start;
|
||||
min-width: 0;
|
||||
}
|
||||
.topbar-nav-toggle {
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
border-radius: 999px;
|
||||
background: rgba(14, 165, 233, 0.12);
|
||||
border: 1px solid rgba(56, 189, 248, 0.28);
|
||||
color: #7dd3fc;
|
||||
cursor: pointer;
|
||||
flex: 0 0 auto;
|
||||
transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
|
||||
}
|
||||
.topbar-nav-toggle:hover,
|
||||
.topbar-nav-toggle[aria-expanded="true"] {
|
||||
background: rgba(14, 165, 233, 0.2);
|
||||
color: #bae6fd;
|
||||
border-color: rgba(125, 211, 252, 0.48);
|
||||
}
|
||||
.topbar-center {
|
||||
grid-area: center;
|
||||
display: flex;
|
||||
@@ -4502,6 +4522,99 @@ body.sb-open #sb-backdrop { display: block; }
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
body.topbar-compact #top-nav {
|
||||
position: sticky;
|
||||
overflow: visible;
|
||||
}
|
||||
body.topbar-compact .topbar-grid {
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
grid-template-areas: "left right";
|
||||
position: relative;
|
||||
}
|
||||
body.topbar-compact .topbar-left {
|
||||
max-width: 100%;
|
||||
}
|
||||
body.topbar-compact .topbar-right {
|
||||
flex: 0 0 auto;
|
||||
min-width: max-content;
|
||||
}
|
||||
body.topbar-compact .topbar-nav-toggle {
|
||||
display: inline-flex;
|
||||
}
|
||||
body.topbar-compact .topbar-center {
|
||||
position: absolute;
|
||||
top: calc(100% + 10px);
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: none;
|
||||
justify-self: stretch;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
background: rgba(8, 13, 28, 0.98);
|
||||
border: 1px solid rgba(51, 65, 85, 0.82);
|
||||
box-shadow: 0 18px 42px rgba(0, 0, 0, 0.5);
|
||||
z-index: 230;
|
||||
max-height: min(68vh, 520px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
body.topbar-compact.topbar-menu-open .topbar-center {
|
||||
display: flex;
|
||||
}
|
||||
body.topbar-compact .nav-dd-bar {
|
||||
justify-content: flex-start;
|
||||
flex-wrap: nowrap;
|
||||
align-items: stretch;
|
||||
gap: 6px;
|
||||
width: 100%;
|
||||
padding-top: 0;
|
||||
flex-direction: column;
|
||||
}
|
||||
body.topbar-compact .nav-dd-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
body.topbar-compact .nav-dd-group-btn {
|
||||
width: 100%;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
body.topbar-compact .nav-dd-group-btn i.fa-chevron-down {
|
||||
margin-left: auto;
|
||||
}
|
||||
body.topbar-compact .nav-dd-menu {
|
||||
position: static;
|
||||
display: none;
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
margin-top: 6px;
|
||||
transform: none;
|
||||
box-shadow: none;
|
||||
border-radius: 8px;
|
||||
background: rgba(2, 8, 22, 0.55);
|
||||
border-color: rgba(51, 65, 85, 0.45);
|
||||
}
|
||||
body.topbar-compact .nav-dd-menu.nav-dd-open {
|
||||
display: flex;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
pointer-events: auto;
|
||||
transform: none;
|
||||
}
|
||||
body.topbar-compact #account-settings-btn {
|
||||
flex: 0 0 auto;
|
||||
max-width: none;
|
||||
min-width: max-content;
|
||||
}
|
||||
body.topbar-compact #username-display {
|
||||
max-width: none;
|
||||
overflow: visible;
|
||||
text-overflow: clip;
|
||||
white-space: nowrap;
|
||||
}
|
||||
body.topbar-compact #role-badge {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.topbar-grid {
|
||||
grid-template-columns: 1fr auto;
|
||||
|
||||
@@ -165,7 +165,7 @@ function initSidebarTree(navLinks) {
|
||||
────────────────────────────────────────────── */
|
||||
|
||||
function createTopbarController(host, refs) {
|
||||
const { panel, navLinks, navUtility } = refs;
|
||||
const { panel, navLinks, navUtility, topbarToggle } = refs;
|
||||
if (!panel || !navLinks || !navUtility) {
|
||||
return { applyAdaptiveNavLayout: () => {} };
|
||||
}
|
||||
@@ -175,8 +175,105 @@ function createTopbarController(host, refs) {
|
||||
initDropdowns(navUtility);
|
||||
initNotifyBadgeMirror(navUtility);
|
||||
|
||||
const grid = host.querySelector(".topbar-grid");
|
||||
const left = host.querySelector(".topbar-left");
|
||||
let compact = false;
|
||||
let layoutFrame = 0;
|
||||
|
||||
const closeCompactMenu = () => {
|
||||
document.body.classList.remove("topbar-menu-open");
|
||||
topbarToggle?.setAttribute("aria-expanded", "false");
|
||||
};
|
||||
|
||||
const setCompact = (next) => {
|
||||
if (compact === next) return;
|
||||
compact = next;
|
||||
document.body.classList.toggle("topbar-compact", next);
|
||||
host.dataset.navMode = next ? "compact" : "desktop";
|
||||
if (!next) closeCompactMenu();
|
||||
};
|
||||
|
||||
const measureDesktopWidth = () => {
|
||||
const wasCompact = document.body.classList.contains("topbar-compact");
|
||||
const wasOpen = document.body.classList.contains("topbar-menu-open");
|
||||
if (wasCompact) {
|
||||
document.body.classList.remove("topbar-compact", "topbar-menu-open");
|
||||
}
|
||||
|
||||
const style = getComputedStyle(host);
|
||||
const horizontalPadding = parseFloat(style.paddingLeft || "0") + parseFloat(style.paddingRight || "0");
|
||||
const gridGap = grid ? parseFloat(getComputedStyle(grid).columnGap || "0") || 0 : 0;
|
||||
const navGap = parseFloat(getComputedStyle(navLinks).columnGap || getComputedStyle(navLinks).gap || "0") || 0;
|
||||
const visibleNavItems = Array.from(navLinks.children).filter((el) => {
|
||||
const itemStyle = getComputedStyle(el);
|
||||
return itemStyle.display !== "none" && !el.classList.contains("hidden");
|
||||
});
|
||||
const navWidth = visibleNavItems.reduce((sum, el) => sum + el.getBoundingClientRect().width, 0) +
|
||||
Math.max(0, visibleNavItems.length - 1) * navGap;
|
||||
const requiredWidth =
|
||||
(left?.scrollWidth || 0) +
|
||||
navWidth +
|
||||
(navUtility?.scrollWidth || 0) +
|
||||
(gridGap * 2) +
|
||||
horizontalPadding +
|
||||
24;
|
||||
|
||||
if (wasCompact) {
|
||||
document.body.classList.add("topbar-compact");
|
||||
document.body.classList.toggle("topbar-menu-open", wasOpen);
|
||||
}
|
||||
return requiredWidth;
|
||||
};
|
||||
|
||||
const applyAdaptiveNavLayout = () => {
|
||||
const availableWidth = host.clientWidth || window.innerWidth;
|
||||
const requiredWidth = measureDesktopWidth();
|
||||
const shouldCompact = requiredWidth > availableWidth;
|
||||
setCompact(shouldCompact);
|
||||
};
|
||||
|
||||
const scheduleAdaptiveNavLayout = () => {
|
||||
if (layoutFrame) return;
|
||||
layoutFrame = requestAnimationFrame(() => {
|
||||
layoutFrame = 0;
|
||||
applyAdaptiveNavLayout();
|
||||
});
|
||||
};
|
||||
|
||||
topbarToggle?.addEventListener("click", (event) => {
|
||||
event.stopPropagation();
|
||||
const nextOpen = !document.body.classList.contains("topbar-menu-open");
|
||||
document.body.classList.toggle("topbar-menu-open", nextOpen);
|
||||
topbarToggle.setAttribute("aria-expanded", String(nextOpen));
|
||||
});
|
||||
|
||||
document.addEventListener("click", (event) => {
|
||||
if (!compact) return;
|
||||
if (event.target.closest("#top-nav")) return;
|
||||
closeCompactMenu();
|
||||
});
|
||||
|
||||
document.addEventListener("keydown", (event) => {
|
||||
if (event.key === "Escape") closeCompactMenu();
|
||||
});
|
||||
|
||||
navLinks.addEventListener("click", (event) => {
|
||||
if (event.target.closest("a[href]")) closeCompactMenu();
|
||||
});
|
||||
|
||||
window.addEventListener("resize", scheduleAdaptiveNavLayout);
|
||||
|
||||
if ("ResizeObserver" in window) {
|
||||
const resizeObserver = new ResizeObserver(scheduleAdaptiveNavLayout);
|
||||
resizeObserver.observe(host);
|
||||
resizeObserver.observe(navLinks);
|
||||
resizeObserver.observe(navUtility);
|
||||
}
|
||||
|
||||
scheduleAdaptiveNavLayout();
|
||||
|
||||
host.dataset.navMode = "desktop";
|
||||
return { applyAdaptiveNavLayout: () => {} };
|
||||
return { applyAdaptiveNavLayout };
|
||||
}
|
||||
|
||||
/* ──────────────────────────────────────────────
|
||||
|
||||
@@ -136,6 +136,9 @@ function mountTopbar(host) {
|
||||
<a href="/" class="flex items-center gap-2 font-semibold tracking-wide">
|
||||
<i class="fa-solid fa-crown header-crown"></i> Overlord
|
||||
</a>
|
||||
<button id="topbar-nav-toggle" class="topbar-nav-toggle" aria-label="Open navigation menu" aria-expanded="false" type="button">
|
||||
<i class="fa-solid fa-layer-group"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
id="nav-panel"
|
||||
@@ -186,6 +189,7 @@ function mountTopbar(host) {
|
||||
// Collect all link refs
|
||||
const refs = {
|
||||
toggle: null,
|
||||
topbarToggle: document.getElementById("topbar-nav-toggle"),
|
||||
panel: document.getElementById("nav-panel"),
|
||||
collapseBtn: null,
|
||||
navLinks: document.getElementById("nav-links"),
|
||||
|
||||
Reference in New Issue
Block a user