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

2.4 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: 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, lang, html, scroll}) after render and on pagehide. The header.ut inline script replays it 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.