fix(apollo-core): scope base design tokens to :root, :host for shadow DOM [MST-12229]#921
fix(apollo-core): scope base design tokens to :root, :host for shadow DOM [MST-12229]#921david-rios-uipath wants to merge 6 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Dependency License Review
License distribution
Excluded packages
|
There was a problem hiding this comment.
Pull request overview
Updates Apollo Core’s generated base token CSS (variables.css) so it applies inside Shadow DOM by emitting the selector as :root, :host (instead of only :root), ensuring base tokens like font families/radius/palette inherit correctly in shadow-root consumers.
Changes:
- Switch
variables.cssoutput to a new custom Style Dictionary format (css/variables-host). - Register
css/variables-hostformat that delegates tocss/variablesand rewrites the selector to:root, :host.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| packages/apollo-core/src/tokens/config.js | Points variables.css generation to the new css/variables-host format. |
| packages/apollo-core/build-tokens.js | Adds a custom Style Dictionary format that rewrites the selector to support Shadow DOM hosts. |
📊 Coverage + size by packagePer-package coverage and bundle size on this PR. New-line coverage = of the source lines this PR adds or changes, the % hit by tests.
"Coverage" is each package's own |
02431ec to
efbd6bf
Compare
📦 Dev Packages🧹 Dev packages cleaned up (label removed). Dev package publishing is disabled. Add the Last updated: Jul 16, 2026, 03:07:25 PM PT |
efbd6bf to
d5c9eba
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
web-packages/ap-chat/src/ap-chat-element.ts:306
- Theme propagation was extended to the Shadow DOM portal container by adding the theme class to
portalContainerand updating it on theme changes. The existing unit tests assert theme updates for the React container but don’t assert that the portal container also tracks the theme, which is now required for semantic tokens/popovers to be styled correctly.
// Create dedicated portal container for tooltips/popovers at Shadow DOM root
// This prevents clipping in embedded mode while being a real HTMLElement for MUI.
this.portalContainer = document.createElement('div');
this.portalContainer.className = `portal-container ${this._theme || 'light'}`;
this.portalContainer.style.position = 'fixed';
this.portalContainer.style.top = '0';
this.portalContainer.style.left = '0';
this.portalContainer.style.width = '100%';
this.portalContainer.style.height = '100%';
this.portalContainer.style.zIndex = '9999';
this.shadowRoot.appendChild(this.portalContainer);
…or shadow DOM
The generated variables.css holds the theme-invariant base tokens (raw
color palette, font families, radius, …). Style Dictionary's built-in
css/variables format scopes them to `:root {}` only, which never matches
inside a shadow root (`:root` matches the document element; a shadow root
is a DocumentFragment). Shadow-DOM canvas consumers (e.g. web-component
embeds) therefore lose --font-mono/--font-title/--font-normal and the raw
palette, falling back to Tailwind's generic ui-monospace stack.
Add a css/variables-apollo-design format that delegates to the built-in
formatter and rewrites only the selector to `:root, .apollo-design`, so the
base tokens also apply inside a shadow root via the `apollo-design` theme
wrapper Pattern-B consumers add — the same hook theme-variables.css already
uses for semantic colors. Generated token body is byte-identical; only the
selector changes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
src/tokens/build.js was a stale duplicate of the root build-tokens.js (the script `build:tokens` actually runs) — superseded and never deleted, referenced by nothing but a biome ignore entry. It extends the same config.js, so after adding the css/variables-apollo-design format it would throw an unknown-format error if run directly, while drifting from the real generator. Delete it (and its biome ignore line) to remove the duplication. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Emit variables.css base tokens (palette, fonts, radius) under `:root, :host` instead of `:root, .apollo-design`. `:host` matches any shadow host that adopts or injects the sheet, so base tokens resolve inside a shadow root — and inherit through the whole shadow tree, including portaled content — without requiring an `.apollo-design` wrapper. Light DOM is unaffected: `:root` still applies and `:host` matches nothing there. This fixes shadow-DOM consumers that self-inject the canvas sheet (traceview's web component, ap-chat) losing apollo fonts and falling back to Tailwind's `ui-monospace`, and lets `:host`-based consumers drop their runtime `:root`→`:host` selector rewrites. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Now that apollo-core scopes base tokens to `:root, :host` (the canvas shadow-DOM
fix), ap-chat no longer rewrites `:root`→`:host` or `body.<theme>`→`:host(.<theme>) *`
at runtime. It adopts variables.css and theme-variables.css raw:
- base tokens (fonts/palette/radius) resolve via `:host` on the element and
inherit through the whole shadow tree, including the portal;
- semantic theme tokens resolve via apollo's existing
`:where(.<theme>:not(.react-flow))`, which now matches the portal container
too — it gains the theme class alongside the React container.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- ap-chat: add a test that the portal container carries the theme class
initially and keeps it in sync when the theme changes, guarding the
:where(.light) semantic-token activation the portal subtree relies on.
- apollo-core: throw in css/variables-shadow-host if the ':root {' selector
isn't found, so a future Style Dictionary reformat can't silently no-op
and regenerate variables.css back to bare :root, reintroducing the
shadow-DOM token-scoping bug.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ab7f4a5 to
54ad6c8
Compare
Problem
The generated
variables.css(raw color palette, font families like--font-mono: inconsolata/--font-title/--font-normal,--radius, …) is scoped to a bare:root {}block.:rootonly ever matches the document element (<html>); a shadow root is aDocumentFragment, not an element, so none of these base tokens apply inside a shadow root.Scope: only font tokens are affected.
--font-mono/--font-title/--font-normaland fall back to Tailwind's genericui-monospacestack (and get no title/body font at all).body.light/.apollo-design.lightblocks that match the theme-class wrapper — only the bare-:rootbase tokens fall through the gap.Fix
variables.cssis emitted by Style Dictionary's built-incss/variablesformat, which hardcodes:root {(SD v2.8.3 has noselectoroption). Add a smallcss/variables-shadow-hostformat that delegates to the built-in formatter and rewrites only the selector to:root, :host, then pointvariables.cssat it.:rootstill covers light-DOM consumers;:hostmatches any shadow host that adopts or injects this sheet, so the base tokens apply on the host and inherit through the entire shadow tree — including portaled content — with no.apollo-designwrapper required. In the light DOM:hostsimply matches nothing.Demo
Before
After
ap-chat
Screen.Recording.2026-07-16.at.5.59.48.PM.mov
Verification
:root {→:root, :host {).variables.cssdiff is exactly one line —:root {→:root, :host {.apollo-reactthrough the full chain — the base-token block (palette +--font-mono:inconsolata+--font-title/--font-normal) is now:root, :host {…}.--font-monoresolves toinconsolatainside the shadow root (traceview WC and ap-chat) — with no wrapper and no runtime selector rewriting — while semantic--color-background/--color-foregroundresolve on both the container and the portal.Downstream, this lets shadow-DOM consumers drop client-side
:root→:hostrewrite workarounds. ap-chat now adoptsvariables.css/theme-variables.cssraw (commits on this branch).Alternative considered:
:root, .apollo-design, scoping to the documented Pattern-B wrapper class (and working in a light-DOM subtree without touching:root). Chose:root, :hostbecause it needs no wrapper, covers portaled/shadow content mounted outside a wrapper, and lets:host-based consumers (ap-chat) drop their runtime selector rewrites.