Skip to content

fix: Update flashing issue in popups and rtl placement#3729

Open
mannycarrera4 wants to merge 10 commits intoWorkday:masterfrom
mannycarrera4:mc-fix-popper-issues
Open

fix: Update flashing issue in popups and rtl placement#3729
mannycarrera4 wants to merge 10 commits intoWorkday:masterfrom
mannycarrera4:mc-fix-popper-issues

Conversation

@mannycarrera4
Copy link
Contributor

@mannycarrera4 mannycarrera4 commented Jan 30, 2026

Summary

Fixes: #3712,

Release Category

Components

Release Note

usePopupStack had two layout effects. The second one was called too late in the render, causing a flashing of styles in components like Select and Menu. The Popup also didn't account for switching placement when rtl is set. These fixes to handle forwarding rlt and switching placement of the popup.


Checklist

For the Reviewer

  • PR title is short and descriptive
  • PR summary describes the change (Fixes/Resolves linked correctly)
  • PR Release Notes describes additional information useful to call out in a release message or removed if not applicable
  • Breaking Changes provides useful information to upgrade to this code or removed if not applicable

Where Should the Reviewer Start?

Areas for Feedback? (optional)

  • Code
  • Documentation
  • Testing
  • Codemods

Testing Manually

Screenshots or GIFs (if applicable)

Thank You Gif (optional)

}
// No cleanup is needed if element or theme is not set, so return undefined (no effect)
return undefined;
}, [localRef, style, theme]);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This layout effect was happening too late, causing menu and select to flash on first render on the first focusable element. Moved this further up in the first uselayout effect

</Popup>
<div style={{display: 'flex', justifyContent: 'flex-start'}}>
<Popup model={model}>
<Popup.Target style={{visibility: 'hidden'}}></Popup.Target>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

when the target is hidden, it knows how to correctly position itself.

@cypress
Copy link

cypress bot commented Jan 30, 2026

Workday/canvas-kit    Run #10220

Run Properties:  status check passed Passed #10220  •  git commit ee2a255de4 ℹ️: Merge 072b267365a410a88cba5f0dbe13b9498b5eab35 into 2923fef0ae7a979a6e61178c5e8f...
Project Workday/canvas-kit
Branch Review mc-fix-popper-issues
Run status status check passed Passed #10220
Run duration 02m 22s
Commit git commit ee2a255de4 ℹ️: Merge 072b267365a410a88cba5f0dbe13b9498b5eab35 into 2923fef0ae7a979a6e61178c5e8f...
Committer Manuel Carrera
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 1
Tests that did not run due to a developer annotating a test with .skip  Pending 86
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 862
View all changes introduced in this branch ↗︎
UI Coverage  19.36%
  Untested elements 1539  
  Tested elements 367  
Accessibility  99.33%
  Failed rules  6 critical   5 serious   0 moderate   2 minor
  Failed elements 77  

@alanbsmith alanbsmith self-assigned this Jan 30, 2026
@mannycarrera4 mannycarrera4 marked this pull request as ready for review February 9, 2026 18:29
@mannycarrera4 mannycarrera4 added the ready for review Code is ready for review label Feb 9, 2026
@RayRedGoose RayRedGoose requested a review from Copilot February 10, 2026 23:42
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes visual flashing in popup-driven components by adjusting focus/positioning timing, and adds RTL-aware placement handling so popups flip left/right (and start/end) correctly when rendered in RTL contexts.

Changes:

  • Add RTL-aware placement/fallback placement flipping in Popper using dir from the popup stack container.
  • Adjust MenuItem focus class application timing to avoid premature focus styling during initial positioning.
  • Update RTL visual test story layout/target visibility to better exercise RTL placement behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
modules/react/popup/stories/visual-testing/Popup.stories.tsx Tweaks RTL visual test layout/target visibility for more reliable RTL placement screenshots.
modules/react/popup/lib/Popper.tsx Adds RTL placement + fallback placement flipping and applies it during Popper create/update.
modules/react/menu/lib/MenuItem.tsx Delays applying the focus class until after deferred focus to reduce initial style flash.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 190 to 197
React.useLayoutEffect(() => {
if (model.state.mode === 'single') {
if (isCursor(model.state, id)) {
// delay focus changes to allow PopperJS to position
requestAnimationFrame(() => {
localRef.current?.focus();
setCanShowFocus(true);
});
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

requestAnimationFrame callback calls setCanShowFocus(true) but the effect doesn’t cancel the RAF on cleanup. If the menu closes/unmounts before the frame fires, this can set state on an unmounted component (React warning) and potentially leak work. Store the RAF id and cancel it in the effect cleanup (and/or guard with a mounted ref).

Copilot uses AI. Check for mistakes.
Comment on lines +191 to +199
// Check RTL from the popup container (stackRef) to flip placements.
// Popper.js doesn't automatically flip left/right placements in RTL mode.
// We use stackRef because it has the dir attribute set by usePopupStack.
const isRTL = stackRef.current ? isElementRTL(stackRef.current) : false;
const rtlAwarePlacement = isRTL ? flipPlacementForRTL(popperPlacement) : popperPlacement;
const rtlAwareFallbackPlacements = isRTL
? fallbackPlacements.map(flipPlacementForRTL)
: fallbackPlacements;

Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

RTL placement flipping is new behavior in Popper, but there are existing unit tests for Popper behavior. Please add test coverage to assert that in an RTL container the passed placement and fallbackPlacements are flipped as expected (including *-start/*-end), and that the render-prop placement reflects the RTL-aware placement.

Copilot uses AI. Check for mistakes.
@mannycarrera4 mannycarrera4 added on hold PR is on hold until further notice and removed ready for review Code is ready for review labels Feb 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

on hold PR is on hold until further notice

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

fix: Menu flashes blue when first opened

2 participants

Comments