Skip to content

fix(Tunnel): render tunnelled children in the first commit - #3022

Open
mfal wants to merge 1 commit into
mainfrom
fix/accessible-names-3015
Open

fix(Tunnel): render tunnelled children in the first commit#3022
mfal wants to merge 1 commit into
mainfrom
fix/accessible-names-3015

Conversation

@mfal

@mfal mfal commented Aug 31, 2026

Copy link
Copy Markdown
Member

Part of #3015. Split out of the original PR: this one carries only the react-tunnel defect and its tests. The docs and story fixes moved to #3050.

The defect: react-tunnel dropped tunnelled children from the first commit

Slider tunnels its <Label> into the value row. TunnelExit fell back to render-phase children only while useIsSSR() was true — never the case on a client-only mount. So the first commit contained no <label> at all, react-aria's useSlot concluded there was none, and warned. The slider genuinely had no accessible name until the next render.

Introduced in de72c80 (#2827), which replaced the ungated getEntries(id) with an isSsr-gated read and so kept only the server half of the bridge its own comment describes. The fix restores the client half: the flag is flipped in a layout effect, never during render, so repeated render invocations before a commit (StrictMode double-invoke, concurrent re-render) all read the same value and SSR hydration stays free of mismatches. From the first commit on, the committed children stay authoritative — even when empty.

This affects every tunnelled slot, not just Slider.

Verified

  • Both new tests are red without the fix and green with it.
  • pnpm nx test:browser react-tunnel 23/23 on this branch, rebased onto current main (1.1.4).
  • eslint + prettier clean on every changed file.

No visual test was added: the settled DOM is unchanged — only the first pre-paint frame differs. run-visual-tests is on this PR so the suite confirms that rather than us assuming it.

🤖 Generated with Claude Code

@mfal
mfal requested a review from a team August 31, 2026 09:09
@mfal mfal added the run-visual-tests Runs the full visual regression suite against the existing baselines and fails the check on mismatch label Aug 31, 2026
@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for ./packages/components/

Status Category Percentage Covered / Total
🔵 Lines 78.69% 746 / 948
🔵 Statements 78.57% 763 / 971
🔵 Functions 80.09% 165 / 206
🔵 Branches 70.33% 377 / 536
File CoverageNo changed files found.
Generated in workflow #6561 for commit 75053fa by the Vitest Coverage Report Action

@github-actions github-actions Bot removed the run-visual-tests Runs the full visual regression suite against the existing baselines and fails the check on mismatch label Aug 31, 2026
@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

✅ Visual Regression Tests Passed

All visual snapshots match the committed baselines.

Run details

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Preview Deployment

Preview environments are ready:

Type URL
docs pr-3022.docs.review.flow-components.de
storybook pr-3022.storybook.review.flow-components.de

Images:

  • docs: ghcr.io/mittwald/flow/docs:pr-3022
  • storybook: ghcr.io/mittwald/flow/storybook:pr-3022

@github-actions

Copy link
Copy Markdown
Contributor

✅ Cross-Version Tests Passed

The current host still renders old published remote versions correctly (iframe) and in the same DOM shape (in-process).

Iframe harness (attribute-accurate): ✅ passed

In-process harness (structure-only): ✅ passed

Run details

@mfal
mfal force-pushed the fix/accessible-names-3015 branch from 6b561a3 to 20099a5 Compare September 1, 2026 11:42
@mfal mfal changed the title fix(Tunnel): render tunnelled children in the first commit (fixes #3015) fix(Tunnel): render tunnelled children in the first commit (part of #3015) Sep 1, 2026
@mfal mfal added the run-visual-tests Runs the full visual regression suite against the existing baselines and fails the check on mismatch label Sep 1, 2026
@mfal mfal self-assigned this Sep 1, 2026
@github-actions github-actions Bot removed the run-visual-tests Runs the full visual regression suite against the existing baselines and fails the check on mismatch label Sep 1, 2026
@mfal
mfal requested a review from ins0 September 1, 2026 11:49
@mfal

mfal commented Sep 1, 2026

Copy link
Copy Markdown
Member Author

Two different failures in one shard — and one of them may not be this branch's

run-visual-tests (4) reports 109 capture timeouts and 3 real pixel diffs. Those need separating.

The 109 are infrastructure, not this PR

All of them are Could not capture a stable screenshot within 5000ms, with no comparison performed, spread across unrelated components. The runner is the cause: this shard spent 815 s in tests against ~80 s on a healthy run. The same signature is currently on main itself (run 33503916049, one shard red, one capture timeout, zero pixel diffs), on #3025 (84 timeouts in one shard), and it aborted #3025's update-screenshots run mid-step. Hundreds of timeouts across several PRs and main, zero pixel diffs among them.

Worth naming: while the runners are this slow, the update-screenshots label is actively dangerous — it runs --update over the whole suite and commits whatever it captures. On #3025 the update step failed before the commit step, which is the only reason nothing was written. That was luck, not a safeguard.

The 3 are real, and probably predate this branch

List empty search views, firefox only (so the dark theme), in (Local) and (Remote), 3256 px / ratio 0.01. Both environments failing together is the signature of a genuine difference rather than a race — a race costs one environment, per this package's own scenarioFocus.ts.

But the likely cause may be main, not this branch:

So a firefox-only regression from #3046 would currently be invisible on main and would surface on the first branch whose label run touches firefox — which is this one.

The decisive test costs one run: trigger the visual suite with firefox on current main (scheduled workflow, or the label on a no-op PR). If List empty search views fails there too, it belongs to #3046 and not here.

I have not re-run anything for the 109, since with the runners in this state a rerun is a coin flip rather than a fix.

🤖 Addressed by Claude Code

@mfal mfal changed the title fix(Tunnel): render tunnelled children in the first commit (part of #3015) fix(Tunnel): render tunnelled children in the first commit Sep 2, 2026
A `TunnelExit` mounting on the client rendered nothing until the entries
had committed, so tunnelled content arrived one commit late. Anything that
inspects the DOM in a layout effect only ever sees the first commit —
react-aria's `useSlot` decides there whether a slotted `<Label>` exists.
For `Slider`, whose `<Label>` is tunnelled into the value row, it decided
"no label": the slider had no accessible name on first paint and react-aria
warned in every dev run (#3015).

The render-phase children were built as exactly that bridge, but the exit
only opted into them while `useIsSSR()` was true, which is never the case
in a client-only mount. Opt in before the first commit as well. The flag
flips in a layout effect, never during render, so repeated render
invocations before a commit stay idempotent and SSR hydration keeps
matching.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@mfal
mfal force-pushed the fix/accessible-names-3015 branch from 20099a5 to 75053fa Compare September 2, 2026 11:53
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.

2 participants