Skip to content

fix(tag-picker): keep dropdown list aligned during parent container motion#36376

Open
PaulGMardling wants to merge 10 commits into
microsoft:masterfrom
PaulGMardling:fix/tagpicker-dialog-misalignment
Open

fix(tag-picker): keep dropdown list aligned during parent container motion#36376
PaulGMardling wants to merge 10 commits into
microsoft:masterfrom
PaulGMardling:fix/tagpicker-dialog-misalignment

Conversation

@PaulGMardling

@PaulGMardling PaulGMardling commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Implementation Notes

I considered 3 paths to fix the stale position on reopen issue:

  1. Dialog-side signal (rejected).
    Expose a callback/state for when the Dialog entry animation finishes and defer rendering positioned content until it settles. Changes the Dialog API, pushes work onto every consumer, and only solves the dialog case.
  2. One-shot recalculation on animation end (rejected).
    Listen for animationend/transitionend on the ancestor and force a single update. Fragile: DialogSurface animates via the Web Animations API (no reliable transitionend), you have to guess which ancestor to watch, and the popover stays misaligned during the animation before snapping into place.
  3. Opt-in per-frame updates in react-positioning (chosen).
    Add an updatePositionOnAnimationFrame option to the shared position manager that re-evaluates position each frame while mounted, so the popover tracks its target regardless of what moved it. TagPicker opts in; everything else is unaffected.

I chose this solution because it's the smallest and most robust change. It defaults to false (no behavior change for existing components — only TagPicker enables it), and keeps the dropdown aligned throughout the animation rather than only after it ends. Because it's a general option on react-positioning rather than a Dialog - or TagPicker - specific hack, any positioned component that hits the same class of problem — a target moved by ancestor animation, transforms, or other motion that doesn't trigger scroll/resize observers — can opt in with a single flag instead of reimplementing the workaround.

Previous Behavior

Opening a TagPicker popover inside a Dialog could produce incorrect popup alignment after dialog reopen when content is rendered during dialog entry motion. The popup position could be computed from transient animated geometry and remain offset.

575848807-53749281-be36-4af8-a799-c7d5d3c136a2

New Behavior

TagPicker popover positioning now stays aligned with its trigger even when opened inside an animating Dialog surface. Positioning updates are refreshed during animation frames for this scenario, preventing stale offset coordinates on reopen.

Screen.Recording.2026-07-09.at.11.06.37.mov

Added/updated coverage:

  1. react-positioning unit coverage for animation-frame update behavior in createPositionManager.
  2. TagPicker Cypress regression coverage for dialog reopen alignment behavior.

Related Issue(s)

Fixes #35968

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

📊 Bundle size report

