feat(ui): adopt the Nebari Design registry header and theme hook - #4
Merged
Conversation
Adopt the shared header and theme hook from the nebari-design shadcn registry (nebari-dev/nebari-design#131), mirroring nebari-landing's canonical Header: - Add components.json with the @Nebari registry and install @nebari/navigation-menu, @nebari/dropdown-menu, @nebari/button, and @nebari/use-theme-preference (button was already identical; the local dropdown-menu is upgraded to the registry version). - Extract the header out of layout.tsx into components/header.tsx built on MenuBarBrand/MenuBarNav/MenuBarActions: h-14 bar, h-8 logo linking home, the app's Dashboard/Apps/Metrics nav links preserved as registry NavLinks, and a 248px profile menu with name/email, a Light/Dark/System menuitemradio segmented theme control, and a red sign-out item wired to the existing Keycloak logout. - Style the header only with the shared semantic tokens (--header-*, --notification-badge, --sign-out-foreground) copied from nebari-landing, plus their @theme --color-* mappings. - Replace the local useThemePreference hook with the registry hook + ThemeProvider (keeping the existing nebari-apps:themeMode storage key) and inline the generated pre-paint bootstrap script in index.html. - Add a vitest + testing-library unit suite for the header (menuitemradio aria-checked assertions included) and run it in CI. The app has no notifications feature, so the notifications bell is intentionally omitted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Xb4VPMBJ4ksnCiChJpVzu
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adopts the shared header and theme hook from the nebari-design shadcn registry, mirroring nebari-landing's canonical
Header.ui/components.jsonwith the@nebariregistry and installed@nebari/navigation-menu,@nebari/dropdown-menu,@nebari/button, and@nebari/use-theme-preferencevianpx shadcn@latest add. The localbutton.tsx/spinner.tsxwere already identical to the registry versions; the localdropdown-menu.tsxwas upgraded to the registry version (its only consumer was the old header). The localavatar.tsxis kept — the registry has no avatar item.layout.tsxintosrc/components/header.tsx, built onMenuBarBrand/MenuBarNav/MenuBarActions. The app's Dashboard/Apps/Metrics nav links are preserved as registryNavLinks (react-routerLinkvia the render prop, active state fromuseLocation). The profile menu keeps the app's real auth wiring:getUser()for name/email, Keycloaklogout()for sign-out, and the existing "Authentication disabled" fallback when auth is off (no sign-out item in that case).--header-border,--header-foreground,--header-action-hover,--notification-badge,--sign-out-foreground—--header-backgroundalready existed) for light and dark insrc/index.css, with their@theme--color-*mappings, values copied from nebari-landing.useThemePreferencehook with the registry hook +ThemeProvider(installedtheme-provider.tsx), keeping the existingnebari-apps:themeModestorage key, and inlined thethemeBootstrapScript-generated pre-paint script inindex.html.ui/tests/) — the repo previously had no JS test infra — and wirednpm testinto the CIuijob.Acceptance criteria (nebari-dev/nebari-design#131)
@nebariregistry added tocomponents.json; header rebuilt onMenuBarBrand/MenuBarActionsfrom@nebari/navigation-menuh-14bar,pl-4, logoh-8 w-auto,MenuBarBrand href="/"witharia-label="Go to homepage"--header-*semantic tokens in light and dark;--notification-badgeand--sign-out-foregrounddefined with--color-*mappings@nebari/use-theme-preference; app wrapped in the registryThemeProvider; bootstrap script inlined inindex.htmlhead; existingnebari-apps:themeModestorage key preservedw-[248px] p-2, red sign-out withLogOuticon usingtext-sign-out-foregroundmenuitemradiosegmented control (Light/Dark/System) wired to the registry hookmenuitemradio+aria-checkedassertions, theme-change callbacks, sign-out, no-auth fallback (there were no pre-existing JS tests to migrate)Test plan
npm run build(tsc -b + vite build, now also type-checkstests/) — passesnpm test(vitest, 7 tests) — passesPre-existing note:
vite buildwarns about a >500 kB chunk; unrelated to this change.Part of nebari-dev/nebari-design#131
🤖 Generated with Claude Code
https://claude.ai/code/session_012Xb4VPMBJ4ksnCiChJpVzu