mirror of
https://github.com/litruv/Docs-Viewer.git
synced 2026-09-10 01:59:44 +10:00
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.
This commit is contained in:
23
src/app.js
23
src/app.js
@@ -52,6 +52,7 @@ export class DocsApp {
|
|||||||
articleScroll: () => host.querySelector("[data-docs-article-scroll]"),
|
articleScroll: () => host.querySelector("[data-docs-article-scroll]"),
|
||||||
siteName: () => host.querySelector("[data-docs-site-name]"),
|
siteName: () => host.querySelector("[data-docs-site-name]"),
|
||||||
authorRole: () => host.querySelector("[data-docs-author-role]"),
|
authorRole: () => host.querySelector("[data-docs-author-role]"),
|
||||||
|
pageTitle: () => host.querySelector("[data-docs-page-title]"),
|
||||||
socials: () => host.querySelector("[data-docs-socials]"),
|
socials: () => host.querySelector("[data-docs-socials]"),
|
||||||
search: () => host.querySelector("[data-docs-search]"),
|
search: () => host.querySelector("[data-docs-search]"),
|
||||||
searchPanel: () => host.querySelector("[data-docs-search-panel]"),
|
searchPanel: () => host.querySelector("[data-docs-search-panel]"),
|
||||||
@@ -156,16 +157,23 @@ export class DocsApp {
|
|||||||
if (siteEl) siteEl.setAttribute("text", site);
|
if (siteEl) siteEl.setAttribute("text", site);
|
||||||
document.title = site;
|
document.title = site;
|
||||||
|
|
||||||
const logo = this.host.querySelector("[data-docs-logo]");
|
const logoUrl = (data.metadata?.logo || this.host.getAttribute("logo") || "./img/logo.png").trim();
|
||||||
if (logo) {
|
for (const logo of this.host.querySelectorAll("[data-docs-logo], [data-docs-logo-top]")) {
|
||||||
logo.setAttribute("alt", site);
|
logo.setAttribute("alt", site);
|
||||||
const logoUrl = (data.metadata?.logo || this.host.getAttribute("logo") || "./img/logo.png").trim();
|
|
||||||
if (logoUrl) {
|
if (logoUrl) {
|
||||||
logo.setAttribute("src", logoUrl);
|
logo.setAttribute("src", logoUrl);
|
||||||
logo.removeAttribute("hidden");
|
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();
|
const role = this.$.authorRole();
|
||||||
if (role) {
|
if (role) {
|
||||||
@@ -176,7 +184,11 @@ export class DocsApp {
|
|||||||
const socials = this.$.socials();
|
const socials = this.$.socials();
|
||||||
if (socials) {
|
if (socials) {
|
||||||
const entries = (data.author?.socials || []).map((s) => {
|
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");
|
const label = shortSocialLabel(s.title || s.url || "link");
|
||||||
// value carries the URL so selection can open it
|
// value carries the URL so selection can open it
|
||||||
return `${encodeURIComponent(s.url)}|${label}|${icon}`;
|
return `${encodeURIComponent(s.url)}|${label}|${icon}`;
|
||||||
@@ -238,6 +250,7 @@ export class DocsApp {
|
|||||||
md.setAttribute("content", content);
|
md.setAttribute("content", content);
|
||||||
}
|
}
|
||||||
document.title = `${title} · ${this.indexData?.metadata?.site_name || "Docs"}`;
|
document.title = `${title} · ${this.indexData?.metadata?.site_name || "Docs"}`;
|
||||||
|
this.$.pageTitle()?.setAttribute("text", title || "Documentation");
|
||||||
|
|
||||||
const fromPath = findSlugByPath(this.indexData?.documents || [], path);
|
const fromPath = findSlugByPath(this.indexData?.documents || [], path);
|
||||||
this.$.nav()?.setAttribute("selected", fromPath || slug || "");
|
this.$.nav()?.setAttribute("selected", fromPath || slug || "");
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
tabindex="0"
|
tabindex="0"
|
||||||
aria-label="Close navigation"
|
aria-label="Close navigation"
|
||||||
>
|
>
|
||||||
<slate-icon name="menu" size="16"></slate-icon>
|
<slate-icon name="bars" size="16"></slate-icon>
|
||||||
</border>
|
</border>
|
||||||
<verticalbox gap="10" fill min-width="0" halign="center">
|
<verticalbox gap="10" fill min-width="0" halign="center">
|
||||||
<img class="docs-viewer-logo-img" data-docs-logo src="./img/logo.png" alt="" />
|
<img class="docs-viewer-logo-img" data-docs-logo src="./img/logo.png" alt="" />
|
||||||
@@ -55,6 +55,27 @@
|
|||||||
|
|
||||||
<canvaspanel class="docs-viewer-main" fill min-width="0" min-height="0">
|
<canvaspanel class="docs-viewer-main" fill min-width="0" min-height="0">
|
||||||
<verticalbox anchors="fill" top="0" left="0" right="0" bottom="0" gap="0">
|
<verticalbox anchors="fill" top="0" left="0" right="0" bottom="0" gap="0">
|
||||||
|
<horizontalbox
|
||||||
|
class="docs-viewer-topbar"
|
||||||
|
gap="10"
|
||||||
|
valign="center"
|
||||||
|
padding="0 12"
|
||||||
|
height="48"
|
||||||
|
>
|
||||||
|
<border
|
||||||
|
class="docs-viewer-topbar-menu"
|
||||||
|
sidebar="docs-viewer-sidebar"
|
||||||
|
padding="6 8"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
aria-label="Open navigation"
|
||||||
|
>
|
||||||
|
<slate-icon name="bars" size="16"></slate-icon>
|
||||||
|
</border>
|
||||||
|
<img class="docs-viewer-topbar-logo" data-docs-logo-top src="./img/logo.png" alt="" />
|
||||||
|
<textblock class="docs-viewer-topbar-divider" text="/"></textblock>
|
||||||
|
<textblock class="docs-viewer-topbar-title" data-docs-page-title text="Documentation" fill></textblock>
|
||||||
|
</horizontalbox>
|
||||||
<border class="docs-viewer-progress-wrap" padding="0" hidden data-docs-progress>
|
<border class="docs-viewer-progress-wrap" padding="0" hidden data-docs-progress>
|
||||||
<slate-progress indeterminate></slate-progress>
|
<slate-progress indeterminate></slate-progress>
|
||||||
</border>
|
</border>
|
||||||
@@ -73,26 +94,12 @@
|
|||||||
</verticalbox>
|
</verticalbox>
|
||||||
</scrollbox>
|
</scrollbox>
|
||||||
</verticalbox>
|
</verticalbox>
|
||||||
|
|
||||||
<border
|
|
||||||
class="docs-viewer-menu-fab"
|
|
||||||
sidebar="docs-viewer-sidebar"
|
|
||||||
anchors="top-left"
|
|
||||||
top="12"
|
|
||||||
left="12"
|
|
||||||
padding="8"
|
|
||||||
role="button"
|
|
||||||
tabindex="0"
|
|
||||||
aria-label="Open navigation"
|
|
||||||
>
|
|
||||||
<slate-icon name="menu" size="18"></slate-icon>
|
|
||||||
</border>
|
|
||||||
</canvaspanel>
|
</canvaspanel>
|
||||||
|
|
||||||
<slate-side-bar
|
<slate-side-bar
|
||||||
class="docs-viewer-outline-rail"
|
class="docs-viewer-outline-rail"
|
||||||
width="240"
|
width="240"
|
||||||
collapse-at="1100"
|
collapse-at="1000"
|
||||||
placement="right"
|
placement="right"
|
||||||
mode="rail"
|
mode="rail"
|
||||||
>
|
>
|
||||||
@@ -151,18 +158,49 @@ self:has(#docs-viewer-sidebar[layout="drawer"][open]) .docs-viewer-menu {
|
|||||||
display: block; /* umc-layout-ok */
|
display: block; /* umc-layout-ok */
|
||||||
}
|
}
|
||||||
|
|
||||||
.docs-viewer-menu-fab {
|
.docs-viewer-topbar {
|
||||||
--widget-background: var(--panel);
|
flex: 0 0 auto; /* umc-layout-ok */
|
||||||
--widget-border: 1px solid var(--line);
|
display: none; /* umc-layout-ok — mobile / drawer only */
|
||||||
--widget-radius: 8px;
|
background: var(--panel);
|
||||||
cursor: pointer;
|
border-bottom: 1px solid var(--line);
|
||||||
z-index: 15; /* umc-layout-ok */
|
box-sizing: border-box;
|
||||||
display: none; /* umc-layout-ok */
|
|
||||||
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 */
|
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 {
|
.docs-viewer-logo {
|
||||||
@@ -193,6 +231,12 @@ self:has(#docs-viewer-sidebar[layout="drawer"]:not([open])) .docs-viewer-menu-fa
|
|||||||
background: var(--bg, #1a1a1a);
|
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 {
|
.docs-viewer-outline-rail .slate-sidebar-panel {
|
||||||
--widget-background: var(--bg, #1a1a1a);
|
--widget-background: var(--bg, #1a1a1a);
|
||||||
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-nav,
|
||||||
.docs-viewer-outline-rail,
|
.docs-viewer-outline-rail,
|
||||||
.docs-viewer-menu,
|
.docs-viewer-menu,
|
||||||
.docs-viewer-menu-fab,
|
.docs-viewer-topbar,
|
||||||
.docs-viewer-search-block,
|
.docs-viewer-search-block,
|
||||||
.docs-viewer-footer,
|
.docs-viewer-footer,
|
||||||
.docs-viewer-progress-wrap {
|
.docs-viewer-progress-wrap {
|
||||||
@@ -352,18 +396,18 @@ export default defineUmc({
|
|||||||
|
|
||||||
SynchronizeProperties(el) {
|
SynchronizeProperties(el) {
|
||||||
const logoUrl = (el.getAttribute("logo") || "./img/logo.png").trim();
|
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]");
|
const text = el.querySelector("[data-docs-site-name]");
|
||||||
if (img) {
|
for (const img of imgs) {
|
||||||
if (logoUrl) {
|
if (logoUrl) {
|
||||||
img.setAttribute("src", logoUrl);
|
img.setAttribute("src", logoUrl);
|
||||||
img.removeAttribute("hidden");
|
img.removeAttribute("hidden");
|
||||||
text?.setAttribute("hidden", "");
|
|
||||||
} else {
|
} else {
|
||||||
img.setAttribute("hidden", "");
|
img.setAttribute("hidden", "");
|
||||||
text?.removeAttribute("hidden");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (logoUrl) text?.setAttribute("hidden", "");
|
||||||
|
else text?.removeAttribute("hidden");
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user