mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2026-08-09 17:41:14 +10:00
fix(docs): add mobile navigation to the splash homepage (#4904)
The homepage uses Starlight's splash template, which has no sidebar and therefore never gets Starlight's own mobile menu toggle - on narrow viewports there was no way to reach any nav link at all. Add a small toggle + panel in the header (only rendered on pages without a sidebar) exposing the same links as the desktop nav, and group it with the search icon so mobile actions sit together instead of spread across the header. Also add the Store and Forums links to the real sidebar config so they're reachable on mobile on every other page too (previously only in the desktop-only top nav), and pull both URLs from a shared site-links.ts so the sidebar config and header can't drift apart.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import starlight from '@astrojs/starlight';
|
||||
import { siteLinks } from './src/site-links.ts';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
@@ -59,8 +60,10 @@ export default defineConfig({
|
||||
{ label: 'FAQ', slug: 'faq' },
|
||||
{ label: 'Known Issues', slug: 'knownissues' },
|
||||
{ label: 'Contributing', slug: 'contributing' },
|
||||
{ label: siteLinks.forums.label, link: siteLinks.forums.href, attrs: { target: '_blank', rel: 'noreferrer' } },
|
||||
],
|
||||
},
|
||||
{ label: siteLinks.store.label, link: siteLinks.store.href, attrs: { target: '_blank', rel: 'noreferrer' } },
|
||||
],
|
||||
}),
|
||||
],
|
||||
|
||||
@@ -6,10 +6,15 @@ import Search from 'virtual:starlight/components/Search';
|
||||
import SiteTitle from 'virtual:starlight/components/SiteTitle';
|
||||
import SocialIcons from 'virtual:starlight/components/SocialIcons';
|
||||
import ThemeSelect from 'virtual:starlight/components/ThemeSelect';
|
||||
import { Icon } from '@astrojs/starlight/components';
|
||||
import { siteLinks } from '../site-links';
|
||||
|
||||
// Render the `Search` component if Pagefind is enabled or the default search component has been overridden.
|
||||
const shouldRenderSearch =
|
||||
config.pagefind || config.components.Search !== '@astrojs/starlight/components/Search.astro';
|
||||
|
||||
// Pages with a sidebar already have Starlight's own mobile menu toggle; only splash pages need this one.
|
||||
const { hasSidebar } = Astro.locals.starlightRoute;
|
||||
---
|
||||
|
||||
<div class="header">
|
||||
@@ -17,9 +22,36 @@ const shouldRenderSearch =
|
||||
<div class="title-wrapper sl-flex">
|
||||
<SiteTitle />
|
||||
</div>
|
||||
{/* Search box. */}
|
||||
<div class="sl-flex print:hidden">
|
||||
{shouldRenderSearch && <Search />}
|
||||
<div class="mobile-actions sl-flex">
|
||||
{/* Search box. */}
|
||||
<div class="sl-flex print:hidden">
|
||||
{shouldRenderSearch && <Search />}
|
||||
</div>
|
||||
{
|
||||
!hasSidebar && (
|
||||
<div class="site-nav-toggle sl-flex md:sl-hidden print:hidden">
|
||||
<button type="button" aria-expanded="false" aria-controls="site-nav-panel" aria-label="Site navigation">
|
||||
<Icon name="bars" class="open-menu" />
|
||||
<Icon name="close" class="close-menu" />
|
||||
</button>
|
||||
<div id="site-nav-panel" class="site-nav-panel">
|
||||
<div class="site-nav-panel-group">
|
||||
<p class="site-nav-panel-heading">Documentation</p>
|
||||
<a href="/guides/">User Guides</a>
|
||||
<a href="/contributing/">Contribution Guides</a>
|
||||
<a href="/code-reference/architecture/">Code Reference</a>
|
||||
</div>
|
||||
<div class="site-nav-panel-group">
|
||||
<p class="site-nav-panel-heading">Help</p>
|
||||
<a href="/faq/">FAQ</a>
|
||||
<a href="/knownissues/">Known Issues</a>
|
||||
<a href={siteLinks.forums.href} target="_blank" rel="noreferrer">{siteLinks.forums.label}</a>
|
||||
</div>
|
||||
<a class="site-nav-panel-link" href={siteLinks.store.href} target="_blank" rel="noreferrer">{siteLinks.store.label}</a>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
{/* Right-side group: nav links, social icons, theme/language pickers. */}
|
||||
<div class="sl-hidden md:sl-flex print:hidden right-group">
|
||||
@@ -43,10 +75,10 @@ const shouldRenderSearch =
|
||||
<div class="site-nav-menu">
|
||||
<a href="/faq/">FAQ</a>
|
||||
<a href="/knownissues/">Known Issues</a>
|
||||
<a href="https://forum.christitus.com/" target="_blank" rel="noreferrer">Forums</a>
|
||||
<a href={siteLinks.forums.href} target="_blank" rel="noreferrer">{siteLinks.forums.label}</a>
|
||||
</div>
|
||||
</div>
|
||||
<a class="site-nav-link" href="https://christitus.com/downloads/" target="_blank" rel="noreferrer">Store</a>
|
||||
<a class="site-nav-link" href={siteLinks.store.href} target="_blank" rel="noreferrer">{siteLinks.store.label}</a>
|
||||
</nav>
|
||||
<div class="sl-flex social-icons">
|
||||
<SocialIcons />
|
||||
@@ -56,6 +88,25 @@ const shouldRenderSearch =
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const toggle = document.querySelector<HTMLElement>('.site-nav-toggle');
|
||||
const btn = toggle?.querySelector('button');
|
||||
|
||||
if (toggle && btn) {
|
||||
const setExpanded = (expanded: boolean) => btn.setAttribute('aria-expanded', String(expanded));
|
||||
|
||||
btn.addEventListener('click', () => setExpanded(btn.getAttribute('aria-expanded') !== 'true'));
|
||||
toggle.addEventListener('keyup', (e) => {
|
||||
if (e.code === 'Escape') {
|
||||
setExpanded(false);
|
||||
btn.focus();
|
||||
}
|
||||
});
|
||||
// Collapse the panel if the viewport grows past the mobile breakpoint.
|
||||
matchMedia('(min-width: 50em)').addEventListener('change', () => setExpanded(false));
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@layer starlight.core {
|
||||
/* Header shell: title, search, right-side nav group. */
|
||||
@@ -75,6 +126,11 @@ const shouldRenderSearch =
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.mobile-actions {
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
/* Right-side group: nav + social icons, divided by a hairline. */
|
||||
.right-group,
|
||||
.social-icons {
|
||||
@@ -194,4 +250,82 @@ const shouldRenderSearch =
|
||||
color: var(--sl-color-white);
|
||||
background: var(--sl-color-gray-6);
|
||||
}
|
||||
|
||||
/* Mobile equivalent of the site-nav, shown via a toggle button since the desktop nav is hidden below `md`. */
|
||||
.site-nav-toggle button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
border: 0;
|
||||
border-radius: var(--wu-radius-sm, 0.5rem);
|
||||
padding: 0;
|
||||
background: none;
|
||||
color: var(--sl-color-gray-2);
|
||||
cursor: pointer;
|
||||
}
|
||||
.site-nav-toggle button:hover {
|
||||
color: var(--sl-color-white);
|
||||
}
|
||||
.site-nav-toggle button svg {
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
}
|
||||
.site-nav-toggle button[aria-expanded='true'] .open-menu,
|
||||
.site-nav-toggle button:not([aria-expanded='true']) .close-menu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.site-nav-panel {
|
||||
display: none;
|
||||
position: fixed;
|
||||
inset-inline: 0;
|
||||
top: var(--sl-nav-height);
|
||||
z-index: var(--sl-z-index-menu);
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
max-height: calc(100vh - var(--sl-nav-height));
|
||||
overflow-y: auto;
|
||||
padding: 1rem var(--sl-nav-pad-x) 1.5rem;
|
||||
background: var(--sl-color-bg-nav);
|
||||
border-bottom: 1px solid var(--sl-color-hairline-shade);
|
||||
}
|
||||
.site-nav-toggle button[aria-expanded='true'] ~ .site-nav-panel {
|
||||
display: flex;
|
||||
}
|
||||
.site-nav-panel-link {
|
||||
padding: 0.5rem 0.25rem;
|
||||
font-size: var(--sl-text-sm);
|
||||
font-weight: 500;
|
||||
color: var(--sl-color-gray-2);
|
||||
text-decoration: none;
|
||||
}
|
||||
.site-nav-panel-link:hover {
|
||||
color: var(--sl-color-white);
|
||||
}
|
||||
.site-nav-panel-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-top: 1px solid var(--sl-color-hairline-light);
|
||||
padding-top: 0.5rem;
|
||||
}
|
||||
.site-nav-panel-heading {
|
||||
margin: 0 0 0.25rem;
|
||||
padding: 0 0.25rem;
|
||||
font-size: var(--sl-text-xs);
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.02em;
|
||||
color: var(--sl-color-gray-3);
|
||||
}
|
||||
.site-nav-panel-group a {
|
||||
padding: 0.5rem 0.25rem;
|
||||
font-size: var(--sl-text-sm);
|
||||
color: var(--sl-color-gray-2);
|
||||
text-decoration: none;
|
||||
}
|
||||
.site-nav-panel-group a:hover {
|
||||
color: var(--sl-color-white);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// Shared external links, so astro.config.mjs and Header.astro can't drift out of sync.
|
||||
export const siteLinks = {
|
||||
store: { label: 'Store', href: 'https://christitus.com/downloads/' },
|
||||
forums: { label: 'Forums', href: 'https://forum.christitus.com/' },
|
||||
} as const;
|
||||
Reference in New Issue
Block a user