2.8 KiB
Sidebar & menu
header.ut: near-minimal shell — empty#sidebarplus a parser-blocking inline script right after it that replays the sidebar cache (below) before first paint; sidebar chrome + nav are otherwise built client-side inmenu-shadcn.js.sidebar-shadcn.js: state machine for theme (light/dark/device), sidebar collapse/expand, accordion, and mobile drawer — exposed aswindow.ShadcnSidebarafter theshadcn-sidebar-readyevent fires.menu-shadcn.js: builds the sidebar chrome and emitsshadcn-sidebar-readybefore waiting for the menu request, so the branding, theme toggle and drawer/collapse controls are immediately available. Its navigation listeners are delegated. It resolves theadminbranch ofui.menu.load(), then renders a two-level sidebar;ICON_MAPmaps a LuCI menu node'snameto/shadcn/icons/*.svg; deeper levels render as#tabmenu.syncRoute()re-marks the active sidebar item (same longest-link-prefix rule as the header.ut replay), breadcrumb and tabs fromL.envafter a router swap without rebuilding the sidebar;closeSurfaces()closes palette/drawer/popover.
Sidebar cache (anti-flash)
menu-shadcn.js snapshots #sidebar.innerHTML + scroll position into sessionStorage['shadcn.sidebar.cache'] ({v: 2, stamp, html, scroll}) after render and on pagehide. The stamp binds the language, user, session and asset version. The header.ut inline script only replays while LuCI's session store still contains its menu, so ui.menu.flushCache() also invalidates the snapshot; the login page clears it. It replays pre-paint on the next navigation, recomputes the active highlight for the current URL (longest link-path prefix — keep in sync with menu-shadcn's dispatchpath matching), restores accordion/scroll state, and sets data-shadcn-built / data-shadcn-restored on #sidebar.
When restored, renderSidebarChrome only re-syncs the hostname, and renderSidebarNav preserves accordion/scroll across its authoritative rebuild.
Restored HTML loses inline JS handlers (innerHTML serialization), so anything that must work before the re-render needs a delegated listener — e.g. the logout click in header.ut, which clears the cache and sets window.shadcnSuppressSidebarCache so the pagehide re-cache stays suppressed.
Bump v whenever the sidebar markup changes shape.
The theme captures no view transitions (components/_view-transitions.css sets :root { view-transition-name: none }); swapped and freshly loaded content fades in instead. On desktop, collapsing eases the rail's width (_layout.css) and #main-wrapper, a flex-1 sibling, follows it frame by frame: the content is pushed, never snapped and slid back. sidebar-shadcn.js sets html[data-sidebar-anim] on the first toggle so a page load never plays the transition.