11// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22// SPDX-License-Identifier: Apache-2.0
33
4- import React , { forwardRef , useCallback , useEffect , useRef } from 'react' ;
4+ import React , { useCallback , useEffect , useRef } from 'react' ;
55
66import { FocusableChangeHandler , SingleTabStopNavigationContext } from '../' ;
77import { useUniqueId } from '../../use-unique-id' ;
@@ -14,44 +14,55 @@ interface TestProviderAPI {
1414
1515const providerRegistry = new Map < string , TestProviderAPI > ( ) ;
1616
17- export const TestSingleTabStopNavigationProvider = forwardRef (
18- ( { children, navigationActive } : { children : React . ReactNode ; navigationActive : boolean } ) => {
19- const focusablesRef = useRef ( new Set < Element > ( ) ) ;
20- const focusHandlersRef = useRef ( new Map < Element , FocusableChangeHandler > ( ) ) ;
21- const registerFocusable = useCallback ( ( focusable : HTMLElement , changeHandler : FocusableChangeHandler ) => {
22- focusablesRef . current . add ( focusable ) ;
23- focusHandlersRef . current . set ( focusable , changeHandler ) ;
24- return ( ) => {
25- focusablesRef . current . delete ( focusable ) ;
26- focusHandlersRef . current . delete ( focusable ) ;
27- } ;
28- } , [ ] ) ;
29-
30- const providerId = useUniqueId ( ) ;
31- providerRegistry . set ( providerId , {
32- setCurrentTarget : ( focusTarget , suppressed = [ ] ) => {
33- focusablesRef . current . forEach ( focusable => {
34- const handler = focusHandlersRef . current . get ( focusable ) ! ;
35- handler ( focusTarget === focusable || suppressed . includes ( focusable ) ) ;
36- } ) ;
37- } ,
38- } ) ;
39- useEffect (
40- ( ) => ( ) => {
41- providerRegistry . delete ( providerId ) ;
42- } ,
43- [ providerId ]
44- ) ;
45-
46- return (
47- < SingleTabStopNavigationContext . Provider
48- value = { { navigationActive, registerFocusable, resetFocusTarget : ( ) => { } } }
49- >
50- { children }
51- </ SingleTabStopNavigationContext . Provider >
52- ) ;
53- }
54- ) ;
17+ export const TestSingleTabStopNavigationProvider = ( {
18+ children,
19+ navigationActive,
20+ } : {
21+ children : React . ReactNode ;
22+ navigationActive : boolean ;
23+ } ) => {
24+ const focusablesRef = useRef ( new Set < Element > ( ) ) ;
25+ const focusHandlersRef = useRef ( new Map < Element , FocusableChangeHandler > ( ) ) ;
26+ const registerFocusable = useCallback ( ( focusable : HTMLElement , changeHandler : FocusableChangeHandler ) => {
27+ focusablesRef . current . add ( focusable ) ;
28+ focusHandlersRef . current . set ( focusable , changeHandler ) ;
29+ return ( ) => {
30+ focusablesRef . current . delete ( focusable ) ;
31+ focusHandlersRef . current . delete ( focusable ) ;
32+ } ;
33+ } , [ ] ) ;
34+
35+ const providerId = useUniqueId ( ) ;
36+ providerRegistry . set ( providerId , {
37+ setCurrentTarget : ( focusTarget , suppressed = [ ] ) => {
38+ focusablesRef . current . forEach ( focusable => {
39+ const handler = focusHandlersRef . current . get ( focusable ) ! ;
40+ handler ( focusTarget === focusable || suppressed . includes ( focusable ) ) ;
41+ } ) ;
42+ } ,
43+ } ) ;
44+ useEffect (
45+ ( ) => ( ) => {
46+ providerRegistry . delete ( providerId ) ;
47+ } ,
48+ [ providerId ]
49+ ) ;
50+
51+ return (
52+ < SingleTabStopNavigationContext . Provider
53+ value = { {
54+ navigationActive,
55+ registerFocusable,
56+ // The reset target feature is not needed in the test provider, and it is
57+ // already tested with the actual provider implementation instead.
58+ // istanbul ignore next
59+ resetFocusTarget : ( ) => { } ,
60+ } }
61+ >
62+ { children }
63+ </ SingleTabStopNavigationContext . Provider >
64+ ) ;
65+ } ;
5566
5667export const setTestSingleTabStopNavigationTarget : SetTarget = ( focusTarget , suppressed ) => {
5768 Array . from ( providerRegistry ) . forEach ( ( [ , provider ] ) => provider . setCurrentTarget ( focusTarget , suppressed ) ) ;
0 commit comments