Skip to content

Commit 7e971fa

Browse files
committed
fix(web): inverted scroll handler should defer to nested scrollable element targets
1 parent 00d5e1b commit 7e971fa

File tree

1 file changed

+57
-2
lines changed

1 file changed

+57
-2
lines changed

src/native/config/PlatformHelper.web.ts

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,69 @@ import {
77
} from "recyclerlistview";
88
import { DefaultJSItemAnimator } from "recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator";
99

10+
/**
11+
* Checks if a wheel event should be handled by a nested scrollable element.
12+
*/
13+
const shouldNestedElementHandleScroll = (
14+
event: globalThis.WheelEvent
15+
): boolean => {
16+
const targetNode = event.target;
17+
if (!(targetNode instanceof HTMLElement)) {
18+
return false;
19+
}
20+
21+
let target: HTMLElement | null = targetNode;
22+
const currentTarget = event.currentTarget as HTMLElement;
23+
24+
while (target && target !== currentTarget) {
25+
const style = window.getComputedStyle(target);
26+
const overflowY = style.overflowY;
27+
const overflowX = style.overflowX;
28+
29+
const isScrollableY =
30+
overflowY === "auto" || overflowY === "scroll" || overflowY === "overlay";
31+
const isScrollableX =
32+
overflowX === "auto" || overflowX === "scroll" || overflowX === "overlay";
33+
34+
// Check if element should handle vertical scroll
35+
if (isScrollableY && target.scrollHeight > target.clientHeight) {
36+
if (
37+
(event.deltaY > 0 &&
38+
target.scrollTop < target.scrollHeight - target.clientHeight) ||
39+
(event.deltaY < 0 && target.scrollTop > 0)
40+
) {
41+
return true;
42+
}
43+
}
44+
45+
// Check if element should handle horizontal scroll
46+
if (isScrollableX && target.scrollWidth > target.clientWidth) {
47+
if (
48+
(event.deltaX > 0 &&
49+
target.scrollLeft < target.scrollWidth - target.clientWidth) ||
50+
(event.deltaX < 0 && target.scrollLeft > 0)
51+
) {
52+
return true;
53+
}
54+
}
55+
56+
target = target.parentElement;
57+
}
58+
59+
return false;
60+
};
61+
1062
const createInvertedWheelEventHandler = (type: "horizontal" | "vertical") => {
1163
return (event: globalThis.WheelEvent) => {
12-
const node = event.currentTarget as HTMLElement;
64+
if (shouldNestedElementHandleScroll(event)) {
65+
return;
66+
}
1367

68+
const currentTarget = event.currentTarget as HTMLElement;
1469
const deltaX = type === "horizontal" ? -event.deltaX : event.deltaX;
1570
const deltaY = type === "vertical" ? -event.deltaY : event.deltaY;
1671

17-
node.scrollBy({
72+
currentTarget.scrollBy({
1873
top: deltaY,
1974
left: deltaX,
2075
behavior: "auto",

0 commit comments

Comments
 (0)