diff --git a/packages/pluggableWidgets/gallery-native/CHANGELOG.md b/packages/pluggableWidgets/gallery-native/CHANGELOG.md index 7a052fcf5..d7b45c55e 100644 --- a/packages/pluggableWidgets/gallery-native/CHANGELOG.md +++ b/packages/pluggableWidgets/gallery-native/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +- We've fixed an issue where Gallery widget does not display data. + ## [2.2.1] - 2026-6-10 ### Changed diff --git a/packages/pluggableWidgets/gallery-native/package.json b/packages/pluggableWidgets/gallery-native/package.json index 191460789..6ab6f707d 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.2.1", + "version": "2.2.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/components/Gallery.tsx b/packages/pluggableWidgets/gallery-native/src/components/Gallery.tsx index 99660d44f..b0a6e070a 100644 --- a/packages/pluggableWidgets/gallery-native/src/components/Gallery.tsx +++ b/packages/pluggableWidgets/gallery-native/src/components/Gallery.tsx @@ -1,5 +1,14 @@ -import { ReactElement, ReactNode, useCallback, useMemo } from "react"; -import { Text, Pressable, View, ViewProps, Platform, TouchableOpacity, useWindowDimensions } from "react-native"; +import { ReactElement, ReactNode, useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { + LayoutChangeEvent, + Text, + Pressable, + View, + ViewProps, + Platform, + TouchableOpacity, + useWindowDimensions +} from "react-native"; import { ObjectItem, DynamicValue } from "mendix"; import DeviceInfo from "react-native-device-info"; import { GalleryStyle } from "../ui/Styles"; @@ -35,6 +44,13 @@ export const Gallery = (props: GalleryProps): ReactElem const lastItemId = props.items?.[props.items.length - 1]?.id; const { name, style, itemRenderer } = props; const { width } = useWindowDimensions(); + // FlashList requires a non-zero height to render items (it's virtualized and needs viewport dimensions). + // When the parent provides height (e.g. via flex), we use flex: 1. When it doesn't (e.g. a Container + // widget with no flex/height), flex: 1 resolves to 0 and nothing renders. In that case, we fall back + // to minHeight based on FlashList's reported content size. We measure the FlashList area specifically so we get the height of the list area, not the entire Gallery (which may include filters and padding). + const listAreaRef = useRef(null); + const [contentHeight, setContentHeight] = useState(0); + const [layoutDecision, setLayoutDecision] = useState<"minHeight" | "flex" | null>(null); const onEndReached = (): void => { if (props.pagination === "virtualScrolling" && props.hasMoreItems) { @@ -136,29 +152,62 @@ export const Gallery = (props: GalleryProps): ReactElem [props.style.emptyPlaceholder, props.emptyPlaceholder] ); + const handleListAreaLayout = useCallback( + (event: LayoutChangeEvent) => { + const { height } = event.nativeEvent.layout; + if (height > 0 && layoutDecision === null) { + setLayoutDecision("flex"); + } + }, + [layoutDecision] + ); + + useEffect(() => { + if (contentHeight > 0 && layoutDecision === null && listAreaRef.current) { + listAreaRef.current.measure((_x, _y, _width, height) => { + setLayoutDecision(height > 0 ? "flex" : "minHeight"); + }); + } + }, [contentHeight, layoutDecision]); + + const containerStyle = isScrollDirectionVertical + ? layoutDecision === "minHeight" + ? [{ minHeight: Math.max(contentHeight, 1) }, props.style.container] + : [{ flex: 1 }, props.style.container] + : props.style.container; + + const listStyle = isScrollDirectionVertical ? [{ flex: 1 }, props.style.list] : props.style.list; + return ( - + {props.filters ? {props.filters} : null} - item.id} - ListEmptyComponent={renderEmptyPlaceholder} - onEndReached={onEndReached} - onEndReachedThreshold={0.6} - scrollEventThrottle={50} - renderItem={renderItem} - style={props.style.list} - testID={`${name}-list`} - /> + + item.id} + ListEmptyComponent={renderEmptyPlaceholder} + onEndReached={onEndReached} + onEndReachedThreshold={0.6} + scrollEventThrottle={50} + renderItem={renderItem} + style={listStyle} + testID={`${name}-list`} + onContentSizeChange={isScrollDirectionVertical ? (_w, h) => setContentHeight(h) : undefined} + /> + ); }; 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 70a4343a0..2547620a5 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 @@ -2,173 +2,198 @@ exports[`Gallery rendering rendering with load more button it shouldn't render the paging button if hasn't more item 1`] = ` - - + + - 11 + + 11 + - - - + - 22 + + 22 + - - - + - 33 + + 33 + - - - + - 44 + + 44 + - - - + - 55 + + 55 + - - - + - 66 + + 66 + - - - + - 77 + + 77 + - - - + - 88 + + 88 + - - - + - 99 + + 99 + @@ -178,220 +203,245 @@ exports[`Gallery rendering rendering with load more button it shouldn't render t exports[`Gallery rendering rendering with load more button renders correctly 1`] = ` - - + + - 11 + + 11 + - - - + - 22 + + 22 + - - - + - 33 + + 33 + - - - + - 44 + + 44 + - - - + - 55 + + 55 + - - - + - 66 + + 66 + - - - + - 77 + + 77 + - - - + - 88 + + 88 + - - - + - 99 + + 99 + - - - - Load more - + onBlur={[Function]} + onClick={[Function]} + onFocus={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={{}} + testID="gallery-test-pagination-button" + > + + Load more + + @@ -399,220 +449,245 @@ exports[`Gallery rendering rendering with load more button renders correctly 1`] exports[`Gallery rendering rendering with load more button renders correctly with custom paging button title 1`] = ` - - + + - 11 + + 11 + - - - + - 22 + + 22 + - - - + - 33 + + 33 + - - - + - 44 + + 44 + - - - + - 55 + + 55 + - - - + - 66 + + 66 + - - - + - 77 + + 77 + - - - + - 88 + + 88 + - - - + - 99 + + 99 + - - - - Show more - + onBlur={[Function]} + onClick={[Function]} + onFocus={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={{}} + testID="gallery-test-pagination-button" + > + + Show more + + @@ -620,173 +695,198 @@ exports[`Gallery rendering rendering with load more button renders correctly wit exports[`Gallery rendering renders correctly 1`] = ` - - + + - 11 + + 11 + - - - + - 22 + + 22 + - - - + - 33 + + 33 + - - - + - 44 + + 44 + - - - + - 55 + + 55 + - - - + - 66 + + 66 + - - - + - 77 + + 77 + - - - + - 88 + + 88 + - - - + - 99 + + 99 + @@ -799,214 +899,216 @@ exports[`Gallery rendering renders correctly horizontal 1`] = ` style={{}} testID="gallery-test" > - - - + + } + horizontal={true} + keyExtractor={[Function]} + onEndReached={[Function]} + onEndReachedThreshold={0.6} + scrollEventThrottle={50} + testID="gallery-test-list" + > + - 11 + + 11 + - - - + - 22 + + 22 + - - - + - 33 + + 33 + - - - + - 44 + + 44 + - - - + - 55 + + 55 + - - - + - 66 + + 66 + - - - + - 77 + + 77 + - - - + - 88 + + 88 + - - - + - 99 + + 99 + @@ -1016,28 +1118,53 @@ exports[`Gallery rendering renders correctly horizontal 1`] = ` exports[`Gallery rendering renders correctly with empty list and custom placeholder 1`] = ` - - - Empty list... - + + + + Empty list... + + @@ -1045,176 +1172,201 @@ exports[`Gallery rendering renders correctly with empty list and custom placehol exports[`Gallery rendering renders correctly with filter 1`] = ` - - + + - 11 + + 11 + - - - + - 22 + + 22 + - - - + - 33 + + 33 + - - - + - 44 + + 44 + - - - + - 55 + + 55 + - - - + - 66 + + 66 + - - - + - 77 + + 77 + - - - + - 88 + + 88 + - - - + - 99 + + 99 + diff --git a/packages/pluggableWidgets/gallery-native/src/package.xml b/packages/pluggableWidgets/gallery-native/src/package.xml index 83840116c..812f72309 100644 --- a/packages/pluggableWidgets/gallery-native/src/package.xml +++ b/packages/pluggableWidgets/gallery-native/src/package.xml @@ -1,6 +1,6 @@ - +