Skip to content

Commit a6772bd

Browse files
yury-sdgozman
authored andcommitted
cherry-pick(#41280): Revert "fix(trace-viewer): add keyboard navigation to NetworkFilters component"
1 parent 8133dcf commit a6772bd

5 files changed

Lines changed: 40 additions & 93 deletions

File tree

packages/html-reporter/src/tabbedPane.tsx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { clsx, handleTabListKeyDown } from '@web/uiUtils';
17+
import { clsx } from '@web/uiUtils';
1818
import './colors.css';
1919
import './tabbedPane.css';
2020
import * as React from 'react';
@@ -35,9 +35,24 @@ export const TabbedPane: React.FunctionComponent<{
3535
const tabStripRef = React.useRef<HTMLDivElement>(null);
3636

3737
const handleKeyDown = (e: React.KeyboardEvent) => {
38-
const nextIndex = handleTabListKeyDown(e, tabStripRef.current);
39-
if (nextIndex !== -1)
40-
setSelectedTab(tabs[nextIndex].id);
38+
const tabElements = Array.from(tabStripRef.current?.querySelectorAll('[role="tab"]') ?? []) as HTMLElement[];
39+
const currentIndex = tabElements.findIndex(el => el === document.activeElement);
40+
if (currentIndex === -1)
41+
return;
42+
let nextIndex = currentIndex;
43+
if (e.key === 'ArrowRight')
44+
nextIndex = (currentIndex + 1) % tabElements.length;
45+
else if (e.key === 'ArrowLeft')
46+
nextIndex = (currentIndex - 1 + tabElements.length) % tabElements.length;
47+
else if (e.key === 'Home')
48+
nextIndex = 0;
49+
else if (e.key === 'End')
50+
nextIndex = tabElements.length - 1;
51+
else
52+
return;
53+
e.preventDefault();
54+
tabElements[nextIndex].focus();
55+
setSelectedTab(tabs[nextIndex].id);
4156
};
4257

4358
return <div className='tabbed-pane'>

packages/trace-viewer/src/ui/networkFilters.tsx

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
* limitations under the License.
1515
*/
1616

17-
import * as React from 'react';
18-
import { handleTabListKeyDown } from '@web/uiUtils';
1917
import './networkFilters.css';
2018

2119
const resourceTypes = ['Fetch', 'HTML', 'JS', 'CSS', 'Font', 'Image', 'WS'] as const;
@@ -32,14 +30,6 @@ export const NetworkFilters = ({ filterState, onFilterStateChange }: {
3230
filterState: FilterState,
3331
onFilterStateChange: (filterState: FilterState) => void,
3432
}) => {
35-
const tabListRef = React.useRef<HTMLDivElement>(null);
36-
37-
const handleKeyDown = (e: React.KeyboardEvent) => {
38-
handleTabListKeyDown(e, tabListRef.current);
39-
};
40-
41-
const isAllSelected = filterState.resourceTypes.size === 0;
42-
4333
return (
4434
<div className='network-filters'>
4535
<input
@@ -50,14 +40,11 @@ export const NetworkFilters = ({ filterState, onFilterStateChange }: {
5040
onChange={e => onFilterStateChange({ ...filterState, searchValue: e.target.value })}
5141
/>
5242

53-
<div className='network-filters-resource-types' role='tablist' aria-multiselectable='true' onKeyDown={handleKeyDown} ref={tabListRef}>
43+
<div className='network-filters-resource-types' role='tablist' aria-multiselectable='true'>
5444
<div
5545
title='All'
5646
onClick={() => onFilterStateChange({ ...filterState, resourceTypes: new Set() })}
57-
className={`network-filters-resource-type ${isAllSelected ? 'selected' : ''}`}
58-
role='tab'
59-
tabIndex={isAllSelected ? 0 : -1}
60-
aria-selected={isAllSelected}
47+
className={`network-filters-resource-type ${filterState.resourceTypes.size === 0 ? 'selected' : ''}`}
6148
>
6249
All
6350
</div>
@@ -77,7 +64,6 @@ export const NetworkFilters = ({ filterState, onFilterStateChange }: {
7764
}}
7865
className={`network-filters-resource-type ${filterState.resourceTypes.has(resourceType) ? 'selected' : ''}`}
7966
role='tab'
80-
tabIndex={filterState.resourceTypes.has(resourceType) ? 0 : -1}
8167
aria-selected={filterState.resourceTypes.has(resourceType)}
8268
>
8369
{resourceType}

packages/web/src/components/tabbedPane.tsx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { clsx, handleTabListKeyDown } from '../uiUtils';
17+
import { clsx } from '../uiUtils';
1818
import './tabbedPane.css';
1919
import { Toolbar } from './toolbar';
2020
import * as React from 'react';
@@ -45,9 +45,24 @@ export const TabbedPane: React.FunctionComponent<{
4545
mode = 'default';
4646

4747
const handleKeyDown = (e: React.KeyboardEvent) => {
48-
const nextIndex = handleTabListKeyDown(e, tabListRef.current);
49-
if (nextIndex !== -1)
50-
setSelectedTab?.(tabs[nextIndex].id);
48+
const tabElements = Array.from(tabListRef.current?.querySelectorAll('[role="tab"]') ?? []) as HTMLElement[];
49+
const currentIndex = tabElements.findIndex(el => el === document.activeElement);
50+
if (currentIndex === -1)
51+
return;
52+
let nextIndex = currentIndex;
53+
if (e.key === 'ArrowRight')
54+
nextIndex = (currentIndex + 1) % tabElements.length;
55+
else if (e.key === 'ArrowLeft')
56+
nextIndex = (currentIndex - 1 + tabElements.length) % tabElements.length;
57+
else if (e.key === 'Home')
58+
nextIndex = 0;
59+
else if (e.key === 'End')
60+
nextIndex = tabElements.length - 1;
61+
else
62+
return;
63+
e.preventDefault();
64+
tabElements[nextIndex].focus();
65+
setSelectedTab?.(tabs[nextIndex].id);
5166
};
5267

5368
return <div className='tabbed-pane' data-testid={dataTestId}>

packages/web/src/uiUtils.ts

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -210,27 +210,6 @@ export function scrollIntoViewIfNeeded(element: Element | undefined) {
210210
element?.scrollIntoView();
211211
}
212212

213-
export function handleTabListKeyDown(e: React.KeyboardEvent, tabListElement: HTMLElement | null): number {
214-
const tabElements = Array.from(tabListElement?.querySelectorAll('[role="tab"]') ?? []) as HTMLElement[];
215-
const currentIndex = tabElements.findIndex(el => el === document.activeElement);
216-
if (currentIndex === -1)
217-
return -1;
218-
let nextIndex = currentIndex;
219-
if (e.key === 'ArrowRight')
220-
nextIndex = (currentIndex + 1) % tabElements.length;
221-
else if (e.key === 'ArrowLeft')
222-
nextIndex = (currentIndex - 1 + tabElements.length) % tabElements.length;
223-
else if (e.key === 'Home')
224-
nextIndex = 0;
225-
else if (e.key === 'End')
226-
nextIndex = tabElements.length - 1;
227-
else
228-
return -1;
229-
e.preventDefault();
230-
tabElements[nextIndex].focus();
231-
return nextIndex;
232-
}
233-
234213
const kControlCodesRe = '\\u0000-\\u0020\\u007f-\\u009f';
235214
export const kWebLinkRe = new RegExp('(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|www\\.)[^\\s' + kControlCodesRe + '"]{2,}[^\\s' + kControlCodesRe + '"\')}\\],:;.!?]', 'ug');
236215

tests/playwright-test/ui-mode-test-network-tab.spec.ts

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -478,51 +478,3 @@ test('should preserve selection during test run', async ({ runUITest, server },
478478
await page.waitForTimeout(1000);
479479
await expect(headersPanel).toBeVisible();
480480
});
481-
482-
test('should support keyboard navigation for resource type filters', async ({ runUITest, server }) => {
483-
server.setRoute('/api/endpoint', (_, res) => res.setHeader('Content-Type', 'application/json').end());
484-
485-
const { page } = await runUITest({
486-
'network-tab.test.ts': `
487-
import { test, expect } from '@playwright/test';
488-
test('network tab test', async ({ page }) => {
489-
await page.goto('${server.PREFIX}/network-tab/network.html');
490-
await page.evaluate(() => (window as any).donePromise);
491-
});
492-
`,
493-
});
494-
495-
await page.getByRole('treeitem', { name: 'network tab test' }).dblclick();
496-
await expect(page.getByTestId('workbench-run-status')).toContainText('Passed');
497-
498-
await page.getByRole('tab', { name: 'Network' }).click();
499-
500-
const filters = page.locator('.network-filters-resource-types');
501-
502-
// Focus the "All" tab and navigate with arrow keys.
503-
await filters.getByText('All', { exact: true }).focus();
504-
await page.keyboard.press('ArrowRight');
505-
await expect(filters.getByText('Fetch', { exact: true })).toBeFocused();
506-
507-
await page.keyboard.press('ArrowRight');
508-
await expect(filters.getByText('HTML', { exact: true })).toBeFocused();
509-
510-
await page.keyboard.press('ArrowRight');
511-
await expect(filters.getByText('JS', { exact: true })).toBeFocused();
512-
513-
// ArrowLeft goes back.
514-
await page.keyboard.press('ArrowLeft');
515-
await expect(filters.getByText('HTML', { exact: true })).toBeFocused();
516-
517-
// Home jumps to first tab.
518-
await page.keyboard.press('Home');
519-
await expect(filters.getByText('All', { exact: true })).toBeFocused();
520-
521-
// End jumps to last tab.
522-
await page.keyboard.press('End');
523-
await expect(filters.getByText('Image', { exact: true })).toBeFocused();
524-
525-
// Wraps around from last to first.
526-
await page.keyboard.press('ArrowRight');
527-
await expect(filters.getByText('All', { exact: true })).toBeFocused();
528-
});

0 commit comments

Comments
 (0)