Skip to content

Commit 75b3106

Browse files
authored
revert: Reverts single tab stop navigation changes (#157)
1 parent 96fb0e3 commit 75b3106

File tree

6 files changed

+38
-284
lines changed

6 files changed

+38
-284
lines changed

src/internal/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ export { getGlobalFlag } from './global-flags';
3131
export {
3232
SingleTabStopNavigationAPI,
3333
SingleTabStopNavigationProvider,
34-
SingleTabStopNavigationReset,
3534
useSingleTabStopNavigation,
3635
} from './single-tab-stop';
3736
export { isFocusable, getAllFocusables, getFirstFocusable, getLastFocusable } from './focus-lock-utils/utils';
Lines changed: 22 additions & 213 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,22 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
import React, { useContext, useEffect, useRef } from 'react';
5-
import { render } from '@testing-library/react';
4+
import React, { useRef } from 'react';
5+
import { render, act } from '@testing-library/react';
66

7-
import {
8-
SingleTabStopNavigationAPI,
9-
SingleTabStopNavigationContext,
10-
SingleTabStopNavigationProvider,
11-
SingleTabStopNavigationReset,
12-
useSingleTabStopNavigation,
13-
} from '../';
7+
import { SingleTabStopNavigationContext, useSingleTabStopNavigation } from '../';
148
import { renderWithSingleTabStopNavigation } from './utils';
159

16-
// Simple STSN subscriber component
1710
function Button(props: React.HTMLAttributes<HTMLButtonElement>) {
1811
const buttonRef = useRef<HTMLButtonElement>(null);
1912
const { tabIndex } = useSingleTabStopNavigation(buttonRef, { tabIndex: props.tabIndex });
2013
return <button {...props} ref={buttonRef} tabIndex={tabIndex} />;
2114
}
2215

23-
// Simple STSN provider component
24-
function Group({
25-
id,
26-
navigationActive,
27-
children,
28-
}: {
29-
id: string;
30-
navigationActive: boolean;
31-
children: React.ReactNode;
32-
}) {
33-
const navigationAPI = useRef<SingleTabStopNavigationAPI>(null);
34-
35-
useEffect(() => {
36-
navigationAPI.current?.updateFocusTarget();
37-
});
38-
39-
return (
40-
<SingleTabStopNavigationProvider
41-
ref={navigationAPI}
42-
navigationActive={navigationActive}
43-
getNextFocusTarget={() => document.querySelector(`#${id}`)!.querySelectorAll('button')[0] as HTMLElement}
44-
>
45-
<div id={id}>
46-
<Button>First</Button>
47-
<Button>Second</Button>
48-
{children}
49-
</div>
50-
</SingleTabStopNavigationProvider>
51-
);
52-
}
53-
54-
function findGroupButton(groupId: string, buttonIndex: number) {
55-
return document.querySelector(`#${groupId}`)!.querySelectorAll('button')[buttonIndex] as HTMLElement;
56-
}
16+
test('subscribed components can be rendered outside single tab stop navigation context', () => {
17+
render(<Button />);
18+
expect(document.querySelector('button')).not.toHaveAttribute('tabIndex');
19+
});
5720

5821
test('does not override tab index when keyboard navigation is not active', () => {
5922
renderWithSingleTabStopNavigation(<Button id="button" />, { navigationActive: false });
@@ -71,11 +34,14 @@ test('does not override tab index for suppressed elements', () => {
7134
</div>,
7235
{ navigationActive: true }
7336
);
74-
setCurrentTarget(document.querySelector('#button1'), [
75-
document.querySelector('#button1'),
76-
document.querySelector('#button2'),
77-
document.querySelector('#button3'),
78-
]);
37+
act(() => {
38+
setCurrentTarget(document.querySelector('#button1'), [
39+
document.querySelector('#button1'),
40+
document.querySelector('#button2'),
41+
document.querySelector('#button3'),
42+
]);
43+
});
44+
7945
expect(document.querySelector('#button1')).toHaveAttribute('tabIndex', '0');
8046
expect(document.querySelector('#button2')).toHaveAttribute('tabIndex', '0');
8147
expect(document.querySelector('#button3')).toHaveAttribute('tabIndex', '-1');
@@ -90,7 +56,9 @@ test('overrides tab index when keyboard navigation is active', () => {
9056
<Button id="button2" />
9157
</div>
9258
);
93-
setCurrentTarget(document.querySelector('#button1'));
59+
act(() => {
60+
setCurrentTarget(document.querySelector('#button1'));
61+
});
9462
expect(document.querySelector('#button1')).toHaveAttribute('tabIndex', '0');
9563
expect(document.querySelector('#button2')).toHaveAttribute('tabIndex', '-1');
9664
});
@@ -102,7 +70,9 @@ test('does not override explicit tab index with 0', () => {
10270
<Button id="button2" tabIndex={-2} />
10371
</div>
10472
);
105-
setCurrentTarget(document.querySelector('#button1'));
73+
act(() => {
74+
setCurrentTarget(document.querySelector('#button1'));
75+
});
10676
expect(document.querySelector('#button1')).toHaveAttribute('tabIndex', '-2');
10777
expect(document.querySelector('#button2')).toHaveAttribute('tabIndex', '-2');
10878
});
@@ -114,9 +84,7 @@ test('propagates and suppresses navigation active state', () => {
11484
}
11585
function Test({ navigationActive }: { navigationActive: boolean }) {
11686
return (
117-
<SingleTabStopNavigationContext.Provider
118-
value={{ navigationActive, registerFocusable: () => () => {}, resetFocusTarget: () => {} }}
119-
>
87+
<SingleTabStopNavigationContext.Provider value={{ navigationActive, registerFocusable: () => () => {} }}>
12088
<Component />
12189
</SingleTabStopNavigationContext.Provider>
12290
);
@@ -128,162 +96,3 @@ test('propagates and suppresses navigation active state', () => {
12896
rerender(<Test navigationActive={false} />);
12997
expect(document.querySelector('div')).toHaveTextContent('false');
13098
});
131-
132-
test('subscriber components can be used without provider', () => {
133-
function TestComponent(props: React.HTMLAttributes<HTMLButtonElement>) {
134-
const ref = useRef(null);
135-
const contextResult = useContext(SingleTabStopNavigationContext);
136-
const hookResult = useSingleTabStopNavigation(ref, { tabIndex: props.tabIndex });
137-
useEffect(() => {
138-
contextResult.registerFocusable(ref.current!, () => {});
139-
contextResult.resetFocusTarget();
140-
});
141-
return (
142-
<div ref={ref}>
143-
Context: {`${contextResult.navigationActive}`}, Hook: {`${hookResult.navigationActive}:${hookResult.tabIndex}`}
144-
</div>
145-
);
146-
}
147-
const { container } = render(<TestComponent />);
148-
expect(container.textContent).toBe('Context: false, Hook: false:undefined');
149-
});
150-
151-
describe('nested contexts', () => {
152-
test('tab indices are distributed correctly when switching contexts from inner to outer', () => {
153-
const { rerender } = render(
154-
<Group id="outer-most" navigationActive={false}>
155-
<Group id="outer" navigationActive={false}>
156-
<Group id="inner" navigationActive={true}>
157-
{null}
158-
</Group>
159-
</Group>
160-
</Group>
161-
);
162-
expect(findGroupButton('outer-most', 0)).not.toHaveAttribute('tabindex');
163-
expect(findGroupButton('outer-most', 1)).not.toHaveAttribute('tabindex');
164-
expect(findGroupButton('outer', 0)).not.toHaveAttribute('tabindex');
165-
expect(findGroupButton('outer', 1)).not.toHaveAttribute('tabindex');
166-
expect(findGroupButton('inner', 0)).toHaveAttribute('tabindex', '0');
167-
expect(findGroupButton('inner', 1)).toHaveAttribute('tabindex', '-1');
168-
169-
rerender(
170-
<Group id="outer-most" navigationActive={false}>
171-
<Group id="outer" navigationActive={true}>
172-
<Group id="inner" navigationActive={true}>
173-
{null}
174-
</Group>
175-
</Group>
176-
</Group>
177-
);
178-
expect(findGroupButton('outer-most', 0)).not.toHaveAttribute('tabindex');
179-
expect(findGroupButton('outer-most', 1)).not.toHaveAttribute('tabindex');
180-
expect(findGroupButton('outer', 0)).toHaveAttribute('tabindex', '0');
181-
expect(findGroupButton('outer', 1)).toHaveAttribute('tabindex', '-1');
182-
expect(findGroupButton('inner', 0)).toHaveAttribute('tabindex', '-1');
183-
expect(findGroupButton('inner', 1)).toHaveAttribute('tabindex', '-1');
184-
185-
rerender(
186-
<Group id="outer-most" navigationActive={true}>
187-
<Group id="outer" navigationActive={true}>
188-
<Group id="inner" navigationActive={true}>
189-
{null}
190-
</Group>
191-
</Group>
192-
</Group>
193-
);
194-
expect(findGroupButton('outer-most', 0)).toHaveAttribute('tabindex', '0');
195-
expect(findGroupButton('outer-most', 1)).toHaveAttribute('tabindex', '-1');
196-
expect(findGroupButton('outer', 0)).toHaveAttribute('tabindex', '-1');
197-
expect(findGroupButton('outer', 1)).toHaveAttribute('tabindex', '-1');
198-
expect(findGroupButton('inner', 0)).toHaveAttribute('tabindex', '-1');
199-
expect(findGroupButton('inner', 1)).toHaveAttribute('tabindex', '-1');
200-
});
201-
202-
test('tab indices are distributed correctly when switching contexts from outer to inner', () => {
203-
const { rerender } = render(
204-
<Group id="outer-most" navigationActive={true}>
205-
<Group id="outer" navigationActive={true}>
206-
<Group id="inner" navigationActive={true}>
207-
{null}
208-
</Group>
209-
</Group>
210-
</Group>
211-
);
212-
expect(findGroupButton('outer-most', 0)).toHaveAttribute('tabindex', '0');
213-
expect(findGroupButton('outer-most', 1)).toHaveAttribute('tabindex', '-1');
214-
expect(findGroupButton('outer', 0)).toHaveAttribute('tabindex', '-1');
215-
expect(findGroupButton('outer', 1)).toHaveAttribute('tabindex', '-1');
216-
expect(findGroupButton('inner', 0)).toHaveAttribute('tabindex', '-1');
217-
expect(findGroupButton('inner', 1)).toHaveAttribute('tabindex', '-1');
218-
219-
rerender(
220-
<Group id="outer-most" navigationActive={false}>
221-
<Group id="outer" navigationActive={true}>
222-
<Group id="inner" navigationActive={true}>
223-
{null}
224-
</Group>
225-
</Group>
226-
</Group>
227-
);
228-
expect(findGroupButton('outer-most', 0)).not.toHaveAttribute('tabindex');
229-
expect(findGroupButton('outer-most', 1)).not.toHaveAttribute('tabindex');
230-
expect(findGroupButton('outer', 0)).toHaveAttribute('tabindex', '0');
231-
expect(findGroupButton('outer', 1)).toHaveAttribute('tabindex', '-1');
232-
expect(findGroupButton('inner', 0)).toHaveAttribute('tabindex', '-1');
233-
expect(findGroupButton('inner', 1)).toHaveAttribute('tabindex', '-1');
234-
235-
rerender(
236-
<Group id="outer-most" navigationActive={false}>
237-
<Group id="outer" navigationActive={false}>
238-
<Group id="inner" navigationActive={true}>
239-
{null}
240-
</Group>
241-
</Group>
242-
</Group>
243-
);
244-
expect(findGroupButton('outer-most', 0)).not.toHaveAttribute('tabindex');
245-
expect(findGroupButton('outer-most', 1)).not.toHaveAttribute('tabindex');
246-
expect(findGroupButton('outer', 0)).not.toHaveAttribute('tabindex');
247-
expect(findGroupButton('outer', 1)).not.toHaveAttribute('tabindex');
248-
expect(findGroupButton('inner', 0)).toHaveAttribute('tabindex', '0');
249-
expect(findGroupButton('inner', 1)).toHaveAttribute('tabindex', '-1');
250-
});
251-
252-
test('ignores parent context when reset is used', () => {
253-
const { rerender } = render(
254-
<Group id="outer-most" navigationActive={true}>
255-
<SingleTabStopNavigationReset>
256-
<Group id="outer" navigationActive={true}>
257-
<Group id="inner" navigationActive={true}>
258-
{null}
259-
</Group>
260-
</Group>
261-
</SingleTabStopNavigationReset>
262-
</Group>
263-
);
264-
expect(findGroupButton('outer-most', 0)).toHaveAttribute('tabindex', '0');
265-
expect(findGroupButton('outer-most', 1)).toHaveAttribute('tabindex', '-1');
266-
expect(findGroupButton('outer', 0)).toHaveAttribute('tabindex', '0');
267-
expect(findGroupButton('outer', 1)).toHaveAttribute('tabindex', '-1');
268-
expect(findGroupButton('inner', 0)).toHaveAttribute('tabindex', '-1');
269-
expect(findGroupButton('inner', 1)).toHaveAttribute('tabindex', '-1');
270-
271-
rerender(
272-
<Group id="outer-most" navigationActive={true}>
273-
<Group id="outer" navigationActive={true}>
274-
<SingleTabStopNavigationReset>
275-
<Group id="inner" navigationActive={true}>
276-
{null}
277-
</Group>
278-
</SingleTabStopNavigationReset>
279-
</Group>
280-
</Group>
281-
);
282-
expect(findGroupButton('outer-most', 0)).toHaveAttribute('tabindex', '0');
283-
expect(findGroupButton('outer-most', 1)).toHaveAttribute('tabindex', '-1');
284-
expect(findGroupButton('outer', 0)).toHaveAttribute('tabindex', '-1');
285-
expect(findGroupButton('outer', 1)).toHaveAttribute('tabindex', '-1');
286-
expect(findGroupButton('inner', 0)).toHaveAttribute('tabindex', '0');
287-
expect(findGroupButton('inner', 1)).toHaveAttribute('tabindex', '-1');
288-
});
289-
});

src/internal/single-tab-stop/__tests__/utils.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@ const FakeSingleTabStopNavigationProvider = forwardRef(
3636
}));
3737

3838
return (
39-
<SingleTabStopNavigationContext.Provider
40-
value={{ navigationActive, registerFocusable, resetFocusTarget: () => {} }}
41-
>
39+
<SingleTabStopNavigationContext.Provider value={{ registerFocusable, navigationActive }}>
4240
{children}
4341
</SingleTabStopNavigationContext.Provider>
4442
);

0 commit comments

Comments
 (0)