@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,73 +0,0 @@
1
- {
2
- "name": "list-test",
3
- "license": "MIT",
4
- "main": "expo-router/entry",
5
- "version": "1.0.0",
6
- "scripts": {
7
- "start": "expo start",
8
- "android": "expo run:android",
9
- "android:release": "RELEASE=TRUE expo run:android --variant release",
10
- "android-o": "OLD_ARCH=TRUE expo run:android",
11
- "android-o:release": "RELEASE=TRUE OLD_ARCH=TRUE expo run:android --variant release",
12
- "ios": "expo run:ios",
13
- "ios-o": "OLD_ARCH=TRUE expo run:ios",
14
- "web": "expo start --web",
15
- "test": "jest --watchAll",
16
- "lint": "expo lint",
17
- "prebuild:clean": "rm -rf ios android && npx expo prebuild --clean && npx expo prebuild",
18
- "prebuild-o:clean": "rm -rf ios android && OLD_ARCH=TRUE npx expo prebuild --clean && OLD_ARCH=TRUE npx expo prebuild"
19
- },
20
- "jest": {
21
- "preset": "jest-expo"
22
- },
23
- "dependencies": {
24
- "@expo/vector-icons": "^14.1.0",
25
- "@legendapp/motion": "^2.4.0",
26
- "@legendapp/state": "^3.0.0-beta.19",
27
- "@react-navigation/bottom-tabs": "^7.3.10",
28
- "@react-navigation/native": "^7.1.6",
29
- "@shopify/flash-list": "1.7.6",
30
- "babel-plugin-react-compiler": "^19.1.0-rc.2",
31
- "countries-list": "^3.1.1",
32
- "expo": "^53.0.11",
33
- "expo-atlas": "^0.4.0",
34
- "expo-blur": "~14.1.5",
35
- "expo-constants": "~17.1.6",
36
- "expo-dev-client": "~5.2.0",
37
- "expo-font": "~13.3.1",
38
- "expo-haptics": "~14.1.4",
39
- "expo-linear-gradient": "~14.1.5",
40
- "expo-linking": "~7.1.5",
41
- "expo-router": "~5.1.0",
42
- "expo-splash-screen": "~0.30.9",
43
- "expo-status-bar": "~2.2.3",
44
- "expo-symbols": "~0.4.5",
45
- "expo-system-ui": "~5.0.8",
46
- "expo-web-browser": "~14.1.6",
47
- "react": "19.0.0",
48
- "react-compiler-runtime": "^19.1.0-rc.2",
49
- "react-dom": "19.0.0",
50
- "react-native": "0.79.3",
51
- "react-native-gesture-handler": "~2.24.0",
52
- "react-native-keyboard-controller": "^1.17.4",
53
- "react-native-reanimated": "~3.17.4",
54
- "react-native-redash": "^18.1.3",
55
- "react-native-safe-area-context": "5.4.0",
56
- "react-native-screens": "~4.11.1",
57
- "react-native-web": "^0.20.0",
58
- "react-native-webview": "13.13.5"
59
- },
60
- "devDependencies": {
61
- "@babel/core": "^7.27.4",
62
- "@react-native-community/cli": "latest",
63
- "@types/expo__vector-icons": "^10.0.2",
64
- "@types/jest": "^29.5.14",
65
- "@types/react": "~19.0.10",
66
- "@types/react-test-renderer": "^19.0.0",
67
- "jest": "~29.7.0",
68
- "jest-expo": "~53.0.7",
69
- "react-test-renderer": "19.0.0",
70
- "typescript": "~5.8.3"
71
- },
72
- "private": true
73
- }
@@ -1,84 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * This script is used to reset the project to a blank state.
5
- * It moves the /app, /components, /hooks, /scripts, and /constants directories to /app-example and creates a new /app directory with an index.tsx and _layout.tsx file.
6
- * You can remove the `reset-project` script from package.json and safely delete this file after running it.
7
- */
8
-
9
- const fs = require("fs");
10
- const path = require("path");
11
-
12
- const root = process.cwd();
13
- const oldDirs = ["app", "components", "hooks", "constants", "scripts"];
14
- const newDir = "app-example";
15
- const newAppDir = "app";
16
- const newDirPath = path.join(root, newDir);
17
-
18
- const indexContent = `import { Text, View } from "react-native";
19
-
20
- export default function Index() {
21
- return (
22
- <View
23
- style={{
24
- flex: 1,
25
- justifyContent: "center",
26
- alignItems: "center",
27
- }}
28
- >
29
- <Text>Edit app/index.tsx to edit this screen.</Text>
30
- </View>
31
- );
32
- }
33
- `;
34
-
35
- const layoutContent = `import { Stack } from "expo-router";
36
-
37
- export default function RootLayout() {
38
- return <Stack />;
39
- }
40
- `;
41
-
42
- const moveDirectories = async () => {
43
- try {
44
- // Create the app-example directory
45
- await fs.promises.mkdir(newDirPath, { recursive: true });
46
- console.log(`📁 /${newDir} directory created.`);
47
-
48
- // Move old directories to new app-example directory
49
- for (const dir of oldDirs) {
50
- const oldDirPath = path.join(root, dir);
51
- const newDirPath = path.join(root, newDir, dir);
52
- if (fs.existsSync(oldDirPath)) {
53
- await fs.promises.rename(oldDirPath, newDirPath);
54
- console.log(`➡️ /${dir} moved to /${newDir}/${dir}.`);
55
- } else {
56
- console.log(`➡️ /${dir} does not exist, skipping.`);
57
- }
58
- }
59
-
60
- // Create new /app directory
61
- const newAppDirPath = path.join(root, newAppDir);
62
- await fs.promises.mkdir(newAppDirPath, { recursive: true });
63
- console.log("\n📁 New /app directory created.");
64
-
65
- // Create index.tsx
66
- const indexPath = path.join(newAppDirPath, "index.tsx");
67
- await fs.promises.writeFile(indexPath, indexContent);
68
- console.log("📄 app/index.tsx created.");
69
-
70
- // Create _layout.tsx
71
- const layoutPath = path.join(newAppDirPath, "_layout.tsx");
72
- await fs.promises.writeFile(layoutPath, layoutContent);
73
- console.log("📄 app/_layout.tsx created.");
74
-
75
- console.log("\n✅ Project reset complete. Next steps:");
76
- console.log(
77
- "1. Run `npx expo start` to start a development server.\n2. Edit app/index.tsx to edit the main screen.\n3. Delete the /app-example directory when you're done referencing it."
78
- );
79
- } catch (error) {
80
- console.error(`Error during script execution: ${error}`);
81
- }
82
- };
83
-
84
- moveDirectories();
@@ -1,26 +0,0 @@
1
- {
2
- "extends": "expo/tsconfig.base",
3
- "compilerOptions": {
4
- "strict": true,
5
- "paths": {
6
- "@/*": [
7
- "./*"
8
- ],
9
- "@legendapp/list": [
10
- "../src/index"
11
- ],
12
- "@legendapp/list/keyboard-controller": [
13
- "../src/keyboard-controller"
14
- ],
15
- "@legendapp/list/reanimated": [
16
- "../src/reanimated"
17
- ]
18
- }
19
- },
20
- "include": [
21
- "**/*.ts",
22
- "**/*.tsx",
23
- ".expo/types/**/*.ts",
24
- "expo-env.d.ts"
25
- ],
26
- }
package/posttsup.ts DELETED
@@ -1,24 +0,0 @@
1
- import pkg from './package.json';
2
-
3
- async function copy(...files: string[]) {
4
- return files.map((file) => Bun.write('dist/' + file.replace('src/', ''), Bun.file(file), { createPath: true }));
5
- }
6
-
7
- copy('LICENSE', 'CHANGELOG.md', 'README.md');
8
-
9
- const exports: Record<string, string | { import?: string; require?: string; types: string }> = {
10
- './package.json': './package.json',
11
- };
12
-
13
- const pkgOut = pkg as Record<string, any>;
14
-
15
- pkg.private = false;
16
- pkgOut.exports = exports;
17
- delete pkgOut.devDependencies;
18
- delete pkgOut.overrides;
19
- delete pkgOut.scripts;
20
- delete pkgOut.engines;
21
- delete pkgOut.exports;
22
- delete pkgOut.commitlint;
23
-
24
- Bun.write('dist/package.json', JSON.stringify(pkg, undefined, 2));
package/src/Container.tsx DELETED
@@ -1,176 +0,0 @@
1
- // biome-ignore lint/style/useImportType: Leaving this out makes it crash in some environments
2
- import * as React from "react";
3
- import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
4
- import type { DimensionValue, LayoutChangeEvent, StyleProp, View, ViewStyle } from "react-native";
5
- import { ContextContainer, type ContextContainerType } from "./ContextContainer";
6
- import { LeanView } from "./LeanView";
7
- import { Separator } from "./Separator";
8
- import { IsNewArchitecture, POSITION_OUT_OF_VIEW } from "./constants";
9
- import { isNullOrUndefined } from "./helpers";
10
- import { useArr$, useStateContext } from "./state";
11
- import type { GetRenderedItem } from "./types";
12
-
13
- export const Container = <ItemT,>({
14
- id,
15
- recycleItems,
16
- horizontal,
17
- getRenderedItem,
18
- updateItemSize,
19
- ItemSeparatorComponent,
20
- }: {
21
- id: number;
22
- recycleItems?: boolean;
23
- horizontal: boolean;
24
- getRenderedItem: GetRenderedItem;
25
- updateItemSize: (itemKey: string, size: { width: number; height: number }) => void;
26
- ItemSeparatorComponent?: React.ComponentType<{ leadingItem: ItemT }>;
27
- }) => {
28
- const ctx = useStateContext();
29
- const columnWrapperStyle = ctx.columnWrapperStyle;
30
-
31
- const [column = 0, data, itemKey, position = POSITION_OUT_OF_VIEW, numColumns, extraData] = useArr$([
32
- `containerColumn${id}`,
33
- `containerItemData${id}`,
34
- `containerItemKey${id}`,
35
- `containerPosition${id}`,
36
- "numColumns",
37
- "extraData",
38
- ]);
39
-
40
- const refLastSize = useRef<{ width: number; height: number }>();
41
- const ref = useRef<View>(null);
42
- const [layoutRenderCount, forceLayoutRender] = useState(0);
43
-
44
- const otherAxisPos: DimensionValue | undefined = numColumns > 1 ? `${((column - 1) / numColumns) * 100}%` : 0;
45
- const otherAxisSize: DimensionValue | undefined = numColumns > 1 ? `${(1 / numColumns) * 100}%` : undefined;
46
- let didLayout = false;
47
-
48
- let paddingStyles: ViewStyle | undefined;
49
- if (columnWrapperStyle) {
50
- // Extract gap properties from columnWrapperStyle if available
51
- const { columnGap, rowGap, gap } = columnWrapperStyle;
52
-
53
- // Create padding styles for both horizontal and vertical layouts with multiple columns
54
- if (horizontal) {
55
- paddingStyles = {
56
- paddingRight: columnGap || gap || undefined,
57
- paddingVertical: numColumns > 1 ? (rowGap || gap || 0) / 2 : undefined,
58
- };
59
- } else {
60
- paddingStyles = {
61
- paddingBottom: rowGap || gap || undefined,
62
- paddingHorizontal: numColumns > 1 ? (columnGap || gap || 0) / 2 : undefined,
63
- };
64
- }
65
- }
66
-
67
- const style: StyleProp<ViewStyle> = horizontal
68
- ? {
69
- flexDirection: ItemSeparatorComponent ? "row" : undefined,
70
- position: "absolute",
71
- top: otherAxisPos,
72
- height: otherAxisSize,
73
- left: position,
74
- ...(paddingStyles || {}),
75
- }
76
- : {
77
- position: "absolute",
78
- left: otherAxisPos,
79
- right: numColumns > 1 ? null : 0,
80
- width: otherAxisSize,
81
- top: position,
82
- ...(paddingStyles || {}),
83
- };
84
-
85
- const renderedItemInfo = useMemo(
86
- () => (itemKey !== undefined ? getRenderedItem(itemKey) : null),
87
- [itemKey, data, extraData],
88
- );
89
- const { index, renderedItem } = renderedItemInfo || {};
90
-
91
- const triggerLayout = useCallback(() => {
92
- forceLayoutRender((v) => v + 1);
93
- }, []);
94
-
95
- const contextValue = useMemo<ContextContainerType>(() => {
96
- ctx.viewRefs.set(id, ref);
97
- return { containerId: id, itemKey, index: index!, value: data, triggerLayout };
98
- }, [id, itemKey, index, data]);
99
-
100
- const onLayout = (event: LayoutChangeEvent) => {
101
- if (!isNullOrUndefined(itemKey)) {
102
- didLayout = true;
103
- let layout: { width: number; height: number } = event.nativeEvent.layout;
104
- const size = layout[horizontal ? "width" : "height"];
105
-
106
- const doUpdate = () => {
107
- refLastSize.current = { width: layout.width, height: layout.height };
108
- updateItemSize(itemKey, layout);
109
- };
110
-
111
- if (IsNewArchitecture || size > 0) {
112
- doUpdate();
113
- } else {
114
- // On old architecture, the size can be 0 sometimes, maybe when not fully rendered?
115
- // So we need to make sure it's actually rendered and measure it to make sure it's actually 0.
116
- ref.current?.measure?.((x, y, width, height) => {
117
- layout = { width, height };
118
- doUpdate();
119
- });
120
- }
121
- }
122
- };
123
-
124
- if (IsNewArchitecture) {
125
- // New architecture supports unstable_getBoundingClientRect for getting layout synchronously
126
- useLayoutEffect(() => {
127
- if (!isNullOrUndefined(itemKey)) {
128
- // @ts-expect-error unstable_getBoundingClientRect is unstable and only on Fabric
129
- const measured = ref.current?.unstable_getBoundingClientRect?.();
130
- if (measured) {
131
- const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
132
-
133
- if (size) {
134
- updateItemSize(itemKey, measured);
135
- }
136
- }
137
- }
138
- }, [itemKey, layoutRenderCount]);
139
- } else {
140
- // Since old architecture cannot use unstable_getBoundingClientRect it needs to ensure that
141
- // all containers updateItemSize even if the container did not resize.
142
- useEffect(() => {
143
- // Catch a bug where a container is reused and is the exact same size as the previous item
144
- // so it does not fire an onLayout, so we need to trigger it manually.
145
- // TODO: There must be a better way to do this?
146
- if (!isNullOrUndefined(itemKey)) {
147
- const timeout = setTimeout(() => {
148
- if (!didLayout && refLastSize.current) {
149
- updateItemSize(itemKey, refLastSize.current);
150
- }
151
- }, 16);
152
- return () => {
153
- clearTimeout(timeout);
154
- };
155
- }
156
- }, [itemKey]);
157
- }
158
-
159
- // Use a reactive View to ensure the container element itself
160
- // is not rendered when style changes, only the style prop.
161
- // This is a big perf boost to do less work rendering.
162
- return (
163
- <LeanView style={style} onLayout={onLayout} ref={ref} key={recycleItems ? undefined : itemKey}>
164
- <ContextContainer.Provider value={contextValue}>
165
- {renderedItem}
166
- {renderedItemInfo && ItemSeparatorComponent && (
167
- <Separator
168
- itemKey={itemKey}
169
- ItemSeparatorComponent={ItemSeparatorComponent}
170
- leadingItem={renderedItemInfo.item}
171
- />
172
- )}
173
- </ContextContainer.Provider>
174
- </LeanView>
175
- );
176
- };
@@ -1,85 +0,0 @@
1
- // biome-ignore lint/style/useImportType: Leaving this out makes it crash in some environments
2
- import * as React from "react";
3
- import { Animated, type StyleProp, type ViewStyle } from "react-native";
4
- import { Container } from "./Container";
5
- import { IsNewArchitecture } from "./constants";
6
- import { useArr$, useStateContext } from "./state";
7
- import { type GetRenderedItem, typedMemo } from "./types";
8
- import { useValue$ } from "./useValue$";
9
-
10
- interface ContainersProps<ItemT> {
11
- horizontal: boolean;
12
- recycleItems: boolean;
13
- ItemSeparatorComponent?: React.ComponentType<{ leadingItem: ItemT }>;
14
- waitForInitialLayout: boolean | undefined;
15
- updateItemSize: (itemKey: string, size: { width: number; height: number }) => void;
16
- getRenderedItem: GetRenderedItem;
17
- }
18
-
19
- export const Containers = typedMemo(function Containers<ItemT>({
20
- horizontal,
21
- recycleItems,
22
- ItemSeparatorComponent,
23
- waitForInitialLayout,
24
- updateItemSize,
25
- getRenderedItem,
26
- }: ContainersProps<ItemT>) {
27
- const ctx = useStateContext();
28
- const columnWrapperStyle = ctx.columnWrapperStyle;
29
- const [numContainers, numColumns] = useArr$(["numContainersPooled", "numColumns"]);
30
- const animSize = useValue$("totalSize", {
31
- // Use a microtask if increasing the size significantly, otherwise use a timeout
32
- delay: (value, prevValue) => (!prevValue || value - prevValue > 20 ? 0 : 200),
33
- });
34
- const animOpacity =
35
- waitForInitialLayout && !IsNewArchitecture
36
- ? useValue$("containersDidLayout", { getValue: (value) => (value ? 1 : 0) })
37
- : undefined;
38
- const otherAxisSize = useValue$("otherAxisSize", { delay: 0 });
39
-
40
- const containers: React.ReactNode[] = [];
41
- for (let i = 0; i < numContainers; i++) {
42
- containers.push(
43
- <Container
44
- id={i}
45
- key={i}
46
- recycleItems={recycleItems}
47
- horizontal={horizontal}
48
- getRenderedItem={getRenderedItem}
49
- updateItemSize={updateItemSize}
50
- // specifying inline separator makes Containers rerender on each data change
51
- // should we do memo of ItemSeparatorComponent?
52
- ItemSeparatorComponent={ItemSeparatorComponent}
53
- />,
54
- );
55
- }
56
-
57
- const style: StyleProp<ViewStyle> = horizontal
58
- ? { width: animSize, opacity: animOpacity, minHeight: otherAxisSize }
59
- : { height: animSize, opacity: animOpacity, minWidth: otherAxisSize };
60
-
61
- if (columnWrapperStyle && numColumns > 1) {
62
- // Extract gap properties from columnWrapperStyle if available
63
- const { columnGap, rowGap, gap } = columnWrapperStyle;
64
-
65
- const gapX = columnGap || gap || 0;
66
- const gapY = rowGap || gap || 0;
67
- if (horizontal) {
68
- if (gapY) {
69
- style.marginVertical = -gapY / 2;
70
- }
71
- if (gapX) {
72
- style.marginRight = -gapX;
73
- }
74
- } else {
75
- if (gapX) {
76
- style.marginHorizontal = -gapX;
77
- }
78
- if (gapY) {
79
- style.marginBottom = -gapY;
80
- }
81
- }
82
- }
83
-
84
- return <Animated.View style={style}>{containers}</Animated.View>;
85
- });
@@ -1,145 +0,0 @@
1
- import {
2
- type Dispatch,
3
- type SetStateAction,
4
- createContext,
5
- useCallback,
6
- useContext,
7
- useEffect,
8
- useRef,
9
- useState,
10
- } from "react";
11
- import { isFunction } from "./helpers";
12
- import { useArr$, useSelector$, useStateContext } from "./state";
13
- import type { LegendListRecyclingState, ViewabilityAmountCallback, ViewabilityCallback } from "./types";
14
- import { useInit } from "./useInit";
15
-
16
- export interface ContextContainerType {
17
- containerId: number;
18
- itemKey: string;
19
- index: number;
20
- value: any;
21
- triggerLayout: () => void;
22
- }
23
-
24
- export const ContextContainer = createContext<ContextContainerType>(null as any);
25
-
26
- export function useViewability(callback: ViewabilityCallback, configId?: string) {
27
- const ctx = useStateContext();
28
- const { containerId } = useContext(ContextContainer);
29
-
30
- const key = containerId + (configId ?? "");
31
-
32
- useInit(() => {
33
- const value = ctx.mapViewabilityValues.get(key);
34
- if (value) {
35
- callback(value);
36
- }
37
- });
38
-
39
- ctx.mapViewabilityCallbacks.set(key, callback);
40
-
41
- useEffect(
42
- () => () => {
43
- ctx.mapViewabilityCallbacks.delete(key);
44
- },
45
- [],
46
- );
47
- }
48
-
49
- export function useViewabilityAmount(callback: ViewabilityAmountCallback) {
50
- const ctx = useStateContext();
51
- const { containerId } = useContext(ContextContainer);
52
-
53
- useInit(() => {
54
- const value = ctx.mapViewabilityAmountValues.get(containerId);
55
- if (value) {
56
- callback(value);
57
- }
58
- });
59
-
60
- ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
61
-
62
- useEffect(
63
- () => () => {
64
- ctx.mapViewabilityAmountCallbacks.delete(containerId);
65
- },
66
- [],
67
- );
68
- }
69
-
70
- export function useRecyclingEffect(effect: (info: LegendListRecyclingState<unknown>) => void | (() => void)) {
71
- const { index, value } = useContext(ContextContainer);
72
- const prevValues = useRef<{ prevIndex: number | undefined; prevItem: any }>({
73
- prevIndex: undefined,
74
- prevItem: undefined,
75
- });
76
-
77
- useEffect(() => {
78
- let ret: void | (() => void) = undefined;
79
- // Only run effect if there's a previous value
80
- if (prevValues.current.prevIndex !== undefined && prevValues.current.prevItem !== undefined) {
81
- ret = effect({
82
- index,
83
- item: value,
84
- prevIndex: prevValues.current.prevIndex,
85
- prevItem: prevValues.current.prevItem,
86
- });
87
- }
88
-
89
- // Update refs for next render
90
- prevValues.current = {
91
- prevIndex: index,
92
- prevItem: value,
93
- };
94
-
95
- return ret;
96
- }, [index, value]);
97
- }
98
-
99
- export function useRecyclingState<ItemT>(valueOrFun: ((info: LegendListRecyclingState<ItemT>) => ItemT) | ItemT) {
100
- const { index, value, itemKey, triggerLayout } = useContext(ContextContainer);
101
- const refState = useRef<{ itemKey: string | null; value: ItemT | null }>({
102
- itemKey: null,
103
- value: null,
104
- });
105
- const [_, setRenderNum] = useState(0);
106
- const state = refState.current;
107
-
108
- if (state.itemKey !== itemKey) {
109
- state.itemKey = itemKey;
110
- // Reset local state in ref
111
- state.value = isFunction(valueOrFun)
112
- ? valueOrFun({
113
- index,
114
- item: value,
115
- prevIndex: undefined,
116
- prevItem: undefined,
117
- })
118
- : valueOrFun;
119
- }
120
-
121
- const setState: Dispatch<SetStateAction<ItemT>> = useCallback(
122
- (newState: SetStateAction<ItemT>) => {
123
- // Update local state in ref
124
- state.value = isFunction(newState) ? (newState as (prevState: ItemT) => ItemT)(state.value!) : newState;
125
- // Trigger item to re-render
126
- setRenderNum((v) => v + 1);
127
- // Trigger container to re-render to update item size
128
- triggerLayout();
129
- },
130
- [triggerLayout, state],
131
- );
132
-
133
- return [state.value, setState] as const;
134
- }
135
-
136
- export function useIsLastItem(): boolean {
137
- const { itemKey } = useContext(ContextContainer);
138
- const isLast = useSelector$("lastItemKeys", (lastItemKeys) => lastItemKeys?.includes(itemKey) || false);
139
- return isLast;
140
- }
141
-
142
- export function useListScrollSize(): { width: number; height: number } {
143
- const [scrollSize] = useArr$(["scrollSize"]);
144
- return scrollSize;
145
- }