Package & Exports Baseline (minified/GZIP) PR Change
react-charts
AreaChart
404.329 kB
126.469 kB
404.555 kB
126.537 kB
226 B
68 B
react-charts
DeclarativeChart
754.978 kB
221.556 kB
755.204 kB
221.622 kB
226 B
66 B
react-charts
DonutChart
315.1 kB
97.161 kB
315.326 kB
97.22 kB
226 B
59 B
react-charts
FunnelChart
306.341 kB
93.907 kB
306.567 kB
93.977 kB
226 B
70 B
react-charts
GanttChart
387.386 kB
120.871 kB
387.612 kB
120.943 kB
226 B
72 B
react-charts
GaugeChart
314.433 kB
96.548 kB
314.659 kB
96.61 kB
226 B
62 B
react-charts
GroupedVerticalBarChart
395.54 kB
123.695 kB
395.766 kB
123.771 kB
226 B
76 B
react-charts
HeatMapChart
389.494 kB
121.928 kB
389.72 kB
121.994 kB
226 B
66 B
react-charts
HorizontalBarChart
294.866 kB
89.744 kB
295.092 kB
89.812 kB
226 B
68 B
react-charts
Legends
234.402 kB
70.454 kB
234.628 kB
70.53 kB
226 B
76 B
react-charts
LineChart
415.68 kB
129.602 kB
415.906 kB
129.667 kB
226 B
65 B
react-charts
PolarChart
343.353 kB
107.405 kB
343.579 kB
107.477 kB
226 B
72 B
react-charts
SankeyChart
212.023 kB
68.066 kB
212.249 kB
68.146 kB
226 B
80 B
react-charts
ScatterChart
395.006 kB
123.651 kB
395.232 kB
123.714 kB
226 B
63 B
react-charts
VerticalBarChart
431.938 kB
128.619 kB
432.164 kB
128.696 kB
226 B
77 B
react-charts
VerticalStackedBarChart
401.558 kB
125.102 kB
401.784 kB
125.174 kB
226 B
72 B
react-combobox
Combobox (including child components)
137.959 kB
44.618 kB
138.185 kB
44.694 kB
226 B
76 B
react-combobox
Dropdown (including child components)
137.715 kB
44.382 kB
137.941 kB
44.47 kB
226 B
88 B
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
225.836 kB
67.998 kB
226.062 kB
68.063 kB
226 B
65 B
react-components
react-components: entire library
1.293 MB
325.786 kB
1.293 MB
325.876 kB
260 B
90 B
react-datepicker-compat
DatePicker Compat
216.034 kB
63.912 kB
216.26 kB
63.987 kB
226 B
75 B
react-menu
Menu (including children components)
159.561 kB
50.654 kB
159.787 kB
50.72 kB
226 B
66 B
react-menu
Menu (including selectable components)
162.727 kB
51.291 kB
162.953 kB
51.356 kB
226 B
65 B
react-popover
Popover
125.312 kB
40.384 kB
125.538 kB
40.459 kB
226 B
75 B
react-positioning
usePositioning
28.795 kB
10.14 kB
29.021 kB
10.221 kB
226 B
81 B
react-tag-picker
@fluentui/react-tag-picker - package
173.82 kB
54.128 kB
174.08 kB
54.208 kB
260 B
80 B
react-teaching-popover
TeachingPopover
100.504 kB
31.752 kB
100.73 kB
31.835 kB
226 B
83 B
react-timepicker-compat
TimePicker
140.677 kB
45.99 kB
140.903 kB
46.073 kB
226 B
83 B
react-tooltip
Tooltip
53.023 kB
18.833 kB
53.249 kB
18.913 kB
226 B
80 B
Unchanged fixtures
Package & Exports Size (minified/GZIP)
react-avatar
Avatar
47.22 kB
14.855 kB
react-avatar
AvatarGroup
16.254 kB
6.502 kB
react-avatar
AvatarGroupItem
60.339 kB
18.758 kB
react-breadcrumb
@fluentui/react-breadcrumb - package
103.012 kB
28.827 kB
react-charts
HorizontalBarChartWithAxis
63 B
83 B
react-charts
Sparkline
80.888 kB
26.864 kB
react-checkbox
Checkbox
29.609 kB
10.527 kB
react-components
react-components: Button, FluentProvider & webLightTheme
66.281 kB
19.002 kB
react-components
react-components: FluentProvider & webLightTheme
39.504 kB
13.112 kB
react-dialog
Dialog (including children components)
89.951 kB
27.858 kB
react-field
Field
21.132 kB
7.881 kB
react-headless-components-preview
react-headless-components-preview: entire library
247.531 kB
71.417 kB
react-input
Input
25.027 kB
8.183 kB
react-list
List
74.531 kB
23.01 kB
react-list
ListItem
98.023 kB
29.881 kB
react-overflow
hooks only
9.052 kB
3.227 kB
react-persona
Persona
54.173 kB
16.791 kB
react-portal-compat
PortalCompatProvider
5.341 kB
2.146 kB
react-positioning
useSafeZoneArea
12.399 kB
4.977 kB
react-progress
ProgressBar
19.063 kB
7.418 kB
react-radio
Radio
26.994 kB
8.711 kB
react-radio
RadioGroup
12.759 kB
5.176 kB
react-select
Select
24.876 kB
8.936 kB
react-slider
Slider
32.231 kB
11.086 kB
react-spinbutton
SpinButton
32.513 kB
10.584 kB
react-swatch-picker
@fluentui/react-swatch-picker - package
92.187 kB
27.315 kB
react-switch
Switch
32.231 kB
10.156 kB
react-table
DataGrid
146.759 kB
43.576 kB
react-table
Table (Primitives only)
36.893 kB
12.305 kB
react-table
Table as DataGrid
118.503 kB
33.331 kB
react-table
Table (Selection only)
65.373 kB
18.591 kB
react-table
Table (Sort only)
64.036 kB
18.204 kB
react-tags
InteractionTag
12.463 kB
4.942 kB
react-tags
Tag
28.376 kB
8.9 kB
react-tags
TagGroup
69.648 kB
21.404 kB
react-textarea
Textarea
23.392 kB
8.447 kB
react-tree
FlatTree
135.571 kB
40.413 kB
react-tree
PersonaFlatTree
137.417 kB
40.931 kB
react-tree
PersonaTree
133.498 kB
39.718 kB
react-tree
Tree
131.658 kB
39.221 kB
🤖 This report was generated against 4aa1084999a8c1ac7245724ad6c76210fe80acf6

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

