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

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 (262) hide show
  1. package/.claude/settings.local.json +8 -0
  2. package/.cursor/rules/changelog.mdc +60 -0
  3. package/.github/FUNDING.yml +15 -0
  4. package/.gitignore +5 -0
  5. package/.prettierrc.json +5 -0
  6. package/.vscode/settings.json +14 -0
  7. package/CLAUDE.md +126 -0
  8. package/biome.json +46 -0
  9. package/bun.lock +1289 -0
  10. package/bunfig.toml +2 -0
  11. package/dist/CHANGELOG.md +119 -0
  12. package/dist/LICENSE +21 -0
  13. package/dist/README.md +139 -0
  14. package/{animated.d.mts → dist/animated.d.mts} +1 -1
  15. package/{animated.d.ts → dist/animated.d.ts} +1 -1
  16. package/{index.d.mts → dist/index.d.mts} +63 -15
  17. package/{index.d.ts → dist/index.d.ts} +63 -15
  18. package/dist/index.js +2525 -0
  19. package/dist/index.mjs +2497 -0
  20. package/{keyboard-controller.d.mts → dist/keyboard-controller.d.mts} +4 -4
  21. package/{keyboard-controller.d.ts → dist/keyboard-controller.d.ts} +4 -4
  22. package/dist/package.json +35 -0
  23. package/example/README.md +40 -0
  24. package/example/api/data/genres.json +23 -0
  25. package/example/api/data/playlist/10402-10749.json +1 -0
  26. package/example/api/data/playlist/10402-10770.json +1 -0
  27. package/example/api/data/playlist/10402-37.json +1 -0
  28. package/example/api/data/playlist/10749-10752.json +1 -0
  29. package/example/api/data/playlist/10749-10770.json +1 -0
  30. package/example/api/data/playlist/10749-37.json +1 -0
  31. package/example/api/data/playlist/10749-878.json +1 -0
  32. package/example/api/data/playlist/10751-10402.json +1 -0
  33. package/example/api/data/playlist/10751-10752.json +1 -0
  34. package/example/api/data/playlist/10751-37.json +1 -0
  35. package/example/api/data/playlist/10751-53.json +1 -0
  36. package/example/api/data/playlist/10751-878.json +1 -0
  37. package/example/api/data/playlist/10751-9648.json +1 -0
  38. package/example/api/data/playlist/10752-37.json +1 -0
  39. package/example/api/data/playlist/12-10402.json +1 -0
  40. package/example/api/data/playlist/12-10749.json +1 -0
  41. package/example/api/data/playlist/12-18.json +1 -0
  42. package/example/api/data/playlist/12-27.json +1 -0
  43. package/example/api/data/playlist/12-35.json +1 -0
  44. package/example/api/data/playlist/14-36.json +1 -0
  45. package/example/api/data/playlist/14-878.json +1 -0
  46. package/example/api/data/playlist/16-10751.json +1 -0
  47. package/example/api/data/playlist/16-10770.json +1 -0
  48. package/example/api/data/playlist/16-35.json +1 -0
  49. package/example/api/data/playlist/16-36.json +1 -0
  50. package/example/api/data/playlist/16-53.json +1 -0
  51. package/example/api/data/playlist/18-10751.json +1 -0
  52. package/example/api/data/playlist/18-10752.json +1 -0
  53. package/example/api/data/playlist/18-37.json +1 -0
  54. package/example/api/data/playlist/18-53.json +1 -0
  55. package/example/api/data/playlist/18-878.json +1 -0
  56. package/example/api/data/playlist/27-10749.json +1 -0
  57. package/example/api/data/playlist/27-10770.json +1 -0
  58. package/example/api/data/playlist/28-10749.json +1 -0
  59. package/example/api/data/playlist/28-10751.json +1 -0
  60. package/example/api/data/playlist/28-10770.json +1 -0
  61. package/example/api/data/playlist/28-16.json +1 -0
  62. package/example/api/data/playlist/28-18.json +1 -0
  63. package/example/api/data/playlist/28-36.json +1 -0
  64. package/example/api/data/playlist/28-37.json +1 -0
  65. package/example/api/data/playlist/28-53.json +1 -0
  66. package/example/api/data/playlist/28-80.json +1 -0
  67. package/example/api/data/playlist/28-99.json +1 -0
  68. package/example/api/data/playlist/35-10749.json +1 -0
  69. package/example/api/data/playlist/35-10751.json +1 -0
  70. package/example/api/data/playlist/35-10752.json +1 -0
  71. package/example/api/data/playlist/35-27.json +1 -0
  72. package/example/api/data/playlist/35-36.json +1 -0
  73. package/example/api/data/playlist/35-53.json +1 -0
  74. package/example/api/data/playlist/35-80.json +1 -0
  75. package/example/api/data/playlist/36-37.json +1 -0
  76. package/example/api/data/playlist/36-878.json +1 -0
  77. package/example/api/data/playlist/36-9648.json +1 -0
  78. package/example/api/data/playlist/53-10752.json +1 -0
  79. package/example/api/data/playlist/80-10770.json +1 -0
  80. package/example/api/data/playlist/80-14.json +1 -0
  81. package/example/api/data/playlist/80-18.json +1 -0
  82. package/example/api/data/playlist/80-37.json +1 -0
  83. package/example/api/data/playlist/878-37.json +1 -0
  84. package/example/api/data/playlist/9648-10770.json +1 -0
  85. package/example/api/data/playlist/9648-37.json +1 -0
  86. package/example/api/data/playlist/9648-53.json +1 -0
  87. package/example/api/data/playlist/9648-878.json +1 -0
  88. package/example/api/data/playlist/99-10749.json +1 -0
  89. package/example/api/data/playlist/99-14.json +1 -0
  90. package/example/api/data/playlist/99-18.json +1 -0
  91. package/example/api/data/playlist/99-27.json +1 -0
  92. package/example/api/data/playlist/99-53.json +1 -0
  93. package/example/api/data/playlist/99-9648.json +1 -0
  94. package/example/api/data/playlist/index.ts +73 -0
  95. package/example/api/data/rows.json +1 -0
  96. package/example/api/index.ts +36 -0
  97. package/example/app/(tabs)/_layout.tsx +60 -0
  98. package/example/app/(tabs)/cards.tsx +81 -0
  99. package/example/app/(tabs)/index.tsx +205 -0
  100. package/example/app/(tabs)/moviesL.tsx +7 -0
  101. package/example/app/(tabs)/moviesLR.tsx +7 -0
  102. package/example/app/+not-found.tsx +32 -0
  103. package/example/app/_layout.tsx +34 -0
  104. package/example/app/accurate-scrollto/index.tsx +125 -0
  105. package/example/app/accurate-scrollto-2/index.tsx +52 -0
  106. package/example/app/accurate-scrollto-huge/index.tsx +128 -0
  107. package/example/app/add-to-end/index.tsx +82 -0
  108. package/example/app/ai-chat/index.tsx +236 -0
  109. package/example/app/bidirectional-infinite-list/index.tsx +133 -0
  110. package/example/app/cards-columns/index.tsx +37 -0
  111. package/example/app/cards-flashlist/index.tsx +122 -0
  112. package/example/app/cards-flatlist/index.tsx +94 -0
  113. package/example/app/cards-no-recycle/index.tsx +110 -0
  114. package/example/app/cards-renderItem.tsx +354 -0
  115. package/example/app/chat-example/index.tsx +167 -0
  116. package/example/app/chat-infinite/index.tsx +239 -0
  117. package/example/app/chat-keyboard/index.tsx +248 -0
  118. package/example/app/chat-resize-outer/index.tsx +247 -0
  119. package/example/app/columns/index.tsx +78 -0
  120. package/example/app/countries/index.tsx +182 -0
  121. package/example/app/countries-flashlist/index.tsx +163 -0
  122. package/example/app/countries-reorder/index.tsx +187 -0
  123. package/example/app/extra-data/index.tsx +86 -0
  124. package/example/app/filter-elements/filter-data-provider.tsx +55 -0
  125. package/example/app/filter-elements/index.tsx +118 -0
  126. package/example/app/initial-scroll-index/index.tsx +106 -0
  127. package/example/app/initial-scroll-index/renderFixedItem.tsx +215 -0
  128. package/example/app/initial-scroll-index-free-height/index.tsx +70 -0
  129. package/example/app/initial-scroll-index-keyed/index.tsx +62 -0
  130. package/example/app/lazy-list/index.tsx +123 -0
  131. package/example/app/movies-flashlist/index.tsx +7 -0
  132. package/example/app/mutable-cells/index.tsx +104 -0
  133. package/example/app/video-feed/index.tsx +119 -0
  134. package/example/app.config.js +22 -0
  135. package/example/app.json +45 -0
  136. package/example/assets/fonts/SpaceMono-Regular.ttf +0 -0
  137. package/example/assets/images/adaptive-icon.png +0 -0
  138. package/example/assets/images/favicon.png +0 -0
  139. package/example/assets/images/icon.png +0 -0
  140. package/example/assets/images/partial-react-logo.png +0 -0
  141. package/example/assets/images/react-logo.png +0 -0
  142. package/example/assets/images/react-logo@2x.png +0 -0
  143. package/example/assets/images/react-logo@3x.png +0 -0
  144. package/example/assets/images/splash-icon.png +0 -0
  145. package/example/autoscroll.sh +101 -0
  146. package/example/bun.lock +2266 -0
  147. package/example/bunfig.toml +2 -0
  148. package/example/components/Breathe.tsx +54 -0
  149. package/example/components/Circle.tsx +69 -0
  150. package/example/components/Collapsible.tsx +44 -0
  151. package/example/components/ExternalLink.tsx +24 -0
  152. package/example/components/HapticTab.tsx +18 -0
  153. package/example/components/HelloWave.tsx +37 -0
  154. package/example/components/Movies.tsx +179 -0
  155. package/example/components/ParallaxScrollView.tsx +81 -0
  156. package/example/components/ThemedText.tsx +60 -0
  157. package/example/components/ThemedView.tsx +14 -0
  158. package/example/components/__tests__/ThemedText-test.tsx +10 -0
  159. package/example/components/__tests__/__snapshots__/ThemedText-test.tsx.snap +24 -0
  160. package/example/components/ui/IconSymbol.ios.tsx +32 -0
  161. package/example/components/ui/IconSymbol.tsx +43 -0
  162. package/example/components/ui/TabBarBackground.ios.tsx +22 -0
  163. package/example/components/ui/TabBarBackground.tsx +6 -0
  164. package/example/constants/Colors.ts +26 -0
  165. package/example/constants/constants.ts +5 -0
  166. package/example/constants/useScrollTest.ts +19 -0
  167. package/example/hooks/useColorScheme.ts +1 -0
  168. package/example/hooks/useColorScheme.web.ts +8 -0
  169. package/example/hooks/useThemeColor.ts +22 -0
  170. package/example/ios/.xcode.env +11 -0
  171. package/example/ios/Podfile +64 -0
  172. package/example/ios/Podfile.lock +2767 -0
  173. package/example/ios/Podfile.properties.json +5 -0
  174. package/example/ios/listtest/AppDelegate.swift +70 -0
  175. package/example/ios/listtest/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png +0 -0
  176. package/example/ios/listtest/Images.xcassets/AppIcon.appiconset/Contents.json +14 -0
  177. package/example/ios/listtest/Images.xcassets/Contents.json +6 -0
  178. package/example/ios/listtest/Images.xcassets/SplashScreenBackground.colorset/Contents.json +20 -0
  179. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/Contents.json +23 -0
  180. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image.png +0 -0
  181. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image@2x.png +0 -0
  182. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image@3x.png +0 -0
  183. package/example/ios/listtest/Info.plist +85 -0
  184. package/example/ios/listtest/PrivacyInfo.xcprivacy +48 -0
  185. package/example/ios/listtest/SplashScreen.storyboard +42 -0
  186. package/example/ios/listtest/Supporting/Expo.plist +12 -0
  187. package/example/ios/listtest/listtest-Bridging-Header.h +3 -0
  188. package/example/ios/listtest/listtest.entitlements +5 -0
  189. package/example/ios/listtest.xcodeproj/project.pbxproj +547 -0
  190. package/example/ios/listtest.xcodeproj/xcshareddata/xcschemes/listtest.xcscheme +88 -0
  191. package/example/ios/listtest.xcworkspace/contents.xcworkspacedata +10 -0
  192. package/example/metro.config.js +16 -0
  193. package/example/package.json +73 -0
  194. package/example/scripts/reset-project.js +84 -0
  195. package/example/tsconfig.json +26 -0
  196. package/package.json +88 -34
  197. package/posttsup.ts +24 -0
  198. package/src/Container.tsx +176 -0
  199. package/src/Containers.tsx +85 -0
  200. package/src/ContextContainer.ts +145 -0
  201. package/src/DebugView.tsx +83 -0
  202. package/src/LazyLegendList.tsx +41 -0
  203. package/src/LeanView.tsx +18 -0
  204. package/src/LegendList.tsx +558 -0
  205. package/src/ListComponent.tsx +191 -0
  206. package/src/ScrollAdjust.tsx +24 -0
  207. package/src/ScrollAdjustHandler.ts +26 -0
  208. package/src/Separator.tsx +14 -0
  209. package/src/animated.tsx +6 -0
  210. package/src/calculateItemsInView.ts +363 -0
  211. package/src/calculateOffsetForIndex.ts +23 -0
  212. package/src/calculateOffsetWithOffsetPosition.ts +26 -0
  213. package/src/checkAllSizesKnown.ts +17 -0
  214. package/src/checkAtBottom.ts +36 -0
  215. package/src/checkAtTop.ts +27 -0
  216. package/src/checkThreshold.ts +30 -0
  217. package/src/constants.ts +11 -0
  218. package/src/createColumnWrapperStyle.ts +16 -0
  219. package/src/doInitialAllocateContainers.ts +40 -0
  220. package/src/doMaintainScrollAtEnd.ts +34 -0
  221. package/src/findAvailableContainers.ts +98 -0
  222. package/src/finishScrollTo.ts +8 -0
  223. package/src/getId.ts +21 -0
  224. package/src/getItemSize.ts +52 -0
  225. package/src/getRenderedItem.ts +34 -0
  226. package/src/getScrollVelocity.ts +47 -0
  227. package/src/handleLayout.ts +70 -0
  228. package/src/helpers.ts +39 -0
  229. package/src/index.ts +11 -0
  230. package/src/keyboard-controller.tsx +63 -0
  231. package/src/onScroll.ts +66 -0
  232. package/src/prepareMVCP.ts +50 -0
  233. package/src/reanimated.tsx +63 -0
  234. package/src/requestAdjust.ts +41 -0
  235. package/src/scrollTo.ts +40 -0
  236. package/src/scrollToIndex.ts +34 -0
  237. package/src/setDidLayout.ts +25 -0
  238. package/src/setPaddingTop.ts +28 -0
  239. package/src/state.tsx +304 -0
  240. package/src/types.ts +610 -0
  241. package/src/updateAlignItemsPaddingTop.ts +18 -0
  242. package/src/updateAllPositions.ts +130 -0
  243. package/src/updateItemSize.ts +203 -0
  244. package/src/updateTotalSize.ts +44 -0
  245. package/src/useAnimatedValue.ts +6 -0
  246. package/src/useCombinedRef.ts +22 -0
  247. package/src/useInit.ts +17 -0
  248. package/src/useSyncLayout.tsx +68 -0
  249. package/src/useValue$.ts +53 -0
  250. package/src/viewability.ts +279 -0
  251. package/tsconfig.json +59 -0
  252. package/tsup.config.ts +21 -0
  253. package/index.js +0 -2348
  254. package/index.mjs +0 -2320
  255. /package/{animated.js → dist/animated.js} +0 -0
  256. /package/{animated.mjs → dist/animated.mjs} +0 -0
  257. /package/{keyboard-controller.js → dist/keyboard-controller.js} +0 -0
  258. /package/{keyboard-controller.mjs → dist/keyboard-controller.mjs} +0 -0
  259. /package/{reanimated.d.mts → dist/reanimated.d.mts} +0 -0
  260. /package/{reanimated.d.ts → dist/reanimated.d.ts} +0 -0
  261. /package/{reanimated.js → dist/reanimated.js} +0 -0
  262. /package/{reanimated.mjs → dist/reanimated.mjs} +0 -0
