Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion VirtualList/tests/VirtualList-native-specs.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import '@testing-library/jest-dom';
import {act, render, screen} from '@testing-library/react';
import {act, createEvent, fireEvent, render, screen} from '@testing-library/react';

import Item from '../../Item';
import VirtualList from '../VirtualList';
Expand Down Expand Up @@ -195,6 +195,32 @@ describe('VirtualList with native `scrollMode`', () => {
});
});

describe('Global keydown handling', () => {
test('should prevent default and stop propagation on a global keydown while the spotlight container is disabled', () => {
render(
<VirtualList
clientSize={clientSize}
dataSize={dataSize}
itemRenderer={renderItem}
itemSize={itemSize}
/>
);

// Wheeling in native mode disables the spotlight container, which registers the global
// keydown listener (handleGlobalKeyDown) on the document.
fireEvent.wheel(screen.getByRole('list'), {deltaY: 100});

const keyDownEvent = createEvent.keyDown(document, {keyCode: 13});
const preventDefault = jest.spyOn(keyDownEvent, 'preventDefault');
const stopPropagation = jest.spyOn(keyDownEvent, 'stopPropagation');

fireEvent(document, keyDownEvent);

expect(preventDefault).toHaveBeenCalled();
expect(stopPropagation).toHaveBeenCalled();
});
});

describe('Adding an item', () => {
test('should render an added item named `Password 0` as the first item', (done) => {
const itemArray = [{name: 'A'}, {name: 'B'}, {name: 'C'}];
Expand Down
26 changes: 14 additions & 12 deletions VirtualList/useThemeVirtualList.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const useSpottable = (props, instances) => {
lastFocusedIndex: null,
pause: new Pause('VirtualListBasic')
});
const handleGlobalKeyDownRef = useRef(null);

const {pause} = mutableRef.current;

Expand Down Expand Up @@ -102,23 +103,24 @@ const useSpottable = (props, instances) => {
scrollContainerRef.current.dataset.spotlightContainerDisabled = bool;

if (bool) {
addGlobalKeyDownEventListener(handleGlobalKeyDown);
addGlobalKeyDownEventListener(handleGlobalKeyDownRef.current);
} else {
removeGlobalKeyDownEventListener();
}
}
}, [addGlobalKeyDownEventListener, handleGlobalKeyDown, removeGlobalKeyDownEventListener, scrollContainerRef]);

// eslint-disable-next-line react-hooks/exhaustive-deps
function handleGlobalKeyDown (ev) {
// To prevent scrolling by native scroller
if (scrollMode === 'native') {
ev.preventDefault();
ev.stopPropagation();
}
}, [addGlobalKeyDownEventListener, removeGlobalKeyDownEventListener, scrollContainerRef]);

setContainerDisabled(false);
}
useEffect(() => {
handleGlobalKeyDownRef.current = (ev) => {
// To prevent scrolling by native scroller
if (scrollMode === 'native') {
ev.preventDefault();
ev.stopPropagation();
}

setContainerDisabled(false);
};
}, [scrollMode, setContainerDisabled]);

useEffect(() => {
return () => {
Expand Down
5 changes: 4 additions & 1 deletion tests/screenshot/apps/Agate-View.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ class App extends ReactComponent {
}
}

// Declared at module scope, so the components are not created during render (react-hooks/static-components).
const WrappedAgateAppAutoFocus = ThemeDecorator({noAutoFocus: false}, App);
const WrappedAgateAppNoAutoFocus = ThemeDecorator({noAutoFocus: true}, App);

const ExportedAgateApp = (props) => {

Expand All @@ -151,7 +154,7 @@ const ExportedAgateApp = (props) => {
noAutoFocus = !agateComponents[props.component][props.testId].focus;
}

const WrappedAgateApp = ThemeDecorator({noAutoFocus}, App);
const WrappedAgateApp = noAutoFocus ? WrappedAgateAppNoAutoFocus : WrappedAgateAppAutoFocus;

useEffect(() => {
document.querySelector('#root > div').classList.add('spotlight-input-key');
Expand Down
Loading