From a8f364478a1e56adfcb92887a9e07b0cd7ebd199 Mon Sep 17 00:00:00 2001 From: ishaanxgupta Date: Wed, 1 Jul 2026 20:56:45 +0530 Subject: [PATCH] style(mcp): align graph widget surface --- apps/mcp/src/widget/App.tsx | 59 +++++++++++++++--------- apps/mcp/src/widget/design/globals.css | 62 +++++++++++++++++++------- apps/mcp/src/widget/views/Graph.tsx | 20 ++++++--- 3 files changed, 98 insertions(+), 43 deletions(-) diff --git a/apps/mcp/src/widget/App.tsx b/apps/mcp/src/widget/App.tsx index e5ec8192..c93b7a27 100644 --- a/apps/mcp/src/widget/App.tsx +++ b/apps/mcp/src/widget/App.tsx @@ -47,31 +47,48 @@ export function App() { ) } - return {renderView(state.message, setView, setError)} + const isGraphView = state.message.view === "graph" + return ( + + {renderView(state.message, setView, setError)} + + ) } -function WidgetShell({ children }: { children: ReactNode }) { +function WidgetShell({ + children, + immersive = false, +}: { + children: ReactNode + immersive?: boolean +}) { + const shellClassName = immersive + ? "mcp-widget-shell mcp-widget-shell-graph" + : "mcp-widget-shell" + return ( -
+
-
- - - - - - - - supermemory - MCP - -
+ {immersive ? null : ( +
+ + + + + + + + supermemory + MCP + +
+ )}
{children}
) diff --git a/apps/mcp/src/widget/design/globals.css b/apps/mcp/src/widget/design/globals.css index d7c12cfc..95c259bb 100644 --- a/apps/mcp/src/widget/design/globals.css +++ b/apps/mcp/src/widget/design/globals.css @@ -137,6 +137,45 @@ color: var(--text-primary); } +.mcp-widget-shell-graph { + min-height: 420px; + background: #05080d; +} + +.mcp-widget-shell-graph::before, +.mcp-widget-shell-graph::after { + position: absolute; + inset: 0; + z-index: 0; + pointer-events: none; + content: ""; +} + +.mcp-widget-shell-graph::before { + background-image: radial-gradient( + circle at center, + rgba(105, 167, 240, 0.25) 1px, + transparent 1px + ); + background-size: 32px 32px; + mask-image: radial-gradient(ellipse at center, black 60%, transparent 100%); +} + +.mcp-widget-shell-graph::after { + background: + radial-gradient( + ellipse at 50% 112%, + rgba(75, 160, 250, 0.42) 0%, + rgba(20, 16, 255, 0.3) 34%, + transparent 66% + ), + linear-gradient(180deg, rgba(5, 8, 13, 0) 0%, rgba(5, 8, 13, 0.2) 100%); +} + +.mcp-widget-shell-graph .mcp-widget-glow { + display: none; +} + .mcp-widget-glow { position: absolute; right: -18%; @@ -214,6 +253,10 @@ z-index: 1; } +.mcp-widget-shell-graph .mcp-widget-content { + min-height: inherit; +} + /* Spinner — kept as global because primitives can't easily express a CSS animation */ .spinner { width: 24px; @@ -243,26 +286,13 @@ * minimize). Keeping it in flow with an explicit height avoids that entirely. */ .graph-view { width: 100%; - aspect-ratio: 4 / 3; + aspect-ratio: 16 / 9; /* Never collapse to 0 during a resize/transition — a 0-size frame makes the * package drop its "already fitted" flag and re-fit (a camera animation that * reads as a re-layout). The floor keeps the size continuous. */ - min-height: 280px; + min-height: 420px; position: relative; - background: - linear-gradient(rgba(75, 160, 250, 0.035) 1px, transparent 1px), - linear-gradient(90deg, rgba(75, 160, 250, 0.035) 1px, transparent 1px), - radial-gradient( - circle at 50% 108%, - rgba(75, 160, 250, 0.22), - transparent 42% - ), - var(--bg-primary); - background-size: - 36px 36px, - 36px 36px, - 100% 100%, - 100% 100%; + background: transparent; } .graph-view.fullscreen { diff --git a/apps/mcp/src/widget/views/Graph.tsx b/apps/mcp/src/widget/views/Graph.tsx index c48122af..5c621b2c 100644 --- a/apps/mcp/src/widget/views/Graph.tsx +++ b/apps/mcp/src/widget/views/Graph.tsx @@ -151,6 +151,14 @@ export function Graph({ documents, totalCount }: Props) { // mid-session theme switch re-themes the canvas. const theme = (ctx?.theme as string | undefined) ?? "light" const colors = useGraphColors(theme) + const graphColors = useMemo>( + () => ({ + ...colors, + bg: "transparent", + edgeDerives: "#9ca3af", + }), + [colors], + ) const fullscreenSupported = useMemo(() => { const modes = ( @@ -185,11 +193,11 @@ export function Graph({ documents, totalCount }: Props) { }, [mode, toggleFullscreen]) return ( -
+
{/* No remount on toggle. The CSS just resizes the container; the @@ -197,10 +205,10 @@ export function Graph({ documents, totalCount }: Props) { positions stable, so expand/minimize is instant with no reload. Theme is fed reactively via the colors prop. */}
{fullscreenSupported ? ( @@ -208,7 +216,7 @@ export function Graph({ documents, totalCount }: Props) { aria-label={ mode === "fullscreen" ? "Exit fullscreen" : "Enter fullscreen" } - className="absolute top-4 right-4 z-40 inline-flex items-center justify-center w-9 h-9 rounded-md bg-bg-elevated/80 backdrop-blur border border-border text-text-secondary hover:text-text-primary hover:bg-bg-muted transition-colors" + className="absolute top-3 right-3 z-40 inline-flex items-center justify-center w-9 h-9 rounded-full bg-bg-elevated/90 backdrop-blur border border-border text-text-secondary hover:text-text-primary hover:bg-bg-muted transition-colors" onClick={toggleFullscreen} title={mode === "fullscreen" ? "Exit fullscreen" : "Fullscreen"} type="button"