Skip to content

Commit 2945296

Browse files
fix: can't scroll the document on Firefox (#287)
Co-authored-by: [email protected] <[email protected]>
1 parent 87bbdd5 commit 2945296

File tree

2 files changed

+61
-3
lines changed

2 files changed

+61
-3
lines changed

src/List.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -438,8 +438,11 @@ export function RawList<T>(props: ListProps<T>, ref: React.Ref<ListRef>) {
438438

439439
useLayoutEffect(() => {
440440
// Firefox only
441-
function onMozMousePixelScroll(e: Event) {
442-
if (useVirtual) {
441+
function onMozMousePixelScroll(e: WheelEvent) {
442+
// scrolling at top/bottom limit
443+
const scrollingUpAtTop = isScrollAtTop && e.detail < 0;
444+
const scrollingDownAtBottom = isScrollAtBottom && e.detail > 0;
445+
if (useVirtual && !scrollingUpAtTop && !scrollingDownAtBottom) {
443446
e.preventDefault();
444447
}
445448
}
@@ -454,7 +457,7 @@ export function RawList<T>(props: ListProps<T>, ref: React.Ref<ListRef>) {
454457
componentEle.removeEventListener('DOMMouseScroll', onFireFoxScroll as any);
455458
componentEle.removeEventListener('MozMousePixelScroll', onMozMousePixelScroll as any);
456459
};
457-
}, [useVirtual]);
460+
}, [useVirtual, isScrollAtTop, isScrollAtBottom]);
458461

459462
// Sync scroll left
460463
useLayoutEffect(() => {

tests/scroll-Firefox.test.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,59 @@ describe('List.Firefox-Scroll', () => {
8484
expect(wheelPreventDefault).not.toHaveBeenCalled();
8585
expect(firefoxPreventDefault).toHaveBeenCalledTimes(1);
8686
});
87+
88+
it('should call preventDefault on MozMousePixelScroll', () => {
89+
const preventDefault = jest.fn();
90+
const wrapper = genList({ itemHeight: 20, height: 100, data: genData(100) });
91+
const ulElement = wrapper.find('ul').instance();
92+
93+
act(() => {
94+
const event = new Event('MozMousePixelScroll');
95+
event.detail = 6;
96+
event.preventDefault = preventDefault;
97+
ulElement.dispatchEvent(event);
98+
99+
jest.runAllTimers();
100+
});
101+
102+
expect(preventDefault).toHaveBeenCalled();
103+
});
104+
105+
it('should not call preventDefault on MozMousePixelScroll when scrolling up at top boundary', () => {
106+
const preventDefault = jest.fn();
107+
const wrapper = genList({ itemHeight: 20, height: 100, data: genData(100) });
108+
const ulElement = wrapper.find('ul').instance();
109+
110+
act(() => {
111+
const event = new Event('MozMousePixelScroll');
112+
event.detail = -6;
113+
event.preventDefault = preventDefault;
114+
ulElement.dispatchEvent(event);
115+
116+
jest.runAllTimers();
117+
});
118+
119+
expect(preventDefault).not.toHaveBeenCalled();
120+
});
121+
it('should not call preventDefault on MozMousePixelScroll when scrolling down at bottom boundary', () => {
122+
const preventDefault = jest.fn();
123+
const listRef = React.createRef();
124+
const wrapper = genList({ itemHeight: 20, height: 100, data: genData(100), ref: listRef });
125+
const ulElement = wrapper.find('ul').instance();
126+
// scroll to bottom
127+
listRef.current.scrollTo(99999);
128+
jest.runAllTimers();
129+
expect(wrapper.find('ul').instance().scrollTop).toEqual(1900);
130+
131+
act(() => {
132+
const event = new Event('MozMousePixelScroll');
133+
event.detail = 6;
134+
event.preventDefault = preventDefault;
135+
ulElement.dispatchEvent(event);
136+
137+
jest.runAllTimers();
138+
});
139+
140+
expect(preventDefault).not.toHaveBeenCalled();
141+
});
87142
});

0 commit comments

Comments
 (0)