diff --git a/src/components/UncontrolledTabs.jsx b/src/components/UncontrolledTabs.jsx
index 8e802b71d2..478ca4df61 100644
--- a/src/components/UncontrolledTabs.jsx
+++ b/src/components/UncontrolledTabs.jsx
@@ -4,7 +4,7 @@ import cx from 'clsx';
import { childrenPropType } from '../helpers/propTypes';
import { getTabsCount as getTabsCountHelper } from '../helpers/count';
import { deepMap } from '../helpers/childrenDeepMap';
-import { isTabList, isTabPanel, isTab } from '../helpers/elementTypes';
+import { isTabList, isTabPanel } from '../helpers/elementTypes';
function isNode(node) {
return node && 'getAttribute' in node;
@@ -212,9 +212,9 @@ const UncontrolledTabs = (props) => {
const env =
environment || (typeof window !== 'undefined' ? window : undefined);
if (canUseActiveElement && env) {
- wasTabFocused = React.Children.toArray(child.props.children)
- .filter(isTab)
- .some((tab, i) => env.document.activeElement === getTab(i));
+ wasTabFocused = Object.keys(tabNodes.current).some(
+ (key) => env.document.activeElement === tabNodes.current[key],
+ );
}
result = cloneElement(child, {
diff --git a/src/components/__tests__/Tabs-test.jsx b/src/components/__tests__/Tabs-test.jsx
index 8010cb8efd..e917844925 100644
--- a/src/components/__tests__/Tabs-test.jsx
+++ b/src/components/__tests__/Tabs-test.jsx
@@ -592,6 +592,52 @@ describe('', () => {
expect(inputField).toHaveFocus();
});
+ test('should retain tab focus when controlled tabs are inside a fragment', () => {
+ const renderTabs = (selectedIndex) => (
+ {}}>
+
+ <>
+ First
+ Second
+ >
+
+ First panel
+ Second panel
+
+ );
+ const { rerender } = render(renderTabs(0));
+ screen.getByRole('tab', { name: 'First' }).focus();
+
+ rerender(renderTabs(1));
+
+ expect(screen.getByRole('tab', { name: 'Second' })).toHaveFocus();
+ });
+
+ test('should preserve outside focus when controlled tabs are inside a fragment', () => {
+ const renderTabs = (selectedIndex) => (
+ <>
+
+ {}}>
+
+ <>
+ First
+ Second
+ >
+
+ First panel
+ Second panel
+
+ >
+ );
+ const { rerender } = render(renderTabs(0));
+ const input = screen.getByRole('textbox', { name: 'Outside' });
+ input.focus();
+
+ rerender(renderTabs(1));
+
+ expect(input).toHaveFocus();
+ });
+
test('should not change tabs when arrow up/down is pressed and disableUpDownKeys is passed', async () => {
render(
createTabs({