Skip to content

feat(apollo-wind): add registerCssPropertyRules for shadow DOM#830

Draft
david-rios-uipath wants to merge 2 commits into
mainfrom
rios/shadow-dom-property-registration
Draft

feat(apollo-wind): add registerCssPropertyRules for shadow DOM#830
david-rios-uipath wants to merge 2 commits into
mainfrom
rios/shadow-dom-property-registration

Conversation

@david-rios-uipath

Copy link
Copy Markdown
Contributor

Summary

Adds registerCssPropertyRules(css) — a JS helper that extracts Tailwind v4 @property declarations from a CSS string and registers them at the document level. This is needed because browsers silently ignore @property rules inside shadow DOM <style> elements, breaking composable Tailwind utilities (border, shadow-*, ring-*, translate-*, etc.) inside shadow roots.

See upstream discussion: tailwindlabs/tailwindcss#16772

Immediate consumer: @uipath/traceview — migrating shared Tooltip from MUI to apollo-wind (Radix), which portals inside a shadow root.

Demo

No visual changes in apollo-wind itself — this is a utility export. Visual fix is in the traceview-ui consumer PR.

Changes

  • New: src/lib/register-shadow-dom-properties.ts — extracts @property rules via regex, injects a single <style data-tw-property-rules> into document.head. Idempotent (DOM-based check).
  • New: src/lib/register-shadow-dom-properties.test.ts — 3 tests covering extraction, filtering, and no-op for CSS without @property.
  • Updated: src/lib/index.ts and src/index.ts — export registerCssPropertyRules from the root barrel.

Usage

import { registerCssPropertyRules } from '@uipath/apollo-wind';
import css from '@uipath/apollo-react/canvas/styles/tailwind.canvas.css?raw';

// Call once at app startup — idempotent, safe to call multiple times.
registerCssPropertyRules(css);

Follow-up

  • Discuss with Cristi whether apollo-wind should ship this registration automatically (e.g. as part of the CSS build or a dedicated shadow DOM entry point), rather than requiring each consumer to call it manually.

Testing

  • pnpm --filter @uipath/apollo-wind test passes (912 tests)
  • New unit tests cover extraction, filtering, and idempotency
  • Verified in traceview-ui Storybook: tooltips render fully styled inside shadow DOM after calling this helper

Copilot AI review requested due to automatic review settings June 16, 2026 16:10
@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (PT)
apollo-design 🟢 Ready Preview, Logs Jun 18, 2026, 03:39:14 PM
apollo-docs 🟢 Ready Preview, Logs Jun 18, 2026, 03:39:14 PM
apollo-landing 🟢 Ready Preview, Logs Jun 18, 2026, 03:39:14 PM
apollo-vertex 🟢 Ready Preview, Logs Jun 18, 2026, 03:39:14 PM

@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Dependency License Review

  • 1942 package(s) scanned
  • ✅ No license issues found
  • ⚠️ 2 package(s) excluded (see details below)
License distribution
License Packages
MIT 1712
ISC 89
Apache-2.0 55
BSD-3-Clause 27
BSD-2-Clause 23
BlueOak-1.0.0 8
MPL-2.0 4
MIT-0 3
CC0-1.0 3
MIT OR Apache-2.0 2
(MIT OR Apache-2.0) 2
Unlicense 2
LGPL-3.0-or-later 1
Python-2.0 1
CC-BY-4.0 1
(MPL-2.0 OR Apache-2.0) 1
Unknown 1
Artistic-2.0 1
(WTFPL OR MIT) 1
(BSD-2-Clause OR MIT OR Apache-2.0) 1
CC-BY-3.0 1
0BSD 1
(MIT OR CC0-1.0) 1
MIT AND ISC 1
Excluded packages
Package Version License Reason
@img/sharp-libvips-linux-x64 1.2.4 LGPL-3.0-or-later LGPL pre-built binary, not linked
khroma 2.1.0 Unknown MIT per GitHub repo, missing license field in package.json

const rules: string[] = [];
let match: RegExpExecArray | null;
PROPERTY_RE.lastIndex = 0;
while ((match = PROPERTY_RE.exec(css)) !== null) {

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

The new helper claims idempotency but the unit tests don’t currently assert the idempotent behavior, leaving a key behavior unverified.

Pull request overview

Adds a new @uipath/apollo-wind utility to support Tailwind v4 inside Shadow DOM by extracting @property at-rules from a CSS string and registering them globally via a single marker <style> in document.head.

Changes:

  • Introduces registerCssPropertyRules(css) to extract Tailwind @property rules and inject them once at the document level.
  • Adds unit tests verifying extraction and filtering behavior.
  • Exports the new utility from both the internal lib barrel and the public package entry point.
File summaries
File Description
packages/apollo-wind/src/lib/register-shadow-dom-properties.ts Implements registerCssPropertyRules with regex-based extraction and idempotent DOM marker injection.
packages/apollo-wind/src/lib/register-shadow-dom-properties.test.ts Adds tests for extraction, filtering, and (needs adjustment) idempotency coverage.
packages/apollo-wind/src/lib/index.ts Re-exports the helper from the lib barrel.
packages/apollo-wind/src/index.ts Re-exports the helper from the public API.

Copilot's findings

  • Files reviewed: 4/4 changed files
  • Comments generated: 2

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment on lines +44 to +49
it('does nothing when CSS has no @property rules', () => {
registerCssPropertyRules('.flex { display: flex; }');

expect(document.querySelector(SELECTOR)).toBeNull();
});
});
Comment thread packages/apollo-wind/src/lib/register-shadow-dom-properties.ts Outdated
@david-rios-uipath david-rios-uipath added the dev-packages Adds dev package publishing on pushes to this PR label Jun 18, 2026
@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

📦 Dev Packages

Package Status Updated (PT)
@uipath/apollo-wind@2.22.0-pr830.db4bd76 🟢 Published Jun 18, 2026, 03:38:02 PM

- Fix ReDoS: remove capturing group and use [^}]* instead of [^}]+
- Add idempotency test to verify only one style element is injected
@github-actions

Copy link
Copy Markdown
Contributor

📊 Coverage + size by package

Per-package coverage and bundle size on this PR. New-line coverage = of the source lines this PR adds or changes, the % hit by tests.

Package Coverage New-line coverage Packed (gzip) Unpacked vs main
@uipath/apollo-core 9.0% — (1 untracked) 43.82 MB 57.31 MB ±0
@uipath/apollo-react 35.0% 41.4% (151/365) 7.26 MB 27.53 MB ±0
@uipath/apollo-wind 38.9% 52.8% (28/53) 326.0 KB 2.23 MB +1.5 KB
@uipath/ap-chat 85.8% — (1 untracked) 43.36 MB 55.68 MB ±0

"Coverage" is each package's own coverage.include scope (e.g. apollo-core instruments only scripts/). "Packed"/"Unpacked" come from npm pack --dry-run and only cover built packages — "—" means not measured this run (package not affected / not built). "vs main" is the packed (gzipped) delta against the last successful main build (the package-sizes artifact from the Release workflow); "—" there means no main baseline was available this run. The baseline is main's latest build, not this PR's exact merge-base, so it includes any drift since the branch diverged. Packages with no vitest config are omitted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dev-packages Adds dev package publishing on pushes to this PR pkg:apollo-wind size:L 100-499 changed lines.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants