From f4b40e0d97da56f1b7434b8190a5ab9c1ab3f538 Mon Sep 17 00:00:00 2001 From: litruv Date: Sun, 2 Aug 2026 21:30:35 +1000 Subject: [PATCH] Improve mobile chrome for the slatehtml docs shell. Show a top bar with menu/logo/title when the nav drawer is active, hide the outline at the same breakpoint, fix the FA hamburger icon, and use a message glyph for Discord socials. --- src/app.js | 23 +++++-- src/widgets/slate-docs-viewer.umc | 104 +++++++++++++++++++++--------- 2 files changed, 92 insertions(+), 35 deletions(-) diff --git a/src/app.js b/src/app.js index d9c96c2..bf09de8 100644 --- a/src/app.js +++ b/src/app.js @@ -52,6 +52,7 @@ export class DocsApp { articleScroll: () => host.querySelector("[data-docs-article-scroll]"), siteName: () => host.querySelector("[data-docs-site-name]"), authorRole: () => host.querySelector("[data-docs-author-role]"), + pageTitle: () => host.querySelector("[data-docs-page-title]"), socials: () => host.querySelector("[data-docs-socials]"), search: () => host.querySelector("[data-docs-search]"), searchPanel: () => host.querySelector("[data-docs-search-panel]"), @@ -156,16 +157,23 @@ export class DocsApp { if (siteEl) siteEl.setAttribute("text", site); document.title = site; - const logo = this.host.querySelector("[data-docs-logo]"); - if (logo) { + const logoUrl = (data.metadata?.logo || this.host.getAttribute("logo") || "./img/logo.png").trim(); + for (const logo of this.host.querySelectorAll("[data-docs-logo], [data-docs-logo-top]")) { logo.setAttribute("alt", site); - const logoUrl = (data.metadata?.logo || this.host.getAttribute("logo") || "./img/logo.png").trim(); if (logoUrl) { logo.setAttribute("src", logoUrl); logo.removeAttribute("hidden"); - siteEl?.setAttribute("hidden", ""); + } else { + logo.setAttribute("hidden", ""); } } + if (logoUrl) siteEl?.setAttribute("hidden", ""); + else siteEl?.removeAttribute("hidden"); + + const pageTitle = this.$.pageTitle(); + if (pageTitle && !pageTitle.getAttribute("text")) { + pageTitle.setAttribute("text", site); + } const role = this.$.authorRole(); if (role) { @@ -176,7 +184,11 @@ export class DocsApp { const socials = this.$.socials(); if (socials) { const entries = (data.author?.socials || []).map((s) => { - const icon = faClassToIconName(s.icon); + let icon = faClassToIconName(s.icon); + // Prefer a generic message glyph over the Discord brand mark. + if (/discord/i.test(String(s.icon || "")) || /discord/i.test(String(s.url || ""))) { + icon = "fas:message"; + } const label = shortSocialLabel(s.title || s.url || "link"); // value carries the URL so selection can open it return `${encodeURIComponent(s.url)}|${label}|${icon}`; @@ -238,6 +250,7 @@ export class DocsApp { md.setAttribute("content", content); } document.title = `${title} ยท ${this.indexData?.metadata?.site_name || "Docs"}`; + this.$.pageTitle()?.setAttribute("text", title || "Documentation"); const fromPath = findSlugByPath(this.indexData?.documents || [], path); this.$.nav()?.setAttribute("selected", fromPath || slug || ""); diff --git a/src/widgets/slate-docs-viewer.umc b/src/widgets/slate-docs-viewer.umc index 2dda749..b66e137 100644 --- a/src/widgets/slate-docs-viewer.umc +++ b/src/widgets/slate-docs-viewer.umc @@ -19,7 +19,7 @@ tabindex="0" aria-label="Close navigation" > - + @@ -55,6 +55,27 @@ + + + + + + + + @@ -73,26 +94,12 @@ - - - - @@ -151,18 +158,49 @@ self:has(#docs-viewer-sidebar[layout="drawer"][open]) .docs-viewer-menu { display: block; /* umc-layout-ok */ } -.docs-viewer-menu-fab { - --widget-background: var(--panel); - --widget-border: 1px solid var(--line); - --widget-radius: 8px; - cursor: pointer; - z-index: 15; /* umc-layout-ok */ - display: none; /* umc-layout-ok */ - box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35); +.docs-viewer-topbar { + flex: 0 0 auto; /* umc-layout-ok */ + display: none; /* umc-layout-ok โ€” mobile / drawer only */ + background: var(--panel); + border-bottom: 1px solid var(--line); + box-sizing: border-box; } -self:has(#docs-viewer-sidebar[layout="drawer"]:not([open])) .docs-viewer-menu-fab { +self:has(#docs-viewer-sidebar[layout="drawer"]) .docs-viewer-topbar { + display: flex; /* umc-layout-ok */ +} + +.docs-viewer-topbar-menu { + --widget-background: transparent; + --widget-border: none; + cursor: pointer; + flex: 0 0 auto; /* umc-layout-ok */ +} + +.docs-viewer-topbar-logo { display: block; /* umc-layout-ok */ + height: 24px; /* umc-layout-ok โ€” OG .brand-logo */ + width: auto; /* umc-layout-ok */ + object-fit: contain; + flex: 0 0 auto; /* umc-layout-ok */ +} + +.docs-viewer-topbar-logo[hidden] { + display: none !important; +} + +.docs-viewer-topbar-divider { + color: var(--muted); + font-size: 0.9rem; + flex: 0 0 auto; /* umc-layout-ok */ +} + +.docs-viewer-topbar-title { + font-size: 0.9rem; + min-width: 0; /* umc-layout-ok */ + overflow: hidden; /* umc-layout-ok */ + text-overflow: ellipsis; + white-space: nowrap; } .docs-viewer-logo { @@ -193,6 +231,12 @@ self:has(#docs-viewer-sidebar[layout="drawer"]:not([open])) .docs-viewer-menu-fa background: var(--bg, #1a1a1a); } +/* Drop the outline with the nav drawer (same breakpoint) โ€” no outline drawer. */ +self:has(#docs-viewer-sidebar[layout="drawer"]) .docs-viewer-outline-rail, +.docs-viewer-outline-rail[layout="drawer"] { + display: none !important; +} + .docs-viewer-outline-rail .slate-sidebar-panel { --widget-background: var(--bg, #1a1a1a); background: var(--bg, #1a1a1a); @@ -316,7 +360,7 @@ self:has(#docs-viewer-sidebar[layout="drawer"]:not([open])) .docs-viewer-menu-fa .docs-viewer-nav, .docs-viewer-outline-rail, .docs-viewer-menu, - .docs-viewer-menu-fab, + .docs-viewer-topbar, .docs-viewer-search-block, .docs-viewer-footer, .docs-viewer-progress-wrap { @@ -352,18 +396,18 @@ export default defineUmc({ SynchronizeProperties(el) { const logoUrl = (el.getAttribute("logo") || "./img/logo.png").trim(); - const img = el.querySelector("[data-docs-logo]"); + const imgs = el.querySelectorAll("[data-docs-logo], [data-docs-logo-top]"); const text = el.querySelector("[data-docs-site-name]"); - if (img) { + for (const img of imgs) { if (logoUrl) { img.setAttribute("src", logoUrl); img.removeAttribute("hidden"); - text?.setAttribute("hidden", ""); } else { img.setAttribute("hidden", ""); - text?.removeAttribute("hidden"); } } + if (logoUrl) text?.setAttribute("hidden", ""); + else text?.removeAttribute("hidden"); }, });