diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 049863f7bee050..9b343c2422f675 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -22,6 +22,7 @@ - `Guide`, `Modal`: Restore accent color themability ([#58098](https://github.com/WordPress/gutenberg/pull/58098)). - `DropdownMenuV2`: Restore accent color themability ([#58130](https://github.com/WordPress/gutenberg/pull/58130)). - `Tabs`: improve controlled mode focus handling and keyboard navigation ([#57696](https://github.com/WordPress/gutenberg/pull/57696)). +- `Tabs`: prevent internal focus from updating too early ([#58625](https://github.com/WordPress/gutenberg/pull/58625)). - Expand theming support in the `COLORS` variable object ([#58097](https://github.com/WordPress/gutenberg/pull/58097)). ### Enhancements diff --git a/packages/components/src/tabs/index.tsx b/packages/components/src/tabs/index.tsx index e8e9bff76b3e92..4573f7a6968df9 100644 --- a/packages/components/src/tabs/index.tsx +++ b/packages/components/src/tabs/index.tsx @@ -164,23 +164,25 @@ function Tabs( { return; } - const focusedElement = - items?.[ 0 ]?.element?.ownerDocument.activeElement; - - if ( - ! focusedElement || - ! items.some( ( item ) => focusedElement === item.element ) - ) { - return; // Return early if no tabs are focused. - } + requestAnimationFrame( () => { + const focusedElement = + items?.[ 0 ]?.element?.ownerDocument.activeElement; + + if ( + ! focusedElement || + ! items.some( ( item ) => focusedElement === item.element ) + ) { + return; // Return early if no tabs are focused. + } - // If, after ariakit re-computes the active tab, that tab doesn't match - // the currently focused tab, then we force an update to ariakit to avoid - // any mismatches, especially when navigating to previous/next tab with - // arrow keys. - if ( activeId !== focusedElement.id ) { - setActiveId( focusedElement.id ); - } + // If, after ariakit re-computes the active tab, that tab doesn't match + // the currently focused tab, then we force an update to ariakit to avoid + // any mismatches, especially when navigating to previous/next tab with + // arrow keys. + if ( activeId !== focusedElement.id ) { + setActiveId( focusedElement.id ); + } + } ); }, [ activeId, isControlled, items, setActiveId ] ); const contextValue = useMemo(