Pull request demo site: URL

@PaulGMardling

Copy link
Copy Markdown
Contributor Author

@PaulGMardling please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.

@microsoft-github-policy-service agree [company="{your company}"]

Options:

  • (default - no company specified) I have sole ownership of intellectual property rights to my Submissions and I am not making Submissions in the course of work for my employer.
@microsoft-github-policy-service agree
  • (when company given) I am making Submissions in the course of work for my employer (or my employer has intellectual property rights in my Submissions by contract or applicable law). I have permission from my employer to make Submissions and enter into this Agreement on behalf of my employer. By signing below, the defined term “You” includes me and my employer.
@microsoft-github-policy-service agree company="Microsoft"

Contributor License Agreement

@microsoft-github-policy-service agree company="Microsoft"

@microsoft microsoft deleted a comment from github-actions Bot Jul 9, 2026
@@ -0,0 +1,106 @@
import * as React from 'react';

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This file will be removed before merging.

It was used to demo the changes locally

@microsoft microsoft deleted a comment from github-actions Bot Jul 9, 2026
@PaulGMardling PaulGMardling changed the title fix(tag-picker): keep popup aligned during dialog motion fix(tag-picker): keep dropdown list aligned during dialog motion Jul 10, 2026
@PaulGMardling
PaulGMardling force-pushed the fix/tagpicker-dialog-misalignment branch from 5a868e9 to 56b1d30 Compare July 10, 2026 12:39
@@ -0,0 +1,7 @@
{

@github-actions github-actions Bot Jul 10, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🕵🏾‍♀️ visual changes to review in the Visual Change Report

vr-tests-react-components/Menu Converged - submenuIndicator slotted content 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Menu Converged - submenuIndicator slotted content.default - RTL.submenus open.chromium.png 404 Changed
vr-tests-react-components/Menu Converged - submenuIndicator slotted content.default.submenus open.chromium.png 413 Changed
vr-tests-react-components/Positioning 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Positioning.Positioning end.chromium.png 16 Changed
vr-tests-react-components/Positioning.Positioning end.updated 2 times.chromium.png 44 Changed
vr-tests-react-components/ProgressBar converged 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness - Dark Mode.default.chromium.png 59 Changed
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness - High Contrast.default.chromium.png 158 Changed
vr-tests-react-components/TagPicker 3 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/TagPicker.disabled - High Contrast.chromium.png 1319 Changed
vr-tests-react-components/TagPicker.disabled - RTL.disabled input hover.chromium.png 635 Changed
vr-tests-react-components/TagPicker.disabled.chromium.png 677 Changed

There were 3 duplicate changes discarded. Check the build logs for more information.

@PaulGMardling
PaulGMardling marked this pull request as ready for review July 10, 2026 13:32
@PaulGMardling
PaulGMardling requested a review from a team as a code owner July 10, 2026 13:32
@PaulGMardling PaulGMardling changed the title fix(tag-picker): keep dropdown list aligned during dialog motion fix(tag-picker): keep dropdown list aligned during parent container motion Jul 13, 2026
@PaulGMardling
PaulGMardling force-pushed the fix/tagpicker-dialog-misalignment branch from 56b1d30 to fe08ac5 Compare July 13, 2026 08:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: TagPicker dropdown misaligned when opened inside Dialog with entry animation

1 participant