diff --git a/src/internal/index.ts b/src/internal/index.ts index 9a277fa..c3c2d7a 100644 --- a/src/internal/index.ts +++ b/src/internal/index.ts @@ -31,6 +31,7 @@ export { getGlobalFlag } from './global-flags'; export { SingleTabStopNavigationAPI, SingleTabStopNavigationProvider, + SingleTabStopNavigationReset, useSingleTabStopNavigation, } from './single-tab-stop'; export { isFocusable, getAllFocusables, getFirstFocusable, getLastFocusable } from './focus-lock-utils/utils'; diff --git a/src/internal/single-tab-stop/__tests__/context.test.tsx b/src/internal/single-tab-stop/__tests__/context.test.tsx index 6c5b6e5..cf5f413 100644 --- a/src/internal/single-tab-stop/__tests__/context.test.tsx +++ b/src/internal/single-tab-stop/__tests__/context.test.tsx @@ -8,6 +8,7 @@ import { SingleTabStopNavigationAPI, SingleTabStopNavigationContext, SingleTabStopNavigationProvider, + SingleTabStopNavigationReset, useSingleTabStopNavigation, } from '../'; import { renderWithSingleTabStopNavigation } from './utils'; @@ -247,4 +248,42 @@ describe('nested contexts', () => { expect(findGroupButton('inner', 0)).toHaveAttribute('tabindex', '0'); expect(findGroupButton('inner', 1)).toHaveAttribute('tabindex', '-1'); }); + + test('ignores parent context when reset is used', () => { + const { rerender } = render( + + + + + {null} + + + + + ); + expect(findGroupButton('outer-most', 0)).toHaveAttribute('tabindex', '0'); + expect(findGroupButton('outer-most', 1)).toHaveAttribute('tabindex', '-1'); + expect(findGroupButton('outer', 0)).toHaveAttribute('tabindex', '0'); + expect(findGroupButton('outer', 1)).toHaveAttribute('tabindex', '-1'); + expect(findGroupButton('inner', 0)).toHaveAttribute('tabindex', '-1'); + expect(findGroupButton('inner', 1)).toHaveAttribute('tabindex', '-1'); + + rerender( + + + + + {null} + + + + + ); + expect(findGroupButton('outer-most', 0)).toHaveAttribute('tabindex', '0'); + expect(findGroupButton('outer-most', 1)).toHaveAttribute('tabindex', '-1'); + expect(findGroupButton('outer', 0)).toHaveAttribute('tabindex', '-1'); + expect(findGroupButton('outer', 1)).toHaveAttribute('tabindex', '-1'); + expect(findGroupButton('inner', 0)).toHaveAttribute('tabindex', '0'); + expect(findGroupButton('inner', 1)).toHaveAttribute('tabindex', '-1'); + }); }); diff --git a/src/internal/single-tab-stop/__tests__/utils.tsx b/src/internal/single-tab-stop/__tests__/utils.tsx index 7a135a4..3bddd0b 100644 --- a/src/internal/single-tab-stop/__tests__/utils.tsx +++ b/src/internal/single-tab-stop/__tests__/utils.tsx @@ -37,7 +37,7 @@ const FakeSingleTabStopNavigationProvider = forwardRef( return ( {} }} + value={{ navigationActive, registerFocusable, resetFocusTarget: () => {} }} > {children} diff --git a/src/internal/single-tab-stop/index.tsx b/src/internal/single-tab-stop/index.tsx index ba57c36..6b6fd31 100644 --- a/src/internal/single-tab-stop/index.tsx +++ b/src/internal/single-tab-stop/index.tsx @@ -16,7 +16,7 @@ import nodeBelongs from '../../dom/node-belongs'; export type FocusableChangeHandler = (isFocusable: boolean) => void; -export const defaultValue: { +const defaultValue: { navigationActive: boolean; registerFocusable(focusable: HTMLElement, handler: FocusableChangeHandler): () => void; resetFocusTarget(): void; @@ -71,6 +71,12 @@ export interface SingleTabStopNavigationAPI { isRegistered(element: Element): boolean; } +export function SingleTabStopNavigationReset({ children }: { children: React.ReactNode }) { + return ( + {children} + ); +} + export const SingleTabStopNavigationProvider = forwardRef( ( { @@ -158,7 +164,7 @@ export const SingleTabStopNavigationProvider = forwardRef( const parentContext = useContext(SingleTabStopNavigationContext); const value = parentContext.navigationActive ? parentContext - : { navigationActive, registerFocusable, updateFocusTarget, resetFocusTarget }; + : { navigationReset: false, navigationActive, registerFocusable, updateFocusTarget, resetFocusTarget }; // When contexts switching occurs, it is essential that the now-active one updates the focus target // to ensure the tab indices are correctly set. diff --git a/src/internal/testing.ts b/src/internal/testing.ts index e591f6e..4493fd7 100644 --- a/src/internal/testing.ts +++ b/src/internal/testing.ts @@ -5,3 +5,4 @@ export { clearOneTimeMetricsCache } from './base-component/metrics/metrics'; export { clearMessageCache } from './logging'; export { setGlobalFlag } from './global-flags'; export { clearVisualRefreshState } from './visual-mode'; +export { renderWithSingleTabStopNavigation } from './single-tab-stop/__tests__/utils';