Skip to content

fix(ui-motion): stop leaking elementRef onto emotion-wrapped DOM children - #2672

Merged
balzss merged 1 commit into
masterfrom
fix/ui-motion-elementref-emotion
Aug 25, 2026
Merged

balzss merged 1 commit into
masterfrom
fix/ui-motion-elementref-emotion

Conversation

@balzss

@balzss balzss commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

Any <Transition> child written with a css prop logs:

Warning: React does not recognize the `elementRef` prop on a DOM element.
    at span
    at BaseTransition
    at Transition -> DrawerTray -> DrawerLayout

BaseTransition treated typeof child.type === 'object' as "withStyle-decorated InstUI component". That's true of every forwardRef wrapper, including the one emotion's jsx runtime puts around any element carrying a css prop — and emotion forwards unknown props straight to the DOM node. Tray, DrawerTray, RatingIcon v2 and Modal (constrain="parent") each render such a child.

Changes

Narrow the check to children that actually declare elementRef in allowedProps. Emotion's wrapper doesn't, so <div css={...}> takes the plain ref path; a withStyle child keeps the chained elementRef.

This is deliberately not a revert of #2618 — reverting renderChildren brings back the ref is not a prop warning that PR fixed, verified by trying it rather than assuming. Two tests bracket the fix so neither behaviour can regress into the other.

Test Plan

  • ui-motion passes, as do ui-tray ui-drawer-layout ui-modal ui-rating ui-overlays ui-toggle-details ui-tabs ui-popover and the browser project. build:types clean.
  • Both failure modes checked by temporarily swapping the implementation back.
  • Docs app with devtools open: Alert dismiss/re-add and all three DrawerLayout trays — clean console, no elementref attributes in the DOM.

Fixes INSTUI-5139

Supersedes #2667, which proposed the same allowedProps gate.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-08-25 10:01 UTC

@balzss
balzss force-pushed the fix/ui-motion-elementref-emotion branch from 7069332 to 56fa2c9 Compare July 31, 2026 11:56
@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Visual regression report

Cypress suite:Failing — see the run logs.

Visual diff:No changes.

Status Count
Unchanged 96
Changed 0
New 0
Removed 0

Accessibility (axe): ⚠️ 15 violations on 7 screenshots.

Impact Issue Rule Elements Screenshots
serious Text contrast is too low color-contrast 15 7

📊 View full report — click a screenshot's ⚠ badge to see each violation boxed on the image, with the offending element named and contrast failures shown as color swatches.

Baselines come from the visual-baselines branch. They refresh on every merge to master. The Cypress suite line covers the a11y and console-error assertions — a ❌ there means the suite found real issues even if the visual diff is clean.

})
})

// LX-4014 (#2618): a withStyle child plus an actually-running transition

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Remove this ticket reference from the comment

this.handleRef(
el instanceof Element ? el : (findDOMNode(el) as Element) ?? null
)
// InstUI components expose an `elementRef` prop, which hands back the DOM

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Rewrite this comment without Claude please, it is quite messy

const refIsNotAPropWarnings = (mock: MockInstance) =>
warningsMatching(mock, /`?ref`? is not a prop/)

// The repo compiles JSX with `jsxImportSource: '@emotion/react'`, so a child

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't understand how this comment helps understanding these tests

@balzss
balzss force-pushed the fix/ui-motion-elementref-emotion branch from 56fa2c9 to 1fc61c5 Compare August 13, 2026 12:11
@balzss
balzss requested review from ToMESSKa and joyenjoyer August 13, 2026 12:12
@balzss
balzss force-pushed the fix/ui-motion-elementref-emotion branch from 1fc61c5 to 0ad4b99 Compare August 13, 2026 12:23
Comment on lines +344 to +346
// Only children that declare `elementRef` get one. `typeof child.type ===
// 'object'` also matches emotion's wrapper around `<div css={...}>`, which
// forwards it to the DOM.

@ToMESSKa ToMESSKa Aug 14, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this comment might be confusing as it references the old check which is no longer here.

@balzss
balzss force-pushed the fix/ui-motion-elementref-emotion branch from 0ad4b99 to 93f0688 Compare August 17, 2026 07:38
@balzss
balzss requested a review from ToMESSKa August 17, 2026 09:22
@balzss
balzss force-pushed the fix/ui-motion-elementref-emotion branch from 93f0688 to 9db61c6 Compare August 17, 2026 11:16
github-actions Bot pushed a commit that referenced this pull request Aug 17, 2026

@joyenjoyer joyenjoyer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you simplify the commit message body? It is overly verbose and reference canvas-rce tests and LX-4014, it is too long and adds no value.

BaseTransition used `typeof child.type === 'object'` to detect
withStyle-decorated InstUI components, but that also matches emotion's
wrapper around any element with a `css` prop, and emotion forwards
unknown props to the DOM: "React does not recognize the `elementRef`
prop on a DOM element." Tray, DrawerTray, RatingIcon v2 and Modal
(constrain="parent") all render such a child.

Gate the elementRef branch on the child declaring `elementRef` in
`allowedProps` instead. Not a revert of #2618 — reverting brings back
the warning that PR fixed, so tests cover both.

INSTUI-5139

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@balzss
balzss force-pushed the fix/ui-motion-elementref-emotion branch from 9db61c6 to ef57440 Compare August 24, 2026 10:41
github-actions Bot pushed a commit that referenced this pull request Aug 24, 2026
@balzss
balzss requested review from joyenjoyer and removed request for ToMESSKa August 25, 2026 08:26
@balzss
balzss requested a review from ToMESSKa August 25, 2026 09:31
@balzss
balzss dismissed ToMESSKa’s stale review August 25, 2026 09:58

Dismissing stale review: the comment ToMESSKa flagged (the typeof type === 'object' note) was removed — that code path no longer exists in the current implementation. Current head ef57440 is approved by joyenjoyer and HerrTopi.

@balzss
balzss merged commit 9142976 into master Aug 25, 2026
10 of 11 checks passed
@balzss
balzss deleted the fix/ui-motion-elementref-emotion branch August 25, 2026 10:00
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.

4 participants