@legendapp/list 2.0.0-next.2 → 2.0.0-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/{dist/animated.d.mts → animated.d.mts} +1 -0
  2. package/{dist/animated.d.ts → animated.d.ts} +1 -0
  3. package/{dist/index.d.mts → index.d.mts} +8 -1
  4. package/{dist/index.d.ts → index.d.ts} +8 -1
  5. package/{dist/index.js → index.js} +50 -4
  6. package/{dist/index.mjs → index.mjs} +50 -4
  7. package/{dist/keyboard-controller.d.mts → keyboard-controller.d.mts} +4 -0
  8. package/{dist/keyboard-controller.d.ts → keyboard-controller.d.ts} +4 -0
  9. package/package.json +34 -88
  10. package/.claude/settings.local.json +0 -8
  11. package/.cursor/rules/changelog.mdc +0 -60
  12. package/.github/FUNDING.yml +0 -15
  13. package/.gitignore +0 -5
  14. package/.prettierrc.json +0 -5
  15. package/.vscode/settings.json +0 -14
  16. package/CLAUDE.md +0 -126
  17. package/biome.json +0 -46
  18. package/bun.lock +0 -1289
  19. package/bunfig.toml +0 -2
  20. package/dist/CHANGELOG.md +0 -119
  21. package/dist/LICENSE +0 -21
  22. package/dist/README.md +0 -139
  23. package/dist/package.json +0 -35
  24. package/example/README.md +0 -40
  25. package/example/api/data/genres.json +0 -23
  26. package/example/api/data/playlist/10402-10749.json +0 -1
  27. package/example/api/data/playlist/10402-10770.json +0 -1
  28. package/example/api/data/playlist/10402-37.json +0 -1
  29. package/example/api/data/playlist/10749-10752.json +0 -1
  30. package/example/api/data/playlist/10749-10770.json +0 -1
  31. package/example/api/data/playlist/10749-37.json +0 -1
  32. package/example/api/data/playlist/10749-878.json +0 -1
  33. package/example/api/data/playlist/10751-10402.json +0 -1
  34. package/example/api/data/playlist/10751-10752.json +0 -1
  35. package/example/api/data/playlist/10751-37.json +0 -1
  36. package/example/api/data/playlist/10751-53.json +0 -1
  37. package/example/api/data/playlist/10751-878.json +0 -1
  38. package/example/api/data/playlist/10751-9648.json +0 -1
  39. package/example/api/data/playlist/10752-37.json +0 -1
  40. package/example/api/data/playlist/12-10402.json +0 -1
  41. package/example/api/data/playlist/12-10749.json +0 -1
  42. package/example/api/data/playlist/12-18.json +0 -1
  43. package/example/api/data/playlist/12-27.json +0 -1
  44. package/example/api/data/playlist/12-35.json +0 -1
  45. package/example/api/data/playlist/14-36.json +0 -1
  46. package/example/api/data/playlist/14-878.json +0 -1
  47. package/example/api/data/playlist/16-10751.json +0 -1
  48. package/example/api/data/playlist/16-10770.json +0 -1
  49. package/example/api/data/playlist/16-35.json +0 -1
  50. package/example/api/data/playlist/16-36.json +0 -1
  51. package/example/api/data/playlist/16-53.json +0 -1
  52. package/example/api/data/playlist/18-10751.json +0 -1
  53. package/example/api/data/playlist/18-10752.json +0 -1
  54. package/example/api/data/playlist/18-37.json +0 -1
  55. package/example/api/data/playlist/18-53.json +0 -1
  56. package/example/api/data/playlist/18-878.json +0 -1
  57. package/example/api/data/playlist/27-10749.json +0 -1
  58. package/example/api/data/playlist/27-10770.json +0 -1
  59. package/example/api/data/playlist/28-10749.json +0 -1
  60. package/example/api/data/playlist/28-10751.json +0 -1
  61. package/example/api/data/playlist/28-10770.json +0 -1
  62. package/example/api/data/playlist/28-16.json +0 -1
  63. package/example/api/data/playlist/28-18.json +0 -1
  64. package/example/api/data/playlist/28-36.json +0 -1
  65. package/example/api/data/playlist/28-37.json +0 -1
  66. package/example/api/data/playlist/28-53.json +0 -1
  67. package/example/api/data/playlist/28-80.json +0 -1
  68. package/example/api/data/playlist/28-99.json +0 -1
  69. package/example/api/data/playlist/35-10749.json +0 -1
  70. package/example/api/data/playlist/35-10751.json +0 -1
  71. package/example/api/data/playlist/35-10752.json +0 -1
  72. package/example/api/data/playlist/35-27.json +0 -1
  73. package/example/api/data/playlist/35-36.json +0 -1
  74. package/example/api/data/playlist/35-53.json +0 -1
  75. package/example/api/data/playlist/35-80.json +0 -1
  76. package/example/api/data/playlist/36-37.json +0 -1
  77. package/example/api/data/playlist/36-878.json +0 -1
  78. package/example/api/data/playlist/36-9648.json +0 -1
  79. package/example/api/data/playlist/53-10752.json +0 -1
  80. package/example/api/data/playlist/80-10770.json +0 -1
  81. package/example/api/data/playlist/80-14.json +0 -1
  82. package/example/api/data/playlist/80-18.json +0 -1
  83. package/example/api/data/playlist/80-37.json +0 -1
  84. package/example/api/data/playlist/878-37.json +0 -1
  85. package/example/api/data/playlist/9648-10770.json +0 -1
  86. package/example/api/data/playlist/9648-37.json +0 -1
  87. package/example/api/data/playlist/9648-53.json +0 -1
  88. package/example/api/data/playlist/9648-878.json +0 -1
  89. package/example/api/data/playlist/99-10749.json +0 -1
  90. package/example/api/data/playlist/99-14.json +0 -1
  91. package/example/api/data/playlist/99-18.json +0 -1
  92. package/example/api/data/playlist/99-27.json +0 -1
  93. package/example/api/data/playlist/99-53.json +0 -1
  94. package/example/api/data/playlist/99-9648.json +0 -1
  95. package/example/api/data/playlist/index.ts +0 -73
  96. package/example/api/data/rows.json +0 -1
  97. package/example/api/index.ts +0 -36
  98. package/example/app/(tabs)/_layout.tsx +0 -60
  99. package/example/app/(tabs)/cards.tsx +0 -81
  100. package/example/app/(tabs)/index.tsx +0 -205
  101. package/example/app/(tabs)/moviesL.tsx +0 -7
  102. package/example/app/(tabs)/moviesLR.tsx +0 -7
  103. package/example/app/+not-found.tsx +0 -32
  104. package/example/app/_layout.tsx +0 -34
  105. package/example/app/accurate-scrollto/index.tsx +0 -125
  106. package/example/app/accurate-scrollto-2/index.tsx +0 -52
  107. package/example/app/accurate-scrollto-huge/index.tsx +0 -128
  108. package/example/app/add-to-end/index.tsx +0 -82
  109. package/example/app/ai-chat/index.tsx +0 -236
  110. package/example/app/bidirectional-infinite-list/index.tsx +0 -133
  111. package/example/app/cards-columns/index.tsx +0 -37
  112. package/example/app/cards-flashlist/index.tsx +0 -122
  113. package/example/app/cards-flatlist/index.tsx +0 -94
  114. package/example/app/cards-no-recycle/index.tsx +0 -110
  115. package/example/app/cards-renderItem.tsx +0 -354
  116. package/example/app/chat-example/index.tsx +0 -167
  117. package/example/app/chat-infinite/index.tsx +0 -239
  118. package/example/app/chat-keyboard/index.tsx +0 -248
  119. package/example/app/chat-resize-outer/index.tsx +0 -247
  120. package/example/app/columns/index.tsx +0 -78
  121. package/example/app/countries/index.tsx +0 -182
  122. package/example/app/countries-flashlist/index.tsx +0 -163
  123. package/example/app/countries-reorder/index.tsx +0 -187
  124. package/example/app/extra-data/index.tsx +0 -86
  125. package/example/app/filter-elements/filter-data-provider.tsx +0 -55
  126. package/example/app/filter-elements/index.tsx +0 -118
  127. package/example/app/initial-scroll-index/index.tsx +0 -106
  128. package/example/app/initial-scroll-index/renderFixedItem.tsx +0 -215
  129. package/example/app/initial-scroll-index-free-height/index.tsx +0 -70
  130. package/example/app/initial-scroll-index-keyed/index.tsx +0 -62
  131. package/example/app/lazy-list/index.tsx +0 -123
  132. package/example/app/movies-flashlist/index.tsx +0 -7
  133. package/example/app/mutable-cells/index.tsx +0 -104
  134. package/example/app/video-feed/index.tsx +0 -119
  135. package/example/app.config.js +0 -22
  136. package/example/app.json +0 -45
  137. package/example/assets/fonts/SpaceMono-Regular.ttf +0 -0
  138. package/example/assets/images/adaptive-icon.png +0 -0
  139. package/example/assets/images/favicon.png +0 -0
  140. package/example/assets/images/icon.png +0 -0
  141. package/example/assets/images/partial-react-logo.png +0 -0
  142. package/example/assets/images/react-logo.png +0 -0
  143. package/example/assets/images/react-logo@2x.png +0 -0
  144. package/example/assets/images/react-logo@3x.png +0 -0
  145. package/example/assets/images/splash-icon.png +0 -0
  146. package/example/autoscroll.sh +0 -101
  147. package/example/bun.lock +0 -2266
  148. package/example/bunfig.toml +0 -2
  149. package/example/components/Breathe.tsx +0 -54
  150. package/example/components/Circle.tsx +0 -69
  151. package/example/components/Collapsible.tsx +0 -44
  152. package/example/components/ExternalLink.tsx +0 -24
  153. package/example/components/HapticTab.tsx +0 -18
  154. package/example/components/HelloWave.tsx +0 -37
  155. package/example/components/Movies.tsx +0 -179
  156. package/example/components/ParallaxScrollView.tsx +0 -81
  157. package/example/components/ThemedText.tsx +0 -60
  158. package/example/components/ThemedView.tsx +0 -14
  159. package/example/components/__tests__/ThemedText-test.tsx +0 -10
  160. package/example/components/__tests__/__snapshots__/ThemedText-test.tsx.snap +0 -24
  161. package/example/components/ui/IconSymbol.ios.tsx +0 -32
  162. package/example/components/ui/IconSymbol.tsx +0 -43
  163. package/example/components/ui/TabBarBackground.ios.tsx +0 -22
  164. package/example/components/ui/TabBarBackground.tsx +0 -6
  165. package/example/constants/Colors.ts +0 -26
  166. package/example/constants/constants.ts +0 -5
  167. package/example/constants/useScrollTest.ts +0 -19
  168. package/example/hooks/useColorScheme.ts +0 -1
  169. package/example/hooks/useColorScheme.web.ts +0 -8
  170. package/example/hooks/useThemeColor.ts +0 -22
  171. package/example/ios/.xcode.env +0 -11
  172. package/example/ios/Podfile +0 -64
  173. package/example/ios/Podfile.lock +0 -2767
  174. package/example/ios/Podfile.properties.json +0 -5
  175. package/example/ios/listtest/AppDelegate.swift +0 -70
  176. package/example/ios/listtest/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png +0 -0
  177. package/example/ios/listtest/Images.xcassets/AppIcon.appiconset/Contents.json +0 -14
  178. package/example/ios/listtest/Images.xcassets/Contents.json +0 -6
  179. package/example/ios/listtest/Images.xcassets/SplashScreenBackground.colorset/Contents.json +0 -20
  180. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/Contents.json +0 -23
  181. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image.png +0 -0
  182. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image@2x.png +0 -0
  183. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image@3x.png +0 -0
  184. package/example/ios/listtest/Info.plist +0 -85
  185. package/example/ios/listtest/PrivacyInfo.xcprivacy +0 -48
  186. package/example/ios/listtest/SplashScreen.storyboard +0 -42
  187. package/example/ios/listtest/Supporting/Expo.plist +0 -12
  188. package/example/ios/listtest/listtest-Bridging-Header.h +0 -3
  189. package/example/ios/listtest/listtest.entitlements +0 -5
  190. package/example/ios/listtest.xcodeproj/project.pbxproj +0 -547
  191. package/example/ios/listtest.xcodeproj/xcshareddata/xcschemes/listtest.xcscheme +0 -88
  192. package/example/ios/listtest.xcworkspace/contents.xcworkspacedata +0 -10
  193. package/example/metro.config.js +0 -16
  194. package/example/package.json +0 -73
  195. package/example/scripts/reset-project.js +0 -84
  196. package/example/tsconfig.json +0 -26
  197. package/posttsup.ts +0 -24
  198. package/src/Container.tsx +0 -176
  199. package/src/Containers.tsx +0 -85
  200. package/src/ContextContainer.ts +0 -145
  201. package/src/DebugView.tsx +0 -83
  202. package/src/LazyLegendList.tsx +0 -41
  203. package/src/LeanView.tsx +0 -18
  204. package/src/LegendList.tsx +0 -558
  205. package/src/ListComponent.tsx +0 -191
  206. package/src/ScrollAdjust.tsx +0 -24
  207. package/src/ScrollAdjustHandler.ts +0 -26
  208. package/src/Separator.tsx +0 -14
  209. package/src/animated.tsx +0 -6
  210. package/src/calculateItemsInView.ts +0 -363
  211. package/src/calculateOffsetForIndex.ts +0 -23
  212. package/src/calculateOffsetWithOffsetPosition.ts +0 -26
  213. package/src/checkAllSizesKnown.ts +0 -17
  214. package/src/checkAtBottom.ts +0 -36
  215. package/src/checkAtTop.ts +0 -27
  216. package/src/checkThreshold.ts +0 -30
  217. package/src/constants.ts +0 -11
  218. package/src/createColumnWrapperStyle.ts +0 -16
  219. package/src/doInitialAllocateContainers.ts +0 -40
  220. package/src/doMaintainScrollAtEnd.ts +0 -34
  221. package/src/findAvailableContainers.ts +0 -98
  222. package/src/finishScrollTo.ts +0 -8
  223. package/src/getId.ts +0 -21
  224. package/src/getItemSize.ts +0 -52
  225. package/src/getRenderedItem.ts +0 -34
  226. package/src/getScrollVelocity.ts +0 -47
  227. package/src/handleLayout.ts +0 -70
  228. package/src/helpers.ts +0 -39
  229. package/src/index.ts +0 -11
  230. package/src/keyboard-controller.tsx +0 -63
  231. package/src/onScroll.ts +0 -66
  232. package/src/prepareMVCP.ts +0 -50
  233. package/src/reanimated.tsx +0 -63
  234. package/src/requestAdjust.ts +0 -41
  235. package/src/scrollTo.ts +0 -40
  236. package/src/scrollToIndex.ts +0 -34
  237. package/src/setDidLayout.ts +0 -25
  238. package/src/setPaddingTop.ts +0 -28
  239. package/src/state.tsx +0 -304
  240. package/src/types.ts +0 -610
  241. package/src/updateAlignItemsPaddingTop.ts +0 -18
  242. package/src/updateAllPositions.ts +0 -130
  243. package/src/updateItemSize.ts +0 -203
  244. package/src/updateTotalSize.ts +0 -44
  245. package/src/useAnimatedValue.ts +0 -6
  246. package/src/useCombinedRef.ts +0 -22
  247. package/src/useInit.ts +0 -17
  248. package/src/useSyncLayout.tsx +0 -68
  249. package/src/useValue$.ts +0 -53
  250. package/src/viewability.ts +0 -279
  251. package/tsconfig.json +0 -59
  252. package/tsup.config.ts +0 -21
  253. /package/{dist/animated.js → animated.js} +0 -0
  254. /package/{dist/animated.mjs → animated.mjs} +0 -0
  255. /package/{dist/keyboard-controller.js → keyboard-controller.js} +0 -0
  256. /package/{dist/keyboard-controller.mjs → keyboard-controller.mjs} +0 -0
  257. /package/{dist/reanimated.d.mts → reanimated.d.mts} +0 -0
  258. /package/{dist/reanimated.d.ts → reanimated.d.ts} +0 -0
  259. /package/{dist/reanimated.js → reanimated.js} +0 -0
  260. /package/{dist/reanimated.mjs → reanimated.mjs} +0 -0
