Skip to content

feat(inspector-tabs): send resolved theme tokens and mounted surface to custom tab iframes - #5501

Open
jog1t wants to merge 1 commit into
mainfrom
feat/inspector-tab-theme-tokens
Open

feat(inspector-tabs): send resolved theme tokens and mounted surface to custom tab iframes#5501
jog1t wants to merge 1 commit into
mainfrom
feat/inspector-tab-theme-tokens

Conversation

@jog1t

@jog1t jog1t commented Jul 30, 2026

Copy link
Copy Markdown
Contributor
  • Custom inspector tab iframes now receive the dashboard's resolved theme colors on the existing init postMessage, as tokens (ready-to-use CSS color values) plus surface, which names the token of the panel the tab is mounted on. theme is unchanged, so tabs that only read it keep working.
  • The dashboard resolves the tokens from its own live computed styles per theme and re-sends them through the same path it already used for theme changes, so a tab that applies them updates without a reload.
  • The shared tab stylesheet gains --rivet-surface (the mounted surface, aliasing --rivet-card) and paints html / body with it instead of --rivet-background. This alone makes existing tabs sit flush in their host panel with no tab-side change.
  • Added applyInspectorTabTheme, resolveInspectorTabSurface, and inspectorTabTokenVar helpers to rivetkit/inspector-tab for tabs built with a bundler.
  • Documented the contract on the custom-tabs docs page: which surface a tab is mounted on, the stable token names, and how to follow a live theme change.
  • Updated both example tabs and the docs quickstart to apply the payload and declare the surface explicitly.

Verified against the generated stylesheet and real theme tokens in a harness reproducing the dashboard's card panel: the tab body computes to the same color as its host panel in dark (rgb(12,12,14)) and light (rgb(255,255,255)), updates on theme toggle without reloading, and a theme-only tab with no token handling measures identically.

@railway-app

railway-app Bot commented Jul 30, 2026

Copy link
Copy Markdown

🚅 Deployed to the rivet-pr-5501 environment in rivet-frontend

Service Status Web Updated (UTC)
website 😴 Sleeping (View Logs) Web Jul 30, 2026 at 12:12 am
frontend-cloud 😴 Sleeping (View Logs) Web Jul 30, 2026 at 12:12 am
frontend-inspector 😴 Sleeping (View Logs) Web Jul 30, 2026 at 12:10 am
kitchen-sink 😴 Sleeping (View Logs) Web Jul 30, 2026 at 12:08 am
ladle ✅ Success (View Logs) Web Jul 30, 2026 at 12:04 am
mcp-hub ✅ Success (View Logs) Web Jul 30, 2026 at 12:01 am

@claude

claude Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review

Solid, well-scoped feature: resolved theme tokens + mounted-surface info are added to the existing init postMessage, both fields are optional so older/newer dashboard-tab combinations stay compatible, and the docs/examples are updated in lockstep with the schema (InspectorTabTokensSchema, V1InitSchema). The --rivet-surface / --rivet-surface-foreground alias change is a nice, low-risk way to fix the panel 'seam' issue without requiring tab-side changes.

A few minor things worth a look, nothing blocking:

1. Misleading diagnostic message (frontend/src/components/actors/inspector-tab-tokens.ts)
readInspectorTabTokens() looks up the kebab-case CSS var (--card-foreground) but the console.error on a miss logs the untransformed camelCase name instead (missing dashboard token --cardForeground). Doesn't match the property that was actually queried, which makes this harder to debug if it ever fires. Consider logging the transformed var name that was actually looked up.

2. Duplicated "card" surface constant across the package boundary
INSPECTOR_TAB_SURFACE = "card" in frontend/src/components/actors/inspector-tab-tokens.ts and DEFAULT_INSPECTOR_TAB_SURFACE = "card" in rivetkit-typescript/.../inspector-tab/mod.ts are two independent string literals for the same concept. Since the frontend file already imports INSPECTOR_TAB_TOKEN_NAMES/InspectorTabTokens from rivetkit/inspector-tab, importing DEFAULT_INSPECTOR_TAB_SURFACE too would remove the risk of the two drifting apart later.

3. --rivet-surface-foreground doesn't track live surface changes
--rivet-surface gets pinned live from init.tokens[init.surface], but there's no equivalent wire field for a foreground color, so --rivet-surface-foreground stays hardcoded to var(--rivet-card-foreground) in inspector-tab-aliases.css. Harmless today since surface is always "card", but the code/docs explicitly anticipate the mounted surface changing in the future ('if the host ever moves the tab onto a different surface') — if that happens, background and foreground would go out of sync. Worth a follow-up if/when a non-card surface is introduced.

4. Example inline applyTheme is slightly less defensive than the exported helper
resolveInspectorTabSurface in mod.ts falls back to tokens[DEFAULT_INSPECTOR_TAB_SURFACE] when tokens[surface] itself is missing (e.g. a surface name unknown to this tab's rivetkit version). The copy-pasted inline versions in the two example HTML files and the docs quickstart (const surface = msg.tokens[msg.surface ?? "card"];) don't have that second fallback — a no-op today, but a trap for anyone hand-copying the snippet once surface starts varying.

5. Test coverage
No unit tests were added for the new pure helpers (applyInspectorTabTheme, resolveInspectorTabSurface, inspectorTabTokenVar, readInspectorTabTokens/toCssColor). These are cheap to cover (kebab-case name transform, HSL-vs-already-a-color detection, missing-token fallback behavior) and would guard the token-name transform that's currently hand-duplicated in four places (rivetkit helper, both example tabs, docs mdx).

Nothing here blocks merging — mostly small robustness/consistency nits for a change that's otherwise clean and backward-compatible.

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