@@ -0,0 +1,8 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(bun run:*)"
5
+ ],
6
+ "deny": []
7
+ }
8
+ }
@@ -0,0 +1,60 @@
1
+ ---
2
+ description:
3
+ globs: CHANGELOG.md
4
+ alwaysApply: false
5
+ ---
6
+ # Changelog Update Rules
7
+
8
+ ## Process for Adding Git Changes to Changelog
9
+
10
+ When updating the changelog with recent git commits, follow these guidelines:
11
+
12
+ ### 1. Identify Relevant Commits
13
+ - Get all commits since the last version using: `git log --oneline --since="$(git log --grep="X.X.X" --format="%cd" --date=iso | head -1)" --reverse`
14
+ - Exclude non-user-facing commits like:
15
+ - "Update changelog"
16
+ - "chore:" commits
17
+ - Internal refactoring that doesn't affect API
18
+ - "Refactor*" commits
19
+
20
+ ### 2. Categorize Changes
21
+ Organize changes by type with these prefixes, in this order:
22
+ - **Feat:** New features and capabilities
23
+ - **Fix:** Bug fixes and corrections
24
+ - **Perf:** Performance improvements
25
+ - **Improvement:** Enhancements to existing functionality
26
+
27
+ Skip **Refactor:**, they don't need to be in the changelog
28
+
29
+ ### 3. Format Guidelines
30
+ - Write user-friendly descriptions, not raw commit messages
31
+ - Focus on the impact/benefit to users
32
+ - Be concise but descriptive
33
+ - Use present tense ("Fix X" not "Fixed X")
34
+ - Group similar changes together when possible
35
+
36
+ ### 4. Version Organization
37
+ - Add changes to the current version in package.json
38
+ - If significant changes warrant a new version, bump version first
39
+ - List most important changes (breaking changes, major features) first
40
+ - Group fixes and minor improvements at the end
41
+
42
+ ### 5. Example Format
43
+ ```markdown
44
+ ## X.X.X
45
+ - Fix: [Issue description and impact]
46
+ - Fix: [Another bug fix]
47
+ - Feat: [New feature description]
48
+ - Refactor: [API change description]
49
+ - Perf: [Performance improvement description]
50
+ - Improvement: [Enhancement description]
51
+ ```
52
+
53
+ ### 6. Quality Check
54
+ - Ensure all user-facing changes are documented
55
+ - Verify technical accuracy of descriptions
56
+ - Check that breaking changes are clearly marked
57
+ - Review for consistency in tone and format
58
+
59
+ ### 7. Update package version
60
+ If a specific version number is requested and it is newer than the version in package.json, update package.json
@@ -0,0 +1,15 @@
1
+ # These are supported funding model platforms
2
+
3
+ github: [jmeistrich]
4
+ patreon: # Replace with a single Patreon username
5
+ open_collective: # Replace with a single Open Collective username
6
+ ko_fi: # Replace with a single Ko-fi username
7
+ tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8
+ community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9
+ liberapay: # Replace with a single Liberapay username
10
+ issuehunt: # Replace with a single IssueHunt username
11
+ lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
12
+ polar: # Replace with a single Polar username
13
+ buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
14
+ thanks_dev: # Replace with a single thanks.dev username
15
+ custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
package/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ node_modules
2
+ dist
3
+ example/android
4
+ example/ios
5
+ legendapp-list.tgz
@@ -0,0 +1,5 @@
1
+ {
2
+ "tabWidth": 4,
3
+ "printWidth": 120,
4
+ "singleQuote": true
5
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "editor.codeActionsOnSave": {
3
+ "source.organizeImports.biome": "explicit",
4
+ "quickfix.biome": "explicit"
5
+ },
6
+ "editor.defaultFormatter": "biomejs.biome",
7
+ "[typescriptreact]": {
8
+ "editor.defaultFormatter": "biomejs.biome"
9
+ },
10
+ "[typescript]": {
11
+ "editor.defaultFormatter": "biomejs.biome"
12
+ },
13
+ "editor.formatOnSave": true
14
+ }
package/CLAUDE.md ADDED
@@ -0,0 +1,126 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Development Commands
6
+
7
+ ### Build and Development
8
+ - `bun run build` - Build the package using tsup and run post-build script
9
+ - `bun run publish:manual` - Build and publish to npm manually
10
+ - `bun run lint` - Check code formatting with Biome for src and example
11
+ - `bun run lint:fix` - Auto-fix formatting issues with Biome for src and example
12
+
13
+ ### Example App Development
14
+ The repository includes a React Native example app in the `example/` directory:
15
+ - `cd example && bun i && bun run ios` - Run the example app on iOS
16
+ - Example app uses Expo and demonstrates various Legend List features
17
+
18
+ ### Build Process
19
+ - Uses tsup for TypeScript compilation with multiple entry points:
20
+ - `src/index.ts` (main export)
21
+ - `src/animated.tsx` (animated variant)
22
+ - `src/reanimated.tsx` (reanimated variant)
23
+ - `src/keyboard-controller.tsx` (keyboard integration)
24
+ - Post-build script (`posttsup.ts`) copies LICENSE, CHANGELOG.md, README.md to dist and modifies package.json for publishing
25
+ - Builds to both CommonJS and ESM formats with TypeScript declarations
26
+
27
+ ## Architecture Overview
28
+
29
+ Legend List is a high-performance React Native list component designed as a drop-in replacement for FlatList with better performance, especially for dynamically sized items.
30
+
31
+ ### Core Components
32
+
33
+ **LegendList** (`src/LegendList.tsx`): Main component that wraps functionality in a StateProvider
34
+ - Handles virtualization logic, scroll management, and item positioning
35
+ - Manages anchor elements for `maintainVisibleContentPosition`
36
+ - Implements advanced scroll adjustment and jump prevention
37
+ - Uses container recycling for optimal performance
38
+
39
+ **State Management** (`src/state.tsx`): Global state management using observable patterns
40
+ - Manages container positions, item data, and scroll state
41
+ - Provides reactive updates to child components
42
+
43
+ **Container System** (`src/Container.tsx`, `src/Containers.tsx`): Manages item rendering containers
44
+ - Implements container recycling when `recycleItems` is enabled
45
+ - Handles absolute positioning of list items
46
+ - Manages container allocation and deallocation
47
+
48
+ **Scroll Adjustment** (`src/ScrollAdjustHandler.ts`): Handles complex scroll position adjustments
49
+ - Prevents scroll jumps when items are added/removed
50
+ - Manages scroll position during layout changes
51
+
52
+ ### Key Features Architecture
53
+
54
+ **Dynamic Item Sizing**: Items can have varying heights without performance penalties
55
+ - Uses `getEstimatedItemSize` or `estimatedItemSize` for initial estimates
56
+ - Measures actual sizes on layout and adjusts total size calculations
57
+ - Maintains position accuracy through size change events
58
+
59
+ **Bidirectional Infinite Lists**: Supports infinite scrolling in both directions
60
+ - `onStartReached` and `onEndReached` callbacks with configurable thresholds
61
+ - Maintains scroll position when items are added to the beginning
62
+
63
+ **Chat UI Support**:
64
+ - `alignItemsAtEnd` aligns content to bottom for chat interfaces
65
+ - `maintainScrollAtEnd` automatically scrolls to end when new items are added
66
+ - Avoids need for inverted lists which cause animation issues
67
+
68
+ **Column Support**: Multi-column layouts via `numColumns` prop
69
+ - Manages row heights when items have different sizes within the same row
70
+ - Handles column-aware positioning and gap calculations via `columnWrapperStyle`
71
+
72
+ ### Performance Optimizations
73
+
74
+ **Virtualization**: Only renders items in the visible area plus buffer zones
75
+ - `drawDistance` controls how far ahead/behind to render items
76
+ - Dynamic buffer adjustment based on scroll velocity
77
+ - Container recycling to minimize React element creation/destruction
78
+
79
+ **Scroll Jump Prevention**: Sophisticated system to prevent visual jumps
80
+ - Anchor element tracking for `maintainVisibleContentPosition`
81
+ - Scroll history tracking for velocity calculations
82
+ - Position adjustment when item sizes change
83
+
84
+ **Batched Updates**: Groups layout calculations to reduce renders
85
+ - Uses `requestAnimationFrame` for batching size change calculations
86
+ - Optimizes container position updates
87
+
88
+ ## Integration Patterns
89
+
90
+ ### Basic Usage
91
+ Legend List is designed as a drop-in FlatList replacement:
92
+ ```typescript
93
+ <LegendList
94
+ data={data}
95
+ renderItem={renderItem}
96
+ keyExtractor={(item) => item.id}
97
+ recycleItems={true}
98
+ />
99
+ ```
100
+
101
+ ### Optional Integrations
102
+ - **Animated**: `@legendapp/list/animated` - Works with React Native Animated
103
+ - **Reanimated**: `@legendapp/list/reanimated` - Works with React Native Reanimated
104
+ - **Keyboard Controller**: `@legendapp/list/keyboard-controller` - Integrates with react-native-keyboard-controller
105
+
106
+ ### Viewability Tracking
107
+ Supports advanced viewability detection:
108
+ - Compatible with FlatList's `viewabilityConfig` and `onViewableItemsChanged`
109
+ - Custom hooks available: `useViewability`, `useViewabilityAmount`
110
+
111
+ ## Important Development Notes
112
+
113
+ - When working with container recycling (`recycleItems={true}`), be cautious about local state in item components
114
+ - The `keyExtractor` is crucial for performance and correct behavior when data changes
115
+ - Use `getEstimatedItemSize` for better performance with varying item sizes
116
+ - The component uses advanced scroll position management that should not be interfered with directly
117
+
118
+ ## Configuration Files
119
+
120
+ - **Biome** (`biome.json`): Used for linting and formatting with specific rules for the project
121
+ - **TypeScript** (`tsconfig.json`): Configured for React Native with path mappings for internal imports
122
+ - **Cursor Rules**: `.cursor/rules/changelog.mdc` contains guidelines for maintaining the changelog
123
+
124
+ ## Testing the Library
125
+
126
+ To test changes, use the comprehensive example app which demonstrates various scenarios including dynamic sizing, infinite loading, chat interfaces, and performance comparisons with FlatList.
package/biome.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
3
+ "vcs": {
4
+ "enabled": false,
5
+ "clientKind": "git",
6
+ "useIgnoreFile": false
7
+ },
8
+ "files": {
9
+ "ignoreUnknown": false,
10
+ "ignore": []
11
+ },
12
+ "formatter": {
13
+ "enabled": true,
14
+ "formatWithErrors": false,
15
+ "indentStyle": "space",
16
+ "indentWidth": 4,
17
+ "lineEnding": "lf",
18
+ "lineWidth": 120
19
+ },
20
+ "organizeImports": {
21
+ "enabled": true
22
+ },
23
+ "linter": {
24
+ "enabled": true,
25
+ "rules": {
26
+ "recommended": true,
27
+ "style": {
28
+ "noNonNullAssertion": "off"
29
+ },
30
+ "suspicious": {
31
+ "noArrayIndexKey": "off",
32
+ "noExplicitAny": "off",
33
+ "noConfusingVoidType": "off"
34
+ },
35
+ "correctness": {
36
+ "noUnusedImports": "warn",
37
+ "useExhaustiveDependencies": "off"
38
+ }
39
+ }
40
+ },
41
+ "javascript": {
42
+ "formatter": {
43
+ "quoteStyle": "double"
44
+ }
45
+ }
46
+ }