Skip to content

Commit

Permalink
fix(web): only reverse scroll direction for one axis based on whether…
Browse files Browse the repository at this point in the history
… `horizontal` is set
  • Loading branch information
mtourj committed Jan 24, 2025
1 parent febb588 commit a330f3e
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 60 deletions.
30 changes: 19 additions & 11 deletions src/FlashList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ import {
RenderTargetOptions,
} from "./FlashListProps";
import {
addInvertedWheelHandler,
getCellContainerPlatformStyles,
getFooterContainer,
getItemAnimator,
PlatformConfig,
removeInvertedWheelHandler,
} from "./native/config/PlatformHelper";
import {
ContentStyleExplicit,
Expand Down Expand Up @@ -289,14 +291,15 @@ class FlashList<T> extends React.PureComponent<
private updateWebScrollHandler() {
if (Platform.OS !== "web" || !this.rlvRef) return;

if (this.props.inverted !== this.hasInvertedWheelHandler) {
if (this.props.inverted) {
PlatformConfig.addInvertedWheelHandler(this.rlvRef);
this.hasInvertedWheelHandler = true;
} else {
PlatformConfig.removeInvertedWheelHandler(this.rlvRef);
this.hasInvertedWheelHandler = false;
}
removeInvertedWheelHandler(this.rlvRef);
this.hasInvertedWheelHandler = false;

if (this.props.inverted) {
addInvertedWheelHandler(
this.rlvRef,
this.props.horizontal ? "horizontal" : "vertical"
);
this.hasInvertedWheelHandler = true;
}
}

Expand All @@ -317,12 +320,17 @@ class FlashList<T> extends React.PureComponent<
}

if (this.hasInvertedWheelHandler) {
PlatformConfig.removeInvertedWheelHandler(this.rlvRef);
removeInvertedWheelHandler(this.rlvRef);
}
}

componentDidUpdate() {
this.updateWebScrollHandler();
componentDidUpdate(prevProps: FlashListProps<T>) {
if (
prevProps.inverted !== this.props.inverted ||
prevProps.horizontal !== this.props.horizontal
) {
this.updateWebScrollHandler();
}
}

render() {
Expand Down
27 changes: 15 additions & 12 deletions src/native/config/PlatformHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,6 @@ const PlatformConfig = {
defaultDrawDistance: 250,
invertedTransformStyle: { transform: [{ scaleY: -1 }] },
invertedTransformStyleHorizontal: { transform: [{ scaleX: -1 }] },
addInvertedWheelHandler: (
ref: RecyclerListView<RecyclerListViewProps, any> | undefined
): (() => void) | undefined => {
// (web-only)
return undefined;
},
removeInvertedWheelHandler: (
ref: RecyclerListView<RecyclerListViewProps, any> | undefined
): (() => void) | undefined => {
// (web-only)
return undefined;
},
};
const getCellContainerPlatformStyles = (
inverted: boolean,
Expand All @@ -37,9 +25,24 @@ const getFooterContainer = (): React.ComponentClass | undefined => {
return undefined;
};

const addInvertedWheelHandler = (
ref: RecyclerListView<RecyclerListViewProps, any> | undefined,
type: "horizontal" | "vertical"
): (() => void) | undefined => {
return undefined;
};

const removeInvertedWheelHandler = (
ref: RecyclerListView<RecyclerListViewProps, any> | undefined
): (() => void) | undefined => {
return undefined;
};

export {
PlatformConfig,
getCellContainerPlatformStyles,
getItemAnimator,
getFooterContainer,
addInvertedWheelHandler,
removeInvertedWheelHandler,
};
85 changes: 48 additions & 37 deletions src/native/config/PlatformHelper.web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,32 @@ import {
} from "recyclerlistview";
import { DefaultJSItemAnimator } from "recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator";

const invertedWheelEventHandler = (event: globalThis.WheelEvent) => {
const node = event.currentTarget as HTMLElement;
const createInvertedWheelEventHandler = (type: "horizontal" | "vertical") => {
return (event: globalThis.WheelEvent) => {
const node = event.currentTarget as HTMLElement;

// For inverted lists, we want to scroll in the opposite direction
// So when deltaY is positive (scroll down), we want to scroll up
const deltaY = -event.deltaY;
const deltaX = -event.deltaX;
const deltaX = type === "horizontal" ? -event.deltaX : event.deltaX;
const deltaY = type === "vertical" ? -event.deltaY : event.deltaY;

// Scroll by the inverted delta
node.scrollBy({
top: deltaY,
left: deltaX,
behavior: "auto",
});
node.scrollBy({
top: deltaY,
left: deltaX,
behavior: "auto",
});

// Prevent the default scroll
event.preventDefault();
event.preventDefault();
};
};

const verticalInvertedWheelEventHandler =
createInvertedWheelEventHandler("vertical");
const horizontalInvertedWheelEventHandler =
createInvertedWheelEventHandler("horizontal");

const PlatformConfig = {
defaultDrawDistance: 2000,
invertedTransformStyle: { transform: [{ scaleY: -1 }] },
invertedTransformStyleHorizontal: { transform: [{ scaleX: -1 }] },
addInvertedWheelHandler: (
ref: RecyclerListView<RecyclerListViewProps, any> | undefined
): ((event: globalThis.WheelEvent) => void) | undefined => {
if (!ref) return undefined;
const node = findNodeHandle(ref) as unknown as HTMLElement;
if (node) {
node.addEventListener("wheel", invertedWheelEventHandler, {
passive: false,
});
return invertedWheelEventHandler;
}
return undefined;
},
removeInvertedWheelHandler: (
ref: RecyclerListView<RecyclerListViewProps, any> | undefined
): ((event: globalThis.WheelEvent) => void) | undefined => {
if (!ref) return undefined;
const node = findNodeHandle(ref) as unknown as HTMLElement;
if (node) {
node.removeEventListener("wheel", invertedWheelEventHandler);
}
return undefined;
},
};
const getCellContainerPlatformStyles = (
inverted: boolean,
Expand All @@ -71,10 +51,41 @@ const getItemAnimator = (): BaseItemAnimator | undefined => {
const getFooterContainer = (): React.ComponentClass | undefined => {
return View;
};
const addInvertedWheelHandler = (
ref: RecyclerListView<RecyclerListViewProps, any> | undefined,
type: "horizontal" | "vertical"
): ((event: globalThis.WheelEvent) => void) | undefined => {
if (!ref) return undefined;
const node = findNodeHandle(ref) as unknown as HTMLElement;
if (node) {
const handler =
type === "horizontal"
? horizontalInvertedWheelEventHandler
: verticalInvertedWheelEventHandler;
node.addEventListener("wheel", handler, {
passive: false,
});
return handler;
}
return undefined;
};
const removeInvertedWheelHandler = (
ref: RecyclerListView<RecyclerListViewProps, any> | undefined
): ((event: globalThis.WheelEvent) => void) | undefined => {
if (!ref) return undefined;
const node = findNodeHandle(ref) as unknown as HTMLElement;
if (node) {
node.removeEventListener("wheel", verticalInvertedWheelEventHandler);
node.removeEventListener("wheel", horizontalInvertedWheelEventHandler);
}
return undefined;
};

export {
PlatformConfig,
getCellContainerPlatformStyles,
getItemAnimator,
getFooterContainer,
addInvertedWheelHandler,
removeInvertedWheelHandler,
};

0 comments on commit a330f3e

Please sign in to comment.