feat: widen the webui library surface for consumers building their own pages - #2130
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The new consumer-provided admin-page path handling and navbar-blur extension hook contract need hardening/clarification to avoid invalid consumer input causing routing failures and to make the new exported behavior unambiguous.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR broadens the published openvsx-webui package’s public surface so downstream deployments can build custom pages and extend chrome/menus/dashboard while reusing Open VSX’s core UI primitives and contexts.
Changes:
- Adds new exported UI primitives and shared styles (
Pill, lifted page primitives likecompactControl,glassSurface, etc.) and refactors existing components to use them. - Replaces the extension-tint context with a new navbar-chrome context (tint + blur-depth extension) and renames scroll behavior to
ScrollRestoration. - Exposes additional extension points via
PageSettingsand exports (user menu contributions, admin dashboard contributed pages,MainContextadditions, request/utils exports), with new unit tests covering these extension points.
File summaries
| File | Description |
|---|---|
| webui/vite.config.mts | Inlines specific MUI X deps in Vitest’s Vite server to avoid ESM resolution issues in tests. |
| webui/test/unit/support/test-providers.tsx | Adds TestEntryShell + renderInEntryShell and updates MainContext test defaults for userLoading. |
| webui/test/unit/support/menu-queries.ts | Adds menu label query helper avoiding jsdom role-query crashes. |
| webui/test/unit/pages/user/avatar.spec.tsx | Adds tests for contributed desktop user-menu entries and their styling/behavior. |
| webui/test/unit/pages/admin-dashboard/admin-dashboard.spec.tsx | Adds tests for contributed admin pages (routing + nav grouping + shadow protection). |
| webui/test/unit/main.spec.tsx | Adds tests asserting MainContext.userLoading behavior during initial user fetch. |
| webui/test/unit/default/menu-content.spec.tsx | Adds tests for contributed mobile user-menu entries and styling. |
| webui/src/pages/user/avatar.tsx | Adds support for contributed user-menu entries via PageSettings.elements.userMenuContent. |
| webui/src/pages/search/search-header.tsx | Reuses shared compactControl styling primitive. |
| webui/src/pages/extension-detail/extension-detail.tsx | Switches to new navbar-chrome context and updates scroll behavior comment reference. |
| webui/src/pages/admin-dashboard/nav-types.ts | Introduces AdminPage and AdminPageCategory types for consumer-contributed dashboard pages. |
| webui/src/pages/admin-dashboard/admin-dashboard.tsx | Merges contributed admin pages into nav + routes, and builds route name map from merged nav. |
| webui/src/page-settings.ts | Adds userMenuContent and adminPages extension points + user-menu entry prop types. |
| webui/src/main.tsx | Exposes userLoading on MainContext. |
| webui/src/layout/scroll-restoration.tsx | Renames ScrollToTop to ScrollRestoration and documents current limitations. |
| webui/src/layout/app-navbar.tsx | Consumes navbar-chrome blur extent to stretch blur fan for pinned sections. |
| webui/src/layout/app-layout.tsx | Swaps tint provider for NavbarChromeProvider and uses ScrollRestoration. |
| webui/src/index.ts | Re-exports new/expanded public API surface for consumers (contexts, providers, primitives, utils, types). |
| webui/src/default/theme.tsx | Disables popover scroll lock and aligns popover paper styling with floating-paper treatment. |
| webui/src/default/menu-content.tsx | Adds contributed user-menu entries to mobile menu and keeps entry components stable. |
| webui/src/context/navbar-chrome-context.tsx | Adds new navbar-chrome context (tint + blur depth) and associated hooks/provider. |
| webui/src/context/extension-tint-context.tsx | Removes old extension tint context (superseded by navbar-chrome context). |
| webui/src/context.ts | Adds userLoading to the MainContext shape. |
| webui/src/components/pill.tsx | Adds new Pill primitive used by category pills and exported for consumers. |
| webui/src/components/page-primitives.tsx | Lifts shared primitives (e.g., MonoSlash, glassSurface, compactControl). |
| webui/src/components/extension-searchfield.tsx | Uses lifted MonoSlash from page-primitives. |
| webui/src/components/category-pill.tsx | Refactors CategoryPill onto the new Pill primitive. |
| webui/src/app-providers.tsx | Updates provider-stack docs to reflect navbar-chrome context. |
| webui/CHANGELOG.md | Documents new exports/extension points and behavior/context renames. |
Review details
- Files reviewed: 29/29 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
daaa1fe to
f3a49db
Compare
|
I tested this PR locally, so I think we can merge that already in for the 1.2.0 release. |
(cherry picked from commit e0a4859)
(cherry picked from commit 2f96cbc)
(cherry picked from commit 1208a19)
(cherry picked from commit 5bba107)
(cherry picked from commit ad058b3)
The dashboard spec is the first test to mount a page that reaches @mui/x-charts (the rate limiting usage stats chart), x-data-grid and x-date-pickers. Their ESM builds import directory paths Node's resolver rejects, so vite has to bundle them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
adminPages is consumer-provided API input, and the shadowing check took the first segment of the path as given. A leading slash left it inspecting an empty segment, so '/customers' passed the check and sat in the nav beside the built-in page it names, and createRoute joined it into '/admin-dashboard//customers'. Paths are now trimmed of leading and trailing slashes before anything derives a route or a nav link from them, and a path left empty by that is dropped. Also corrects two doc comments that said the opposite of what the code does: compactControl carries nested selectors for the select's inner slots, so it is sx-only rather than usable in a plain style prop; and useExtendNavbarBlur has no ownership stack, so "last writer wins" only holds until any writer unmounts and resets the fan under a second one still mounted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
a270011 to
b391029
Compare
Stack: 1 of 6. Split out of #2027 so each part can be reviewed on its own. Base:
main.All commits here are @gnugomez's, cherry-picked with
-x.This is the part of #2027 that has nothing to do with download analytics: it widens what the published
openvsx-webuipackage exposes, so a deployment can build its own pages on top of it.Pillcomponent, withCategoryPillrefactored onto it, and shared page primitives lifted out (page-primitives.tsx,focusOutline)navbar-chrome-context.tsx), replacingextension-tint-context.tsx;scroll-to-top.tsxbecomesscroll-restoration.tsxuserLoadingand account-menu entries exposed to consumers, viapage-settingsandMainContextnav-types.ts)src/index.tsWhy it is first in the stack
It is independent of everything else in #2027, and it is a published API change — the surface other deployments compile against. That deserves a focused look at naming and stability, which is exactly what does not happen when it arrives as 30 of 114 files behind a feature.
It is also not purely additive:
extension-tint-context.tsxis deleted andscroll-to-toprenamed, so it changes existing chrome behaviour.Notes on the split
Two things were adjusted while rebasing onto current
main:menu-content.tsxconflicted with the publish overhaul (feat: publish extensions overhaul #2098) that landed since. Resolved by keeping both: main'sPublishRoutes/PublishButton/useShortcutimports alongside this branch'sComponentType/useCallback/useMemo/Button/useNavigate.admin-dashboard.tsxconflicted with the Search Index page (feat: add a search index page to the admin dashboard #2121). Resolved by keeping the/search-indexroute and the contributed-pages splat, on thenavItemsrename.One commit is mine rather than cherry-picked: the vite
server.deps.inlineentry. The new dashboard spec is the first test to mount a page reaching@mui/x-charts(the rate-limiting usage-stats chart, already onmain),x-data-gridandx-date-pickers, whose ESM builds import directory paths Node's resolver rejects.The
@mui/x-chartsentry is needed here on its own merits — I initially deferred it as analytics-related and that was wrong; it comes from a chart already onmain.Verification
yarn test274 passing across 54 files,yarn lintclean,tsc --noEmitclean.Refs #2027, #2025