forked from Shopify/flash-list
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathMasonry.tsx
112 lines (108 loc) · 2.86 KB
/
Masonry.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import React from "react";
import { Text, View, StyleSheet, Platform } from "react-native";
import { MasonryFlashList } from "@shopify/flash-list";
interface MasonryData {
index: number;
height: number;
}
export function Masonry() {
const columnCount = 3;
const data: MasonryData[] = new Array(999).fill(null).map((_, index) => {
return {
index,
height: ((index * 10) % 100) + 100 / ((index % columnCount) + 1),
};
});
return (
<View style={styles.container}>
<MasonryFlashList
testID="MasonryList"
data={data}
optimizeItemArrangement
overrideItemLayout={(layout, item) => {
layout.size = item.height;
}}
numColumns={columnCount}
estimatedItemSize={150}
ListHeaderComponent={
<Component
item={{ index: 0, height: 100 }}
text="Header"
backgroundColor="red"
/>
}
ListFooterComponent={
<Component
item={{ index: 0, height: 100 }}
text="Footer"
backgroundColor="lightblue"
/>
}
ListEmptyComponent={
<Component
item={{ index: 0, height: 100 }}
text="Empty"
backgroundColor="black"
/>
}
onViewableItemsChanged={(info) => {
info.changed.forEach((item) => {
if (item.isViewable) {
console.log("Viewable:", item.index);
}
});
}}
keyExtractor={(item, index) => {
if (item.index !== index) {
console.log("Key Extractor issue @", index);
}
return item.index.toString();
}}
getItemType={(item, index) => {
if (item.index !== index) {
console.log(index);
}
return undefined;
}}
renderItem={({ item }) => {
return <Component item={item} />;
}}
getColumnFlex={(_, index) => {
return index === 1 ? 2 : 1;
}}
onLoad={({ elapsedTimeInMs }) => {
console.log("List Load Time", elapsedTimeInMs);
}}
contentContainerStyle={{ paddingHorizontal: 2 }}
/>
</View>
);
}
const Component = (props: {
item: MasonryData;
text?: string;
backgroundColor?: string;
}) => {
return (
<View
style={{
height: props.item.height,
backgroundColor: props.backgroundColor ?? "darkgray",
margin: 2,
alignItems: "center",
justifyContent: "center",
borderRadius: 10,
}}
>
<Text>{props.text ?? props.item.index}</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: Platform.OS === "web" ? undefined : 1,
height: Platform.OS === "web" ? window.innerHeight : undefined,
justifyContent: "center",
backgroundColor: "#ecf0f1",
},
});