From 7c06030a498d40d7e3dbea6c3e05afc32e2d1a90 Mon Sep 17 00:00:00 2001 From: MxKevinBeqo Date: Mon, 6 Oct 2025 14:42:22 +0200 Subject: [PATCH 1/2] fix(gallery-native): virtual scrolling issue --- .../gallery-native/CHANGELOG.md | 5 ++ .../gallery-native/src/components/Gallery.tsx | 73 +++++++++++-------- .../__snapshots__/Gallery.spec.tsx.snap | 7 ++ 3 files changed, 56 insertions(+), 29 deletions(-) diff --git a/packages/pluggableWidgets/gallery-native/CHANGELOG.md b/packages/pluggableWidgets/gallery-native/CHANGELOG.md index b02304cc2..0ce1a28e6 100644 --- a/packages/pluggableWidgets/gallery-native/CHANGELOG.md +++ b/packages/pluggableWidgets/gallery-native/CHANGELOG.md @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +### Fixed + +- We've fixed an issue where the Gallery widget would not properly load more items when scrolling down quickly. + + ## [2.0.0] - 2024-12-3 - Updated react-native-device-info to latest version. diff --git a/packages/pluggableWidgets/gallery-native/src/components/Gallery.tsx b/packages/pluggableWidgets/gallery-native/src/components/Gallery.tsx index bf2a151c7..6bef9a7ae 100644 --- a/packages/pluggableWidgets/gallery-native/src/components/Gallery.tsx +++ b/packages/pluggableWidgets/gallery-native/src/components/Gallery.tsx @@ -1,4 +1,4 @@ -import { createElement, ReactElement, ReactNode } from "react"; +import { createElement, ReactElement, ReactNode, useCallback } from "react"; import { Text, FlatList, Pressable, View, ViewProps, Platform, TouchableOpacity } from "react-native"; import { ObjectItem, DynamicValue } from "mendix"; import DeviceInfo from "react-native-device-info"; @@ -32,6 +32,7 @@ export const Gallery = (props: GalleryProps): ReactElem const numColumns = DeviceInfo.isTablet() ? props.tabletColumns : props.phoneColumns; const firstItemId = props.items?.[0]?.id; const lastItemId = props.items?.[props.items.length - 1]?.id; + const { name, style, itemRenderer } = props; const onEndReached = (): void => { if (props.pagination === "virtualScrolling" && props.hasMoreItems) { @@ -39,31 +40,44 @@ export const Gallery = (props: GalleryProps): ReactElem } }; - const renderItem = (item: { item: T }): ReactElement => - props.itemRenderer((children, onPress) => { - const listItemWrapperProps: ViewProps = { - style: isScrollDirectionVertical && { width: `${100 / numColumns}%` }, - testID: `${props.name}-list-item-${item.item.id}` - }; - const renderListItemContent = ( - - {children} - - ); - return onPress ? ( - - {renderListItemContent} - - ) : ( - {renderListItemContent} - ); - }, item.item); + const renderItem = useCallback( + (item: { item: T }): ReactElement => + itemRenderer((children, onPress) => { + const listItemWrapperProps: ViewProps = { + style: isScrollDirectionVertical && { width: `${100 / numColumns}%` }, + testID: `${name}-list-item-${item.item.id}` + }; + const renderListItemContent = ( + + {children} + + ); + return onPress ? ( + + {renderListItemContent} + + ) : ( + {renderListItemContent} + ); + }, item.item), + [ + isScrollDirectionVertical, + numColumns, + itemRenderer, + name, + style.listItem, + style.firstItem, + style.lastItem, + firstItemId, + lastItemId + ] + ); const loadMoreButton = (): ReactElement | null => { const renderButton = ( @@ -80,7 +94,7 @@ export const Gallery = (props: GalleryProps): ReactElem ); const buttonProps = { - testID: `${props.name}-pagination-button`, + testID: `${name}-pagination-button`, onPress: () => props.hasMoreItems && props.loadMoreItems && props.loadMoreItems(), style: loadMoreButtonContainerStyle }; @@ -111,7 +125,7 @@ export const Gallery = (props: GalleryProps): ReactElem ); return ( - + {props.filters ? {props.filters} : null} (props: GalleryProps): ReactElem keyExtractor={item => item.id} ListEmptyComponent={renderEmptyPlaceholder} onEndReached={onEndReached} + onEndReachedThreshold={0.6} scrollEventThrottle={50} renderItem={renderItem} style={props.style.list} - testID={`${props.name}-list`} + testID={`${name}-list`} /> ); diff --git a/packages/pluggableWidgets/gallery-native/src/components/__tests__/__snapshots__/Gallery.spec.tsx.snap b/packages/pluggableWidgets/gallery-native/src/components/__tests__/__snapshots__/Gallery.spec.tsx.snap index d1fd5c294..6e6f2fa91 100644 --- a/packages/pluggableWidgets/gallery-native/src/components/__tests__/__snapshots__/Gallery.spec.tsx.snap +++ b/packages/pluggableWidgets/gallery-native/src/components/__tests__/__snapshots__/Gallery.spec.tsx.snap @@ -50,6 +50,7 @@ exports[`Gallery rendering rendering with load more button it shouldn't render t keyExtractor={[Function]} onContentSizeChange={[Function]} onEndReached={[Function]} + onEndReachedThreshold={0.6} onLayout={[Function]} onMomentumScrollBegin={[Function]} onMomentumScrollEnd={[Function]} @@ -377,6 +378,7 @@ exports[`Gallery rendering rendering with load more button renders correctly 1`] keyExtractor={[Function]} onContentSizeChange={[Function]} onEndReached={[Function]} + onEndReachedThreshold={0.6} onLayout={[Function]} onMomentumScrollBegin={[Function]} onMomentumScrollEnd={[Function]} @@ -750,6 +752,7 @@ exports[`Gallery rendering rendering with load more button renders correctly wit keyExtractor={[Function]} onContentSizeChange={[Function]} onEndReached={[Function]} + onEndReachedThreshold={0.6} onLayout={[Function]} onMomentumScrollBegin={[Function]} onMomentumScrollEnd={[Function]} @@ -1123,6 +1126,7 @@ exports[`Gallery rendering renders correctly 1`] = ` keyExtractor={[Function]} onContentSizeChange={[Function]} onEndReached={[Function]} + onEndReachedThreshold={0.6} onLayout={[Function]} onMomentumScrollBegin={[Function]} onMomentumScrollEnd={[Function]} @@ -1450,6 +1454,7 @@ exports[`Gallery rendering renders correctly horizontal 1`] = ` keyExtractor={[Function]} onContentSizeChange={[Function]} onEndReached={[Function]} + onEndReachedThreshold={0.6} onLayout={[Function]} onMomentumScrollBegin={[Function]} onMomentumScrollEnd={[Function]} @@ -1758,6 +1763,7 @@ exports[`Gallery rendering renders correctly with empty list and custom placehol keyExtractor={[Function]} onContentSizeChange={[Function]} onEndReached={[Function]} + onEndReachedThreshold={0.6} onLayout={[Function]} onMomentumScrollBegin={[Function]} onMomentumScrollEnd={[Function]} @@ -1844,6 +1850,7 @@ exports[`Gallery rendering renders correctly with filter 1`] = ` keyExtractor={[Function]} onContentSizeChange={[Function]} onEndReached={[Function]} + onEndReachedThreshold={0.6} onLayout={[Function]} onMomentumScrollBegin={[Function]} onMomentumScrollEnd={[Function]} From 00d55491bfc3e5ea5bd53f1a62d0ffe4402aa68a Mon Sep 17 00:00:00 2001 From: MxKevinBeqo Date: Tue, 7 Oct 2025 14:59:52 +0200 Subject: [PATCH 2/2] chore(gallery-native): version bump and changelog update --- packages/pluggableWidgets/gallery-native/CHANGELOG.md | 5 +++-- packages/pluggableWidgets/gallery-native/package.json | 2 +- packages/pluggableWidgets/gallery-native/src/package.xml | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/pluggableWidgets/gallery-native/CHANGELOG.md b/packages/pluggableWidgets/gallery-native/CHANGELOG.md index 0ce1a28e6..4f98b8a2e 100644 --- a/packages/pluggableWidgets/gallery-native/CHANGELOG.md +++ b/packages/pluggableWidgets/gallery-native/CHANGELOG.md @@ -10,11 +10,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - We've fixed an issue where the Gallery widget would not properly load more items when scrolling down quickly. - -## [2.0.0] - 2024-12-3 +## [2.0.1] - 2025-8-5 - Updated react-native-device-info to latest version. +## [2.0.0] - 2024-12-3 + ### Changed - Updated @mendix/pluggable-widgets-tools from version v9.0.0 to v10.15.0. diff --git a/packages/pluggableWidgets/gallery-native/package.json b/packages/pluggableWidgets/gallery-native/package.json index f33cc9ddd..01f5ed2a0 100644 --- a/packages/pluggableWidgets/gallery-native/package.json +++ b/packages/pluggableWidgets/gallery-native/package.json @@ -1,7 +1,7 @@ { "name": "gallery-native", "widgetName": "Gallery", - "version": "2.0.1", + "version": "2.0.2", "description": "A flexible gallery widget that renders columns, rows and layouts.", "copyright": "© Mendix Technology BV 2022. All rights reserved.", "license": "Apache-2.0", diff --git a/packages/pluggableWidgets/gallery-native/src/package.xml b/packages/pluggableWidgets/gallery-native/src/package.xml index 80b03d697..827740b2c 100644 --- a/packages/pluggableWidgets/gallery-native/src/package.xml +++ b/packages/pluggableWidgets/gallery-native/src/package.xml @@ -1,6 +1,6 @@ - +