Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 26 additions & 6 deletions fixture/react-native/src/ComplexMasonry.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import React, { forwardRef, ForwardedRef, useState, useCallback } from "react";
import React, {
forwardRef,
ForwardedRef,
useState,
useCallback,
useEffect,
useRef,
} from "react";
import {
Text,
View,
StyleSheet,
Platform,
TouchableOpacity,
ActivityIndicator,
useWindowDimensions,
} from "react-native";
import { FlashListRef, FlashList } from "@shopify/flash-list";
import FastImage from "@d11/react-native-fast-image";
Expand Down Expand Up @@ -132,9 +140,21 @@ const MasonryCard = ({

// Create our masonry component
const ComplexMasonryComponent = (_: unknown, ref: ForwardedRef<unknown>) => {
const { height } = useWindowDimensions();
const columnCount = 3;
const [items, setItems] = useState(() => generateMasonryData(50));
const [isLoading, setIsLoading] = useState(false);
const loadTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);

useEffect(
() => () => {
if (loadTimeout.current !== null) {
clearTimeout(loadTimeout.current);
loadTimeout.current = null;
}
},
[]
);

// Handle toggling the expanded state of an item
const handleToggleExpand = useCallback((id: string) => {
Expand All @@ -147,19 +167,20 @@ const ComplexMasonryComponent = (_: unknown, ref: ForwardedRef<unknown>) => {

// Handle loading more items when reaching the end of the list
const handleEndReached = useCallback(() => {
if (isLoading) return;
if (loadTimeout.current !== null) return;

setIsLoading(true);

// Simulate network delay
setTimeout(() => {
loadTimeout.current = setTimeout(() => {
loadTimeout.current = null;
setItems((currentItems) => [
...currentItems,
...generateMasonryData(20, currentItems.length),
]);
setIsLoading(false);
}, 500);
}, [isLoading]);
}, []);

// Footer component with loading indicator
const renderFooter = useCallback(() => {
Expand All @@ -180,7 +201,7 @@ const ComplexMasonryComponent = (_: unknown, ref: ForwardedRef<unknown>) => {
);

return (
<View style={styles.container}>
<View style={[styles.container, Platform.OS === "web" && { height }]}>
<FlashList
ref={ref as React.RefObject<FlashListRef<MasonryItem>>}
testID="ComplexMasonryList"
Expand Down Expand Up @@ -218,7 +239,6 @@ export const ComplexMasonry = forwardRef(ComplexMasonryComponent);
const styles = StyleSheet.create({
container: {
flex: Platform.OS === "web" ? undefined : 1,
height: Platform.OS === "web" ? window.innerHeight : undefined,
backgroundColor: "#f5f5f5",
},
listContent: {
Expand Down
21 changes: 12 additions & 9 deletions fixture/react-native/src/DynamicColumnSpan.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import React, { useMemo, useState, useCallback } from "react";
import { Text, View, StyleSheet, Platform, Pressable } from "react-native";
import {
Text,
View,
StyleSheet,
Platform,
Pressable,
useWindowDimensions,
} from "react-native";
import { FlashList, useRecyclingState } from "@shopify/flash-list";

interface DynamicItem {
Expand Down Expand Up @@ -53,6 +60,7 @@ const arraysEqual = (arr1: number[], arr2: number[]): boolean => {
};

export function DynamicColumnSpan() {
const { height } = useWindowDimensions();
const [numItems] = useState(500);
const [isMasonry, setIsMasonry] = useState(false);
const [numColumns, setNumColumns] = useState(3);
Expand Down Expand Up @@ -101,10 +109,6 @@ export function DynamicColumnSpan() {
[]
);

const toggleLayout = () => {
setIsMasonry(!isMasonry);
};

const changeColumns = (cols: number) => {
setNumColumns(cols);
};
Expand All @@ -115,14 +119,14 @@ export function DynamicColumnSpan() {

return (
<React.StrictMode>
<View style={styles.container}>
<View style={[styles.container, Platform.OS === "web" && { height }]}>
{/* Control Panel */}
<View style={styles.controlPanel}>
<View style={styles.controlRow}>
<Text style={styles.controlLabel}>Layout:</Text>
<Pressable
style={[styles.controlButton, !isMasonry && styles.activeButton]}
onPress={toggleLayout}
onPress={() => setIsMasonry(false)}
>
<Text
style={[
Expand All @@ -135,7 +139,7 @@ export function DynamicColumnSpan() {
</Pressable>
<Pressable
style={[styles.controlButton, isMasonry && styles.activeButton]}
onPress={toggleLayout}
onPress={() => setIsMasonry(true)}
>
<Text
style={[
Expand Down Expand Up @@ -275,7 +279,6 @@ const DynamicGridItem = ({
const styles = StyleSheet.create({
container: {
flex: Platform.OS === "web" ? undefined : 1,
height: Platform.OS === "web" ? window.innerHeight : undefined,
backgroundColor: "#f5f5f5",
},
controlPanel: {
Expand Down
13 changes: 10 additions & 3 deletions fixture/react-native/src/Grid.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import React, { useMemo, useState, useCallback } from "react";
import { Text, View, StyleSheet, Platform, Pressable } from "react-native";
import {
Text,
View,
StyleSheet,
Platform,
Pressable,
useWindowDimensions,
} from "react-native";
import { FlashList, useRecyclingState } from "@shopify/flash-list";

interface GridItem {
Expand Down Expand Up @@ -41,6 +48,7 @@ const generateData = (count: number): GridItem[] => {
};

export function Grid() {
const { height } = useWindowDimensions();
const [numItems] = useState(1000); // Default to 100 items

// Generate colors for the grid items
Expand Down Expand Up @@ -69,7 +77,7 @@ export function Grid() {

return (
<React.StrictMode>
<View style={styles.container}>
<View style={[styles.container, Platform.OS === "web" && { height }]}>
<FlashList
testID="GridScreen"
data={data}
Expand Down Expand Up @@ -118,7 +126,6 @@ const GridItem = ({ item }: { item: GridItem }) => {
const styles = StyleSheet.create({
container: {
flex: Platform.OS === "web" ? undefined : 1,
height: Platform.OS === "web" ? window.innerHeight : undefined,
backgroundColor: "#f5f5f5",
},
itemWrapper: {
Expand Down
6 changes: 4 additions & 2 deletions fixture/react-native/src/LayoutOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
Pressable,
Switch,
ScrollView,
useWindowDimensions,
} from "react-native";
import { FlashList, useRecyclingState } from "@shopify/flash-list";

Expand Down Expand Up @@ -38,6 +39,7 @@ const colors = [
];

export function LayoutOptions() {
const { height } = useWindowDimensions();
// Configuration states
const [numColumns, setNumColumns] = useState(1);
const [isHorizontal, setIsHorizontal] = useState(false);
Expand Down Expand Up @@ -88,10 +90,11 @@ export function LayoutOptions() {
}, []);

return (
<View style={styles.container}>
<View style={[styles.container, Platform.OS === "web" && { height }]}>
{renderControls()}

<FlashList
key={isHorizontal ? "horizontal" : "vertical"}
data={data}
numColumns={isHorizontal ? 1 : numColumns}
horizontal={isHorizontal}
Expand Down Expand Up @@ -151,7 +154,6 @@ const ListItemComponent = ({ item }: { item: ListItem }) => {
const styles = StyleSheet.create({
container: {
flex: Platform.OS === "web" ? undefined : 1,
height: Platform.OS === "web" ? window.innerHeight : undefined,
backgroundColor: "#f5f5f5",
},
controls: {
Expand Down
12 changes: 9 additions & 3 deletions fixture/react-native/src/Masonry.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import React from "react";
import { Text, View, StyleSheet, Platform } from "react-native";
import {
Text,
View,
StyleSheet,
Platform,
useWindowDimensions,
} from "react-native";
import { FlashList } from "@shopify/flash-list";

interface MasonryData {
Expand All @@ -8,6 +14,7 @@ interface MasonryData {
}

export function Masonry() {
const { height } = useWindowDimensions();
const columnCount = 3;
const data: MasonryData[] = new Array(999).fill(null).map((_, index) => {
return {
Expand All @@ -17,7 +24,7 @@ export function Masonry() {
});
return (
<React.StrictMode>
<View style={styles.container}>
<View style={[styles.container, Platform.OS === "web" && { height }]}>
<FlashList
testID="MasonryList"
data={data}
Expand Down Expand Up @@ -100,7 +107,6 @@ const Component = (props: {
const styles = StyleSheet.create({
container: {
flex: Platform.OS === "web" ? undefined : 1,
height: Platform.OS === "web" ? window.innerHeight : undefined,
justifyContent: "center",
backgroundColor: "#ecf0f1",
},
Expand Down
17 changes: 12 additions & 5 deletions fixture/web/Grid.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import React, { useMemo, useState, useCallback } from "react";
import { Text, View, StyleSheet, Platform, Pressable } from "react-native";
import { RecyclerView, useRecyclingState } from "@shopify/flash-list";
import {
Text,
View,
StyleSheet,
Platform,
Pressable,
useWindowDimensions,
} from "react-native";
import { FlashList, useRecyclingState } from "@shopify/flash-list";

interface GridItem {
id: number;
Expand Down Expand Up @@ -41,6 +48,7 @@ const generateData = (count: number): GridItem[] => {
};

export function Grid() {
const { height } = useWindowDimensions();
const [numItems] = useState(1000); // Default to 100 items

// Generate colors for the grid items
Expand Down Expand Up @@ -68,8 +76,8 @@ export function Grid() {
const keyExtractor = useCallback((item: GridItem) => item.id.toString(), []);

return (
<View style={styles.container}>
<RecyclerView
<View style={[styles.container, Platform.OS === "web" && { height }]}>
<FlashList
testID="GridScreen"
data={data}
numColumns={2}
Expand Down Expand Up @@ -115,7 +123,6 @@ const GridItem = ({ item }: { item: GridItem }) => {
const styles = StyleSheet.create({
container: {
flex: Platform.OS === "web" ? undefined : 1,
height: Platform.OS === "web" ? window.innerHeight : undefined,
backgroundColor: "#f5f5f5",
},
itemWrapper: {
Expand Down
Loading