Skip to content

refactor(ui): migrate Mantine UI v8 → @ossrandom/design-system v0.3.0#71

Merged
aksOps merged 14 commits into
mainfrom
feat/ui-design-system-foundation
Apr 30, 2026
Merged

refactor(ui): migrate Mantine UI v8 → @ossrandom/design-system v0.3.0#71
aksOps merged 14 commits into
mainfrom
feat/ui-design-system-foundation

Conversation

@aksOps

@aksOps aksOps commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Per board direction, replace Mantine with the RandomCodeSpace design system. The UI's only direct Mantine surface was 3 files (provider + 2 MCP components), so this is a focused refactor — not a full visual rewrite. Custom CSS strip and <Card> adoption are intentionally deferred to follow-up PRs to keep this one reviewable.

Drive-by build fix

Build was already broken on main: react-window was bumped to v2 by Dependabot, but LogsPage.tsx / TracesPage.tsx still import VariableSizeList / FixedSizeList / ListChildComponentProps which v2 no longer exports. Pinned back to ^1.8.10 here to unblock the build; the v2 API migration is its own follow-up.

Files

  • ui/src/main.tsxMantineProviderThemeProvider; ToastRegion mounted at root.
  • ui/src/components/mcp/ToolCallModal.tsx — Mantine Modal → DS Modal. The DS Modal API is stricter (no padding=0, classNames, styles, custom width) so the hand-rolled header is collapsed into title / description props; size maps to "lg".
  • ui/src/components/mcp/RPCPopup.tsx — Mantine Modal + Tabs → DS Modal + Tabs. DS Tabs uses items={[{key, label}]} instead of children-style sub-components; the methods array translates directly.
  • ui/package.json — drop @mantine/core + @mantine/hooks; add @ossrandom/design-system@0.3.0; pin react-window to ^1.8.10 (drive-by build fix).
  • internal/ui/dist/* — regenerated. Bundle delta: -598 / +123 lines (Mantine CSS gone). DS variable woff2 fonts (Bricolage Grotesque, Plus Jakarta Sans, Geist Mono) ship as separate on-demand assets (~30–130 KB each).
  • CLAUDE.md — project rule updated: "NO Tailwind CSS, NO Mantine — use @ossrandom/design-system exclusively for UI components and tokens. Raw CSS only for layout escape hatches."

Out of scope (deliberate, follow-up PRs)

  • Strip ui/src/styles/tokens.css (DS provides design tokens) and slim global.css to layout-only.
  • Replace <div className=\"card\"> with DS <Card>; replace inline style={{display:'flex'...}} with DS <Space>/<Grid>/<AppShell>/<PageHeader>.
  • Migrate ServiceMap.tsx / EChart.tsx from echarts to the DS /charts subpath.
  • react-window v2 API migration (VariableSizeListList).

Test plan

  • cd ui && npm run build — clean
  • cd ui && npm run test -- --run — 32/32 pass
  • Go binary rebuilt with the new embedded UI; GET / returns the DS-styled bundle
  • DS fonts load on demand from /assets/*.woff2
  • CI green before merge

🤖 Generated with Claude Code

Replace the Mantine dependency with the RandomCodeSpace design system per
project board direction. Per-component scope is small — the UI's only
direct Mantine surface is main.tsx (provider) plus two MCP components
(Modal/Tabs).

Changes:
- main.tsx — MantineProvider to ThemeProvider; ToastRegion mounted at root
- ToolCallModal.tsx — Mantine Modal to DS Modal. DS Modal API is stricter
  (no padding=0, no classNames, no styles, no custom width) so the
  hand-rolled header is collapsed into title/description props and the
  modal sizes to lg instead of min(880px, 100vw-2rem).
- RPCPopup.tsx — Mantine Modal+Tabs to DS Modal+Tabs. Tabs API is items
  rather than children, so the methods array maps to items={[{key,label}]}.
- @mantine/core and @mantine/hooks removed from package.json
- @ossrandom/design-system@0.3.0 added (public npm; no GHP/PAT setup)
- internal/ui/dist regenerated. Net bundle is -598 / +123 lines because
  Mantine CSS is gone; DS ships variable woff2 fonts (Bricolage Grotesque,
  Plus Jakarta Sans, Geist Mono) as separate ~30-130KB assets that load
  on demand.
- CLAUDE.md project rules updated: NO Tailwind CSS, NO Mantine — use
  @ossrandom/design-system exclusively for UI components and tokens.
  Raw CSS only for layout escape hatches.

Out of scope (deliberate, follow-up PRs):
- Strip ui/src/styles/tokens.css and slim global.css to layout-only.
- Migrate ServiceMap.tsx / EChart.tsx from echarts to DS charts subpath.
- Replace inline style={{display:flex…}} with DS Space/Grid/Card.

Drive-by: pin react-window to ^1.8.10 (was ^2.2.7). The v2 API is
incompatible with current LogsPage.tsx / TracesPage.tsx imports
(VariableSizeList, FixedSizeList, ListChildComponentProps no longer
exported), and the build was broken on main even before this PR. The
v2 migration is its own concern; pinning back to v1 here keeps this PR
strictly about the DS swap and gets the build green.

Verification:
- npm run build: clean
- npm run test: 32/32 pass
- Live: HTTP_PORT=37778 ./otelcontext, GET / returns the DS-styled bundle
  (fonts load on demand, /assets/index-*.js + /assets/index-*.css served).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@socket-security

socket-security Bot commented Apr 29, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​cytoscape-cose-bilkent@​4.1.09910010075100
Addednpm/​@​ossrandom/​design-system@​0.3.07710010091100
Addednpm/​cytoscape@​3.33.210010010095100

View full report

aksOps and others added 4 commits April 29, 2026 14:13
…al shift

Rewrite ui/src/styles/tokens.css so the legacy --bg-base / --text-primary /
--color-accent etc. names resolve to @ossrandom/design-system tokens
(--bg-0..3, --fg-1..4, --accent-fg, --border-1..3). Existing inline
`var(--*)` usage and the .card/.top-nav/.nav-link rules in global.css now
pick up the DS palette and fonts (Bricolage Grotesque, Plus Jakarta Sans,
Geist Mono, Cod Gray on Signal Red) without touching every component.

This is the thin transition shim called out as "out of scope" in the
parent commit's message — a follow-up PR will replace the class-based
styles in global.css with DS components and delete this file entirely.

Bundle delta: -21 CSS lines (light-theme block removed; DS owns theming
via ThemeProvider mode now). Live verified at oteliq.randomcodespace.dev:
the new CSS hash (index-BLTTK0qH.css) ships --bg-base:var(--bg-0) plus the
DS variable woff2 references for all three font families.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…s + custom CSS

- ServiceMap: replace echarts force-directed graph with DS ServiceMap (cose-bilkent)
- TracesPage / LogsPage / ServiceSidePanel: replace .card / .badge / .side-panel
  classes with DS Card / Badge / Button / Alert / Input / Spin / Space
- TopNav / MCP console + modals: already on DS, polished tones (mono palette)
- ErrorBoundary: keep inline styles (must render if DS fails to load) but bind
  to DS CSS vars with hex fallbacks for theme harmony
- Strip global.css to layout-only escape hatches (#root, scrollbar, code, html
  height); strip tokens.css to box-sizing reset + colorJSON syntax palette
- Remove echarts dependency (-4 packages); delete unused EChart wrapper +
  tierLayout (orphaned after migration)
- Net 1376 insertions / 1722 deletions; CSS bundle 49 KB (gzip 9.4 KB)
Comment thread internal/ui/dist/assets/design-system-BNhP-Tae.js
Comment thread internal/ui/dist/assets/design-system-DFjB0sSn.js
Comment thread internal/ui/dist/assets/design-system-IOKLDoaG.js
aksOps added 9 commits April 29, 2026 15:21
…er/Stat/Grid/CodeBlock)

- App: AppShell hosts header + main content; no inline styles
- TopNav: PageHeader + controlled Tabs + Stat strip; StatPill helper deleted
- ServiceSidePanel: KPI grid → DS Stat (4-up); upstream/downstream lists →
  Card-bordered Buttons; health bar → DS Progress
- TracesPage / LogsPage: 12-col Grid + Card + ScrollDiv + Space; row buttons
  built from DS Button + Space; pre-with-HTML eliminated
- ServiceMap: side-panel split moved to Grid (8/4); toolbar → Card extra slot
- MCP modals: pre+colorJSON HTML → DS CodeBlock (language="json", copyable)
- ToolCard / MCPConsole / ToolCallModal / RPCPopup: Grid + Space replace
  inline grid/flex; Card title/extra/footer slots replace bespoke headers
- Drop tokens.css entirely (--syntax-* palette unused after CodeBlock swap);
  global.css trimmed to browser reset only (3 rules: box-sizing, body margin,
  #root height)
- utils.ts: drop unused colorJSON + esc helpers

Net: 619 insertions / 1078 deletions; CSS bundle 48.5 KB (gzip 9.2 KB).
…treams, MCP simplified

Each view now owns its own layout with PageHeader + Stat strip + a single full-width
data surface, instead of cramming a split-grid into a shared container.

- ServicesView: full-bleed DSServiceMap (height 620); right Drawer hosts the
  service detail panel on node-click. 4-up Stat strip surfaces real-time
  active services / error rate / total traces / total logs.
- TracesView: DS Table (compact, sticky header, striped) replaces the virtualized
  card list; row click opens a right Drawer with the span waterfall. Stats:
  in-view trace count, error count, avg duration, p95 (computed locally).
- LogsView: DS Table for the stream; severity Buttons + Input live in
  Card.extra. "Find similar" opens a right Drawer instead of stealing a
  side column. Stats: in-view / errors / warnings / info counts.
- MCPConsole rewritten: tool cards / Call / JSON-RPC modals removed entirely.
  Single Card now shows the endpoint URL with copy button + three example
  CodeBlocks (tools/list, tools/call, curl). useMCP hook deleted.
- TopNav: compact horizontal bar — brand, controlled Tabs, live/offline badge,
  theme toggle. Stat strip moved into per-view PageHeaders.
- App: AppShell.header = TopNav; main = view switch. No serviceFilter/dashboard
  global chrome — each view consumes what it needs.

Files removed: ToolCard.tsx, ToolCallModal.tsx, RPCPopup.tsx, useMCP.ts,
  ServiceMap.tsx, TracesPage.tsx, LogsPage.tsx (all replaced).
Deps removed: react-window, @types/react-window (-3 packages); virtualization
  is unnecessary at the 200-row cap.

Net 804 insertions / 1096 deletions; JS 247 KB / gzip 77 KB; CSS 48.5 KB / gzip 9.2 KB.
Mobile (≤760px) nav was unreachable — header overflowed off-screen with no
hamburger. Layout was also too heavy — every Stat was its own bordered Card.

- TopNav: useMediaQuery splits into compact (hamburger → left Drawer with DS
  Menu vertical) and wide (Tabs inline) variants
- StatRow component: single Card with inline Stats separated by Divider —
  replaces the 4-card 12-col Grid wrapper across all three views
- MCP page reduced to one Card: URL with Copy button + one paragraph on
  HTTP-Streamable / JSON-RPC / Bearer auth. The 3 example CodeBlocks are
  gone (they read as "tools" still being there).
- Drawer width: number on desktop, "92vw" on mobile so it doesn't overflow
- ServiceMap height: 660 desktop, 460 mobile (the map is the hero)
- PageHeaders use size="sm" with inlineSubtitle to reclaim vertical space
- ServicesView accepts string-or-number DBSizeMB from /api/stats (server
  returns "1990.0" as string while old type expected number)

11 files changed, 269 insertions / 258 deletions.
ServicesView and ServiceSidePanel: toFixed(2) instead of toFixed(1).
DS Stat renders delta.value verbatim, so passing a raw float showed e.g.
"↑15.661224321%". The error-rate / error-count / warn-count deltas were
also redundant with the main value (no period-over-period data).

- ServicesView / ServiceSidePanel: drop delta on error-rate Stat (showed
  the same number as the value).
- LogsView: drop delta on errors / warnings (same — count == count).
- TracesView: keep p95 delta (it's a real comparison vs avg) but round
  to 1 decimal at the source so DS doesn't print 10 decimals.
…unters

dashboard.total_traces / total_logs are *recent-window* counters, while
DBSizeMB reflects the entire on-disk dataset. The mismatch made 4 GB look
unjustified next to a small "Logs" number. Switch the Traces/Logs Stats
to /api/stats (TraceCount/LogCount) so they reconcile with DB size; fall
back to dashboard counters when /api/stats hasn't loaded yet.
@sonarqubecloud

Copy link
Copy Markdown

@aksOps aksOps merged commit 75a2e56 into main Apr 30, 2026
17 checks passed
@aksOps aksOps deleted the feat/ui-design-system-foundation branch April 30, 2026 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant