Files
op-packages/luci-theme-shadcn/.dev/docs/sidebar.md
T

2.8 KiB

Sidebar & menu

  • header.ut: near-minimal shell — empty #sidebar plus 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 in menu-shadcn.js.
  • sidebar-shadcn.js: state machine for theme (light/dark/device), sidebar collapse/expand, accordion, and mobile drawer — exposed as window.ShadcnSidebar after the shadcn-sidebar-ready event fires.
  • menu-shadcn.js: builds the sidebar chrome and emits shadcn-sidebar-ready before waiting for the menu request, so the branding, theme toggle and drawer/collapse controls are immediately available. Its navigation listeners are delegated. It resolves the admin branch of ui.menu.load(), then renders a two-level sidebar; ICON_MAP maps a LuCI menu node's name to /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 from L.env after 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.