aidenybai / aidenybai/react-scan

0.5.7 overlay toggle switch (and other translate/rotate utilities) render broken: Tailwind v4 @property rules unregistered inside shadow DOM

Aperta
#463 0 commenti 1 reazione 0 assegnatari Vedi su GitHub
Lingua principale
TypeScript
Stelle
21.8k
Fork
390
Merge medio
23m
PR unite (30g)
1

Descrizione

## Symptom

In `react-scan@0.5.7`, overlay UI utilities that rely on Tailwind v4's `translate` / `rotate` / `scale` shorthand render incorrectly. The most visible symptom is the outline-render toggle switch: in the OFF state the white thumb pops out of the track and hangs below it. The same class of bug affects the resize handles, slider thumb, and expand arrow — anywhere the overlay CSS uses `@apply -translate-*` / `translate-*`.

Reproduction on Chrome 149 with a Tailwind v4 host (also reproduces with a non-Tailwind host, verified against a Panda CSS project — the host stylesheet is irrelevant since the overlay is inside a shadow DOM).

Downgrading to `react-scan@0.5.6` restores correct rendering (v0.5.6 is on Tailwind v3, which uses preflight-seeded `--tw-translate-*` rather than `@property`).

## Screenshots

Image

## Root cause

React Scan mounts its overlay UI in a shadow DOM and injects the bundled Tailwind stylesheet as a `` element inside that shadow root ([`packages/scan/src/core/index.ts`](https://github.com/aidenybai/react-scan/blob/main/packages/scan/src/core/index.ts#L33-L51)). Tailwind v3 → v4 in 0.5.7 changed how `-translate-y-1/2` etc. compile: instead of the preflight-seeded `--tw-translate-*` variables, v4 emits 62 `@property` rules to declare the `initial-value` (0).

Chromium does not register `@property` rules declared inside a shadow-DOM stylesheet. The CSSOM parses them into `CSSPropertyRule`s (visible via `stylesheet.cssRules`), but the custom-property registry is empty for that shadow tree. Consequently `--tw-translate-x` has no computed value, and

```css
translate: var(--tw-translate-x) var(--tw-translate-y);
```

collapses to `translate: none`.

Measurement on `.react-scan-toggle > div::before` in the OFF state (react-scan 0.5.7, Chrome 149):

| property | value |
| --- | --- |
| `translate` | `none` |
| `--tw-translate-x` | `""` (empty) |
| `--tw-translate-y` | `calc(calc(1 / 2 * 100%) * -1)` |

For the ON state, the `input:checked + div::before` selector applies `translate-x-full` which explicitly sets `--tw-translate-x: 100%`, so translate resolves — that's why the ON state visually looks OK while OFF is broken.

Document-level `@property` registrations *do* cascade into a shadow tree, verified in a minimal repro on Chrome 149.

Spec: [CSS Properties and Values API L1](https://drafts.css-houdini.org/css-properties-values-api/).

## Proposed fix (branch available)

I have a one-file fix on my fork:
[`hidenari-pixel/react-scan@fix/shadow-dom-property-registration`](https://github.com/hidenari-pixel/react-scan/tree/fix/shadow-dom-property-registration) ([diff](https://github.com/aidenybai/react-scan/compare/main...hidenari-pixel:react-scan:fix/shadow-dom-property-registration))

Approach: in `initRootContainer()`, extract every `@property --…{…}` block from the bundled overlay CSS with a regex before injecting the stylesheet into the shadow root, and mount just those rules under a `<style data-react-scan="property-registrations">` in `document.head`. The remainder still goes into the shadow root as before.

After the fix, the same `::before` in the OFF state resolves to:

| property | value |
| --- | --- |
| `translate` | `0px -50%` |
| `--tw-translate-x` | `0` |
| `--tw-translate-y` | `calc(calc(1 / 2 * 100%) * -1)` |

and 62/62 `@property` rules move from the shadow tree to `document.head`.

- Change is ~14 lines in `packages/scan/src/core/index.ts` plus a changeset entry
- `pnpm --filter react-scan build` succeeds
- `pnpm test:e2e` — 47/47 pass, including the outline toggle instrumentation specs from #459
- Manual verification in `kitchen-sink` on Chrome 149: toggle thumb renders centered in both OFF and ON states

## Note

I tried to open this as a PR but hit "An owner of this repository has limited the ability to open a pull request to users that are collaborators on this repository." Happy to open the PR the moment the interaction limit is lifted, or invited as a collaborator, or feel free to cherry-pick the commit directly:

```
git remote add hidenari-pixel https://github.com/hidenari-pixel/react-scan.git
git fetch hidenari-pixel fix/shadow-dom-property-registration
git cherry-pick 2407c8b
```

Related open work: PR #458 (React port of the toolbar UI) may incidentally sidestep this if it moves off Tailwind v4 utility classes, but it is still open and orthogonal.

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.