diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 31ad5b0457d7ef..bf32aadd73ff5a 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -5,6 +5,7 @@ ### Bug Fix - `FontSizePicker`: Ensure that fluid font size presets appear correctly in the UI controls ([#44791](https://github.com/WordPress/gutenberg/pull/44791)) +- `Navigator`: restore focus only once per location ([#44972](https://github.com/WordPress/gutenberg/pull/44972)). - The `LinkedButton` to unlink sides in `BoxControl`, `BorderBoxControl` and `BorderRadiusControl` have changed from a rectangular primary button to an icon-only button, with a sentence case tooltip, and default-size icon for better legibility. The `Button` component has been fixed so when `isSmall` and `icon` props are set, and no text is present, the button shape is square rather than rectangular. - `Popover`: fix limitShift logic by adding iframe offset correctly [#42950](https://github.com/WordPress/gutenberg/pull/42950)). diff --git a/packages/components/src/navigator/navigator-provider/component.tsx b/packages/components/src/navigator/navigator-provider/component.tsx index 634c6f8204b10e..fc769f2f5736ca 100644 --- a/packages/components/src/navigator/navigator-provider/component.tsx +++ b/packages/components/src/navigator/navigator-provider/component.tsx @@ -49,6 +49,7 @@ function NavigatorProvider( ...options, path, isBack: false, + hasRestoredFocus: false, }, ] ); }, @@ -62,6 +63,7 @@ function NavigatorProvider( { ...locationHistory[ locationHistory.length - 2 ], isBack: true, + hasRestoredFocus: false, }, ] ); } diff --git a/packages/components/src/navigator/navigator-screen/component.tsx b/packages/components/src/navigator/navigator-screen/component.tsx index 94b7bfee306e97..092b95b50d97f6 100644 --- a/packages/components/src/navigator/navigator-screen/component.tsx +++ b/packages/components/src/navigator/navigator-screen/component.tsx @@ -79,7 +79,13 @@ function NavigatorScreen( props: Props, forwardedRef: ForwardedRef< any > ) { // - if the current location is not the initial one (to avoid moving focus on page load) // - when the screen becomes visible // - if the wrapper ref has been assigned - if ( isInitialLocation || ! isMatch || ! wrapperRef.current ) { + // - if focus hasn't already been restored for the current location + if ( + isInitialLocation || + ! isMatch || + ! wrapperRef.current || + location.hasRestoredFocus + ) { return; } @@ -103,10 +109,12 @@ function NavigatorScreen( props: Props, forwardedRef: ForwardedRef< any > ) { elementToFocus = firstTabbable ?? wrapperRef.current; } + location.hasRestoredFocus = true; elementToFocus.focus(); }, [ isInitialLocation, isMatch, + location.hasRestoredFocus, location.isBack, previousLocation?.focusTargetSelector, ] ); diff --git a/packages/components/src/navigator/types.ts b/packages/components/src/navigator/types.ts index edc80c356e18e5..217b9408923374 100644 --- a/packages/components/src/navigator/types.ts +++ b/packages/components/src/navigator/types.ts @@ -11,6 +11,7 @@ export type NavigatorLocation = NavigateOptions & { isInitial?: boolean; isBack?: boolean; path?: string; + hasRestoredFocus?: boolean; }; export type NavigatorContext = {