@@ -1,236 +0,0 @@
1
- import { LegendList } from "@legendapp/list";
2
- import { useHeaderHeight } from "@react-navigation/elements";
3
- import { useEffect, useState } from "react";
4
- import { Dimensions, KeyboardAvoidingView, Platform, StyleSheet, Text, View } from "react-native";
5
- import { SafeAreaView } from "react-native-safe-area-context";
6
-
7
- type Message = {
8
- id: string;
9
- text: string;
10
- sender: "user" | "system";
11
- timeStamp: number;
12
- isPlaceholder?: boolean;
13
- };
14
-
15
- let idCounter = 0;
16
-
17
- const AIChat = () => {
18
- const [messages, setMessages] = useState<Message[]>([]);
19
- const headerHeight = Platform.OS === "ios" ? useHeaderHeight() : 80;
20
- const screenHeight = Dimensions.get("window").height;
21
- const availableHeight = screenHeight - headerHeight; // Subtract header and some padding
22
-
23
- useEffect(() => {
24
- // After 1 second, add user message and system placeholder
25
- const timer1 = setTimeout(() => {
26
- setMessages([
27
- {
28
- id: String(idCounter++),
29
- text: "Hey, can you help me understand how React Native virtualization works?",
30
- sender: "user",
31
- timeStamp: Date.now(),
32
- },
33
- {
34
- id: String(idCounter++),
35
- text: "",
36
- sender: "system",
37
- timeStamp: Date.now(),
38
- isPlaceholder: true,
39
- },
40
- ]);
41
- }, 1000);
42
-
43
- // After 3 seconds total (2 seconds after the first), replace placeholder with long message
44
- const timer2 = setTimeout(() => {
45
- setMessages((prevMessages) =>
46
- prevMessages.map((msg) =>
47
- msg.isPlaceholder
48
- ? {
49
- id: String(idCounter++),
50
- sender: "system",
51
- timeStamp: Date.now(),
52
- text: `React Native virtualization is a performance optimization technique that's crucial for handling large lists efficiently. Here's how it works:
53
-
54
- 1. **Rendering Only Visible Items**: Instead of rendering all items in a list at once, virtualization only renders the items that are currently visible on screen, plus a small buffer of items just outside the visible area.
55
-
56
- 2. **Dynamic Item Creation/Destruction**: As you scroll, items that move out of view are removed from the DOM/native view hierarchy, and new items that come into view are created. This keeps memory usage constant regardless of list size.
57
-
58
- 3. **View Recycling**: Advanced virtualization systems reuse view components rather than creating new ones, which reduces garbage collection and improves performance.
59
-
60
- 4. **Estimated vs Actual Sizing**: The system uses estimated item sizes to calculate scroll positions and total content size, then adjusts as actual sizes are measured.
61
-
62
- 5. **Legend List Implementation**: Legend List enhances this by providing better handling of dynamic item sizes, bidirectional scrolling, and maintains scroll position more accurately than FlatList.
63
-
64
- The key benefits are:
65
- - Constant memory usage regardless of data size
66
- - Smooth scrolling performance
67
- - Better handling of dynamic content
68
- - Reduced time to interactive
69
-
70
- This makes it possible to scroll through thousands of items without performance degradation, which is essential for modern mobile apps dealing with large datasets like social media feeds, chat histories, or product catalogs.`,
71
- isPlaceholder: false,
72
- }
73
- : msg,
74
- ),
75
- );
76
- }, 3000);
77
-
78
- return () => {
79
- clearTimeout(timer1);
80
- clearTimeout(timer2);
81
- };
82
- }, []);
83
-
84
- return (
85
- <SafeAreaView style={styles.container} edges={["bottom"]}>
86
- <KeyboardAvoidingView
87
- style={styles.container}
88
- behavior="padding"
89
- keyboardVerticalOffset={headerHeight}
90
- contentContainerStyle={{ flex: 1 }}
91
- >
92
- <LegendList
93
- data={messages}
94
- contentContainerStyle={styles.contentContainer}
95
- keyExtractor={(item) => item.id}
96
- estimatedItemSize={60}
97
- maintainVisibleContentPosition
98
- maintainScrollAtEnd
99
- alignItemsAtEnd
100
- renderItem={({ item }) => (
101
- <>
102
- {item.isPlaceholder ? (
103
- <View
104
- style={[
105
- styles.systemMessageContainer,
106
- styles.systemStyle,
107
- { minHeight: availableHeight * 0.9 }, // Take up most of available space
108
- ]}
109
- >
110
- <View style={[styles.placeholderContainer, styles.messageContainer]}>
111
- <View style={styles.typingIndicator}>
112
- <View style={[styles.dot, styles.dot1]} />
113
- <View style={[styles.dot, styles.dot2]} />
114
- <View style={[styles.dot, styles.dot3]} />
115
- </View>
116
- <Text style={styles.placeholderText}>AI is thinking...</Text>
117
- </View>
118
- </View>
119
- ) : (
120
- <View
121
- style={[
122
- styles.messageContainer,
123
- item.sender === "system"
124
- ? styles.systemMessageContainer
125
- : styles.userMessageContainer,
126
- item.sender === "system" ? styles.systemStyle : styles.userStyle,
127
- ]}
128
- >
129
- <Text
130
- style={[styles.messageText, item.sender === "user" && styles.userMessageText]}
131
- >
132
- {item.text}
133
- </Text>
134
- <View
135
- style={[
136
- styles.timeStamp,
137
- item.sender === "system" ? styles.systemStyle : styles.userStyle,
138
- ]}
139
- >
140
- <Text style={styles.timeStampText}>
141
- {new Date(item.timeStamp).toLocaleTimeString()}
142
- </Text>
143
- </View>
144
- </View>
145
- )}
146
- </>
147
- )}
148
- />
149
- </KeyboardAvoidingView>
150
- </SafeAreaView>
151
- );
152
- };
153
-
154
- const styles = StyleSheet.create({
155
- container: {
156
- flex: 1,
157
- backgroundColor: "#fff",
158
- },
159
- contentContainer: {
160
- paddingHorizontal: 16,
161
- },
162
- messageContainer: {
163
- padding: 16,
164
- borderRadius: 16,
165
- marginVertical: 4,
166
- },
167
- messageText: {
168
- fontSize: 16,
169
- lineHeight: 22,
170
- },
171
- userMessageText: {
172
- color: "white",
173
- },
174
- systemMessageContainer: {},
175
- userMessageContainer: {
176
- backgroundColor: "#007AFF",
177
- },
178
- systemStyle: {
179
- maxWidth: "85%",
180
- alignSelf: "flex-start",
181
- },
182
- userStyle: {
183
- maxWidth: "75%",
184
- alignSelf: "flex-end",
185
- alignItems: "flex-end",
186
- },
187
- timeStamp: {
188
- marginVertical: 5,
189
- },
190
- timeStampText: {
191
- fontSize: 12,
192
- color: "#888",
193
- },
194
- placeholderContainer: {
195
- backgroundColor: "#f8f9fa",
196
- borderWidth: 1,
197
- borderColor: "#e9ecef",
198
- },
199
- typingIndicator: {
200
- flexDirection: "row",
201
- alignItems: "center",
202
- marginBottom: 12,
203
- },
204
- dot: {
205
- width: 8,
206
- height: 8,
207
- borderRadius: 4,
208
- backgroundColor: "#007AFF",
209
- marginHorizontal: 2,
210
- },
211
- dot1: {
212
- animationName: "typing",
213
- animationDuration: "1.4s",
214
- animationIterationCount: "infinite",
215
- animationDelay: "0s",
216
- },
217
- dot2: {
218
- animationName: "typing",
219
- animationDuration: "1.4s",
220
- animationIterationCount: "infinite",
221
- animationDelay: "0.2s",
222
- },
223
- dot3: {
224
- animationName: "typing",
225
- animationDuration: "1.4s",
226
- animationIterationCount: "infinite",
227
- animationDelay: "0.4s",
228
- },
229
- placeholderText: {
230
- fontSize: 14,
231
- color: "#666",
232
- fontStyle: "italic",
233
- },
234
- });
235
-
236
- export default AIChat;
@@ -1,133 +0,0 @@
1
- import { type Item, renderItem } from "@/app/cards-renderItem";
2
- import { DRAW_DISTANCE, ESTIMATED_ITEM_LENGTH } from "@/constants/constants";
3
- import { LegendList, type LegendListRef } from "@legendapp/list";
4
- import { useRef, useState } from "react";
5
- import { RefreshControl, StyleSheet, View } from "react-native";
6
- import { useSafeAreaInsets } from "react-native-safe-area-context";
7
-
8
- let last = performance.now();
9
-
10
- export default function BidirectionalInfiniteList() {
11
- const listRef = useRef<LegendListRef>(null);
12
-
13
- const [data, setData] = useState<Item[]>(
14
- () =>
15
- Array.from({ length: 20 }, (_, i) => ({
16
- id: i.toString(),
17
- })) as any[],
18
- );
19
-
20
- const [refreshing, setRefreshing] = useState(false);
21
-
22
- const onRefresh = () => {
23
- console.log("onRefresh");
24
- setRefreshing(true);
25
- setTimeout(() => {
26
- setData((prevData) => {
27
- const initialIndex = Number.parseInt(prevData[0].id);
28
- const newData = [
29
- ...Array.from({ length: 5 }, (_, i) => ({
30
- id: (initialIndex - i - 1).toString(),
31
- })).reverse(),
32
- ...prevData,
33
- ];
34
- return newData;
35
- });
36
- setRefreshing(false);
37
- }, 500);
38
- };
39
-
40
- // useEffect(() => {
41
- // setTimeout(() => {
42
- // setData((prevData) => {
43
- // const initialIndex = Number.parseInt(prevData[0].id);
44
- // const newData = [
45
- // ...Array.from({ length: 1 }, (_, i) => ({
46
- // id: (initialIndex - i - 1).toString(),
47
- // })).reverse(),
48
- // ...prevData,
49
- // ];
50
- // return newData;
51
- // });
52
- // }, 2000);
53
- // }, []);
54
-
55
- const { bottom } = useSafeAreaInsets();
56
-
57
- return (
58
- <View style={[StyleSheet.absoluteFill, styles.outerContainer]} key="legendlist">
59
- <LegendList
60
- refreshControl={
61
- <RefreshControl
62
- refreshing={refreshing}
63
- //onRefresh={onRefresh}
64
- tintColor={"#ffffff"}
65
- progressViewOffset={40}
66
- />
67
- }
68
- ref={listRef}
69
- initialScrollIndex={10}
70
- style={[StyleSheet.absoluteFill, styles.scrollContainer]}
71
- contentContainerStyle={styles.listContainer}
72
- data={data}
73
- renderItem={renderItem}
74
- keyExtractor={(item) => `id${item.id}`}
75
- estimatedItemSize={ESTIMATED_ITEM_LENGTH}
76
- drawDistance={DRAW_DISTANCE}
77
- maintainVisibleContentPosition
78
- recycleItems={true}
79
- ListFooterComponent={<View style={{ height: bottom }} />}
80
- onStartReached={(props) => {
81
- const time = performance.now();
82
- console.log("onStartReached", props, last - time);
83
- last = time;
84
- onRefresh();
85
- }}
86
- onEndReached={({ distanceFromEnd }) => {
87
- console.log("onEndReached", distanceFromEnd);
88
- if (distanceFromEnd > 0) {
89
- setTimeout(() => {
90
- setData((prevData) => {
91
- const newData = [
92
- ...prevData,
93
- ...Array.from({ length: 10 }, (_, i) => ({
94
- id: (Number.parseInt(prevData[prevData.length - 1].id) + i + 1).toString(),
95
- })),
96
- ];
97
- return newData;
98
- });
99
- }, 500);
100
- }
101
- }}
102
- />
103
- </View>
104
- );
105
- }
106
-
107
- const styles = StyleSheet.create({
108
- listHeader: {
109
- alignSelf: "center",
110
- height: 100,
111
- width: 100,
112
- backgroundColor: "#456AAA",
113
- borderRadius: 12,
114
- marginHorizontal: 8,
115
- marginVertical: 8,
116
- },
117
- listEmpty: {
118
- flex: 1,
119
- justifyContent: "center",
120
- alignItems: "center",
121
- backgroundColor: "#6789AB",
122
- paddingVertical: 16,
123
- },
124
- outerContainer: {
125
- backgroundColor: "#456",
126
- },
127
- scrollContainer: {},
128
- listContainer: {
129
- width: 360,
130
- maxWidth: "100%",
131
- marginHorizontal: "auto",
132
- },
133
- });
@@ -1,37 +0,0 @@
1
- import Cards from "@/app/(tabs)/cards";
2
- import { LogBox, Platform, StyleSheet } from "react-native";
3
-
4
- LogBox.ignoreLogs(["Open debugger"]);
5
-
6
- export default function CardsColumns() {
7
- return <Cards numColumns={2} />;
8
- }
9
-
10
- const styles = StyleSheet.create({
11
- listHeader: {
12
- alignSelf: "center",
13
- height: 100,
14
- width: 100,
15
- backgroundColor: "#456AAA",
16
- borderRadius: 12,
17
- marginHorizontal: 8,
18
- marginVertical: 8,
19
- },
20
- listEmpty: {
21
- flex: 1,
22
- justifyContent: "center",
23
- alignItems: "center",
24
- backgroundColor: "#6789AB",
25
- paddingVertical: 16,
26
- },
27
- outerContainer: {
28
- backgroundColor: "#456",
29
- bottom: Platform.OS === "ios" ? 82 : 0,
30
- },
31
- scrollContainer: {},
32
- listContainer: {
33
- width: 400,
34
- maxWidth: "100%",
35
- marginHorizontal: "auto",
36
- },
37
- });
@@ -1,122 +0,0 @@
1
- import renderItem from "@/app/cards-renderItem";
2
- import { DO_SCROLL_TEST, DRAW_DISTANCE, ESTIMATED_ITEM_LENGTH, RECYCLE_ITEMS } from "@/constants/constants";
3
- import { useScrollTest } from "@/constants/useScrollTest";
4
- import { FlashList, type ListRenderItemInfo } from "@shopify/flash-list";
5
- import { Fragment, useRef } from "react";
6
- import { StyleSheet, View } from "react-native";
7
-
8
- export default function HomeScreen() {
9
- const data = Array.from({ length: 1000 }, (_, i) => ({ id: i.toString() }));
10
-
11
- const scrollRef = useRef<FlashList<any>>(null);
12
-
13
- // useEffect(() => {
14
- // let amtPerInterval = 4;
15
- // let index = amtPerInterval;
16
- // const interval = setInterval(() => {
17
- // scrollRef.current?.scrollToIndex({
18
- // index,
19
- // });
20
- // index += amtPerInterval;
21
- // }, 100);
22
-
23
- // return () => clearInterval(interval);
24
- // });
25
-
26
- const renderItemFn = (info: ListRenderItemInfo<any>) => {
27
- return RECYCLE_ITEMS ? renderItem(info) : <Fragment key={info.item.id}>{renderItem(info)}</Fragment>;
28
- };
29
-
30
- if (DO_SCROLL_TEST) {
31
- useScrollTest((offset) => {
32
- scrollRef.current?.scrollToOffset({
33
- offset,
34
- animated: true,
35
- });
36
- });
37
- }
38
-
39
- return (
40
- <View style={[StyleSheet.absoluteFill, styles.outerContainer]} key="flashlist">
41
- <FlashList
42
- data={data}
43
- renderItem={renderItemFn}
44
- keyExtractor={(item) => item.id}
45
- contentContainerStyle={styles.listContainer}
46
- estimatedItemSize={ESTIMATED_ITEM_LENGTH}
47
- drawDistance={DRAW_DISTANCE}
48
- ref={scrollRef}
49
- ListHeaderComponent={<View />}
50
- ListHeaderComponentStyle={styles.listHeader}
51
- />
52
- </View>
53
- );
54
- }
55
-
56
- const styles = StyleSheet.create({
57
- listHeader: {
58
- alignSelf: "center",
59
- height: 100,
60
- width: 100,
61
- backgroundColor: "#456AAA",
62
- borderRadius: 12,
63
- marginHorizontal: 8,
64
- marginTop: 8,
65
- },
66
- outerContainer: {
67
- backgroundColor: "#456",
68
- },
69
- scrollContainer: {
70
- // paddingHorizontal: 8,
71
- },
72
- titleContainer: {
73
- flexDirection: "row",
74
- alignItems: "center",
75
- gap: 8,
76
- },
77
- stepContainer: {
78
- gap: 8,
79
- marginBottom: 8,
80
- },
81
- reactLogo: {
82
- height: 178,
83
- width: 290,
84
- bottom: 0,
85
- left: 0,
86
- position: "absolute",
87
- },
88
- itemContainer: {
89
- // padding: 4,
90
- // borderBottomWidth: 1,
91
- // borderBottomColor: "#ccc",
92
- },
93
- listContainer: {
94
- //paddingHorizontal: 16,
95
- //paddingTop: 48,
96
- },
97
- itemTitle: {
98
- fontSize: 18,
99
- fontWeight: "bold",
100
- marginBottom: 8,
101
- color: "#1a1a1a",
102
- },
103
- itemBody: {
104
- fontSize: 14,
105
- color: "#666666",
106
- lineHeight: 20,
107
- flex: 1,
108
- },
109
- itemFooter: {
110
- flexDirection: "row",
111
- justifyContent: "flex-start",
112
- gap: 16,
113
- marginTop: 12,
114
- paddingTop: 12,
115
- borderTopWidth: 1,
116
- borderTopColor: "#f0f0f0",
117
- },
118
- footerText: {
119
- fontSize: 14,
120
- color: "#888888",
121
- },
122
- });
@@ -1,94 +0,0 @@
1
- import renderItem from "@/app/cards-renderItem";
2
- import { FlatList, StyleSheet, View } from "react-native";
3
-
4
- export default function CardsFlatList() {
5
- const data = Array.from({ length: 1000 }, (_, i) => ({ id: i.toString() }));
6
-
7
- return (
8
- <View style={[StyleSheet.absoluteFill, styles.outerContainer]} key="flatlist">
9
- <FlatList
10
- style={[StyleSheet.absoluteFill, styles.scrollContainer]}
11
- data={data}
12
- renderItem={renderItem as any}
13
- keyExtractor={(item) => item.id}
14
- contentContainerStyle={styles.listContainer}
15
- ListHeaderComponent={<View />}
16
- ListHeaderComponentStyle={styles.listHeader}
17
- // Performance optimizations
18
- windowSize={3} // Reduced window size for better performance
19
- maxToRenderPerBatch={5} // Reduced batch size for smoother scrolling
20
- initialNumToRender={8} // Initial render amount
21
- removeClippedSubviews={true} // Detach views outside of the viewport
22
- updateCellsBatchingPeriod={50} // Batching period for updates
23
- />
24
- </View>
25
- );
26
- }
27
-
28
- const styles = StyleSheet.create({
29
- listHeader: {
30
- alignSelf: "center",
31
- height: 100,
32
- width: 100,
33
- backgroundColor: "#456AAA",
34
- borderRadius: 12,
35
- marginHorizontal: 8,
36
- marginTop: 8,
37
- },
38
- outerContainer: {
39
- backgroundColor: "#456",
40
- },
41
- scrollContainer: {
42
- // paddingHorizontal: 16,
43
- },
44
- titleContainer: {
45
- flexDirection: "row",
46
- alignItems: "center",
47
- gap: 8,
48
- },
49
- stepContainer: {
50
- gap: 8,
51
- marginBottom: 8,
52
- },
53
- reactLogo: {
54
- height: 178,
55
- width: 290,
56
- bottom: 0,
57
- left: 0,
58
- position: "absolute",
59
- },
60
- itemContainer: {
61
- // padding: 4,
62
- // borderBottomWidth: 1,
63
- // borderBottomColor: "#ccc",
64
- },
65
- listContainer: {
66
- paddingHorizontal: 16,
67
- // paddingTop: 48,
68
- },
69
- itemTitle: {
70
- fontSize: 18,
71
- fontWeight: "bold",
72
- marginBottom: 8,
73
- color: "#1a1a1a",
74
- },
75
- itemBody: {
76
- fontSize: 14,
77
- color: "#666666",
78
- lineHeight: 20,
79
- flex: 1,
80
- },
81
- itemFooter: {
82
- flexDirection: "row",
83
- justifyContent: "flex-start",
84
- gap: 16,
85
- marginTop: 12,
86
- paddingTop: 12,
87
- borderTopWidth: 1,
88
- borderTopColor: "#f0f0f0",
89
- },
90
- footerText: {
91
- fontSize: 14,
92
- color: "#888888",
93
- },
94
- });