From a6b4c22e1055e7c77eca66e38ebde47df4bbd8b1 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Fri, 18 Oct 2024 15:51:34 +0200 Subject: [PATCH] Add Ariakit workaround while waiting to update to new version --- packages/components/src/tabs/tab.tsx | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/packages/components/src/tabs/tab.tsx b/packages/components/src/tabs/tab.tsx index 29f6111adc8397..70f56e52ad2627 100644 --- a/packages/components/src/tabs/tab.tsx +++ b/packages/components/src/tabs/tab.tsx @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import * as Ariakit from '@ariakit/react'; + /** * WordPress dependencies */ @@ -22,13 +27,27 @@ export const Tab = forwardRef< HTMLButtonElement, Omit< WordPressComponentProps< TabProps, 'button', false >, 'id' > >( function Tab( { children, tabId, disabled, render, ...otherProps }, ref ) { - const context = useTabsContext(); - if ( ! context ) { + const { store, instanceId } = useTabsContext() ?? {}; + + // If the active item is not connected, the tablist may end up in a state + // where none of the tabs are tabbable. In this case, we force all tabs to + // be tabbable, so that as soon as an item received focus, it becomes active + // and Tablist goes back to working as expected. + // eslint-disable-next-line @wordpress/no-unused-vars-before-return + const tabbable = Ariakit.useStoreState( store, ( state ) => { + return ( + state?.activeId !== null && + ! store?.item( state?.activeId )?.element?.isConnected + ); + } ); + + if ( ! store ) { warning( '`Tabs.Tab` must be wrapped in a `Tabs` component.' ); return null; } - const { store, instanceId } = context; + const instancedTabId = `${ instanceId }-${ tabId }`; + return ( { children }