Skip to content

fix: restore TeachingPopover navigation and close focus - #36719

Open
Paul Mardling (PaulGMardling) wants to merge 2 commits into
masterfrom
paulgmardling-teachingpopover-focus-fixes
Open

fix: restore TeachingPopover navigation and close focus#36719
Paul Mardling (PaulGMardling) wants to merge 2 commits into
masterfrom
paulgmardling-teachingpopover-focus-fixes

Conversation

@PaulGMardling

Copy link
Copy Markdown
Contributor

Previous Behavior

Returning to the first carousel step with previous.altText: null could leave focus on a hidden Previous button rather than moving to Next. Headless TeachingPopover also relied on native popover focus restoration: React-driven closure removes the surface before the native hide algorithm can restore focus. This particularly affects initially-open controlled tours and the final Got it action.

New Behavior

  • Shared headless usePopover restores trigger focus after a real open-to-closed transition when focus has fallen back to the document body. Initially closed mounts do not acquire focus, triggerless popovers are safe, and deliberate focus on an outside control is preserved.
  • Shared TeachingPopover carousel/base FooterButton hooks register navigation refs and transfer focus to the opposite button when null/undefined alternate content hides the focused navigation button. Both styled TeachingPopover and downstream headless wrappers inherit this; no consumer focus effect is required.
  • Hidden navigation is reflected in root props and respected by styled FooterButton CSS. Existing user refs and focus handlers are preserved.
  • Added Jest and real-browser regressions for controlled/uncontrolled navigation, initially-open tours, Got it with value reset before closure, Escape, dismissal, modal mode, rejected controlled finish, triggerless tours, and intentional outside focus.

Validation: both affected packages build and type-check successfully; package lint passes (one pre-existing unrelated ToastTitle warning). Full package Jest run: 1,478 passing; final focused rerun: 365 passing. Chrome: 67 headless and 13 styled tests pass. Three pre-existing non-click hover/context focus tests remain skipped; their native interaction timing is outside this fix. API generation completed without report changes. Patch changefiles are included for both packages.

Two-part delivery and release dependency

This is part 1: component-owned upstream fixes. Part 2 is a separate 1JS integration draft that removes the Lesson workaround and adds consumer regression coverage; it must remain blocked until these fixes are actually published and consumed.

Current source versions are @fluentui/react-headless-components-preview@0.2.5 and @fluentui/react-teaching-popover@9.7.5. Headless already depends on the base teaching package through ^9.7.5, which admits a future 9.x patch without a manual range change. However, an existing downstream lockfile may retain the old base package: integration must resolve both fixed packages, including the newly released headless package for close-focus restoration. This PR does not invent a release version or claim currently published packages contain these fixes.

Related Issue(s)

  • Part 1 of the two-part fix for ADO work item 39652. The work item should not be considered fully delivered until downstream integration consumes the released fixes.

Handle lost focus after headless popover closure and transfer carousel navigation focus when alternate content hides the active button.

Related: https://dev.azure.com/microsoftdesign/fluent-ui/_workitems/edit/39652

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

📊 Bundle size report

Package & Exports Baseline (minified/GZIP) PR Change
react-components
react-components: all base hooks
217.893 kB
68.338 kB
218.673 kB
68.577 kB
780 B
239 B
react-components
react-components: entire library
1.283 MB
322.086 kB
1.284 MB
322.384 kB
879 B
298 B
react-headless-components-preview
react-headless-components-preview: entire library
242.029 kB
68.213 kB
243.005 kB
68.517 kB
976 B
304 B
react-headless-components-preview
@fluentui/react-headless-components-preview/teaching-popover
36.073 kB
12.006 kB
37.035 kB
12.319 kB
962 B
313 B
Unchanged fixtures
Package & Exports Size (minified/GZIP)
react-components
react-components: Button, FluentProvider & webLightTheme
67.471 kB
19.465 kB
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
227.136 kB
68.41 kB
react-components
react-components: FluentProvider & webLightTheme
40.694 kB
13.549 kB
react-headless-components-preview
@fluentui/react-headless-components-preview/tag-picker
54.012 kB
17.756 kB
react-portal-compat
PortalCompatProvider
5.341 kB
2.146 kB
react-teaching-popover
TeachingPopover
101.77 kB
32.204 kB
react-timepicker-compat
TimePicker
142.037 kB
46.44 kB
🤖 This report was generated against 43665d5fb41408837ad1e85eb662575da9e0c4d0

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

Pull request demo site: URL

@@ -0,0 +1,6 @@
{

@github-actions github-actions Bot Sep 9, 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 10 Changed
vr-tests-react-components/Positioning.Positioning end.updated 2 times.chromium.png 139 Changed
vr-tests-react-components/ProgressBar converged 3 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness - Dark Mode.default.chromium.png 43 Changed
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness - High Contrast.default.chromium.png 67 Changed
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness.default.chromium.png 147 Changed
vr-tests-react-components/TagPicker 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/TagPicker.disabled - RTL.chromium.png 635 Changed
vr-tests-react-components/TagPicker.disabled.disabled input hover.chromium.png 677 Changed

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

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@PaulGMardling
Paul Mardling (PaulGMardling) marked this pull request as ready for review September 10, 2026 13:27
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.

1 participant