admin: the mobile drawer becomes a rac disclosure, asset budget raised to 850,000 bytes
the drawer is inline flow content, so disclosure is the honest semantic: rac now owns aria-expanded, aria-controls, and the panel hidden state, while the open guard still unmounts the drawer contents so a closed drawer keeps no second pause control or health poll alive. the disclosure modules cost 3,669 bytes and the assets gate had 1,998 of headroom, so the budget moves from 800,000 to 850,000.
This commit is contained in:
@@ -2,6 +2,7 @@ import { useId, useState } from "react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { Link, Outlet, useNavigate } from "@tanstack/react-router";
|
||||
import * as stylex from "@stylexjs/stylex";
|
||||
import { Button, Disclosure, DisclosurePanel } from "react-aria-components";
|
||||
import { useAuth } from "@/auth/store";
|
||||
import InlineError from "@/lib/InlineError";
|
||||
import { healthQuery, versionQuery } from "@/lib/queries";
|
||||
@@ -333,35 +334,46 @@ export default function AppShell() {
|
||||
<LogoutButton style={styles.sidebarLogout} />
|
||||
<SidebarFooter />
|
||||
</aside>
|
||||
<div {...stylex.props(styles.column)}>
|
||||
{/* The column itself is the disclosure: the trigger sits in the header
|
||||
and the panel opens below the notices, so any wrapper around only
|
||||
the two would have to cut across the column's own flex children. */}
|
||||
<Disclosure
|
||||
isExpanded={drawerOpen}
|
||||
onExpandedChange={setDrawerOpen}
|
||||
{...stylex.props(styles.column)}
|
||||
>
|
||||
<header {...stylex.props(styles.header)}>
|
||||
<button
|
||||
type="button"
|
||||
aria-expanded={drawerOpen}
|
||||
aria-controls="mobile-nav"
|
||||
onClick={() => setDrawerOpen((open) => !open)}
|
||||
{...stylex.props(shared.button, styles.narrowOnly, shared.focusRing)}
|
||||
<Button
|
||||
slot="trigger"
|
||||
className={() =>
|
||||
stylex.props(shared.button, styles.narrowOnly, shared.focusRing).className ?? ""
|
||||
}
|
||||
>
|
||||
Menu
|
||||
</button>
|
||||
</Button>
|
||||
<span {...stylex.props(styles.narrowBrand)}>nxdns</span>
|
||||
<div {...stylex.props(styles.headerRight)}>
|
||||
<LogoutButton />
|
||||
</div>
|
||||
</header>
|
||||
<ConfigStatusNotices />
|
||||
{drawerOpen && (
|
||||
<div id="mobile-nav" {...stylex.props(styles.drawer)}>
|
||||
<nav aria-label="Main" {...stylex.props(styles.drawerNav)}>
|
||||
<NavLinks onNavigate={() => setDrawerOpen(false)} />
|
||||
</nav>
|
||||
<SidebarFooter />
|
||||
</div>
|
||||
)}
|
||||
<DisclosurePanel id="mobile-nav" {...stylex.props(styles.drawer)}>
|
||||
{/* React Aria only hides a collapsed panel; the shell drops it
|
||||
instead, so a closed drawer keeps no second health poll and
|
||||
no second Pause control alive behind the header. */}
|
||||
{drawerOpen && (
|
||||
<>
|
||||
<nav aria-label="Main" {...stylex.props(styles.drawerNav)}>
|
||||
<NavLinks onNavigate={() => setDrawerOpen(false)} />
|
||||
</nav>
|
||||
<SidebarFooter />
|
||||
</>
|
||||
)}
|
||||
</DisclosurePanel>
|
||||
<main id="main-content" data-scroll-restoration-id="main" {...stylex.props(styles.main)}>
|
||||
<Outlet />
|
||||
</main>
|
||||
</div>
|
||||
</Disclosure>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user