@legendapp/list 2.0.0-next.1 → 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.
- package/.claude/settings.local.json +8 -0
- package/.cursor/rules/changelog.mdc +60 -0
- package/.github/FUNDING.yml +15 -0
- package/.gitignore +5 -0
- package/.prettierrc.json +5 -0
- package/.vscode/settings.json +14 -0
- package/CLAUDE.md +126 -0
- package/biome.json +46 -0
- package/bun.lock +1289 -0
- package/bunfig.toml +2 -0
- package/dist/CHANGELOG.md +119 -0
- package/dist/LICENSE +21 -0
- package/dist/README.md +139 -0
- package/{animated.d.mts → dist/animated.d.mts} +1 -1
- package/{animated.d.ts → dist/animated.d.ts} +1 -1
- package/{index.d.mts → dist/index.d.mts} +16 -10
- package/{index.d.ts → dist/index.d.ts} +16 -10
- package/{index.js → dist/index.js} +52 -32
- package/{index.mjs → dist/index.mjs} +52 -32
- package/{keyboard-controller.d.mts → dist/keyboard-controller.d.mts} +4 -4
- package/{keyboard-controller.d.ts → dist/keyboard-controller.d.ts} +4 -4
- package/dist/package.json +35 -0
- package/example/README.md +40 -0
- package/example/api/data/genres.json +23 -0
- package/example/api/data/playlist/10402-10749.json +1 -0
- package/example/api/data/playlist/10402-10770.json +1 -0
- package/example/api/data/playlist/10402-37.json +1 -0
- package/example/api/data/playlist/10749-10752.json +1 -0
- package/example/api/data/playlist/10749-10770.json +1 -0
- package/example/api/data/playlist/10749-37.json +1 -0
- package/example/api/data/playlist/10749-878.json +1 -0
- package/example/api/data/playlist/10751-10402.json +1 -0
- package/example/api/data/playlist/10751-10752.json +1 -0
- package/example/api/data/playlist/10751-37.json +1 -0
- package/example/api/data/playlist/10751-53.json +1 -0
- package/example/api/data/playlist/10751-878.json +1 -0
- package/example/api/data/playlist/10751-9648.json +1 -0
- package/example/api/data/playlist/10752-37.json +1 -0
- package/example/api/data/playlist/12-10402.json +1 -0
- package/example/api/data/playlist/12-10749.json +1 -0
- package/example/api/data/playlist/12-18.json +1 -0
- package/example/api/data/playlist/12-27.json +1 -0
- package/example/api/data/playlist/12-35.json +1 -0
- package/example/api/data/playlist/14-36.json +1 -0
- package/example/api/data/playlist/14-878.json +1 -0
- package/example/api/data/playlist/16-10751.json +1 -0
- package/example/api/data/playlist/16-10770.json +1 -0
- package/example/api/data/playlist/16-35.json +1 -0
- package/example/api/data/playlist/16-36.json +1 -0
- package/example/api/data/playlist/16-53.json +1 -0
- package/example/api/data/playlist/18-10751.json +1 -0
- package/example/api/data/playlist/18-10752.json +1 -0
- package/example/api/data/playlist/18-37.json +1 -0
- package/example/api/data/playlist/18-53.json +1 -0
- package/example/api/data/playlist/18-878.json +1 -0
- package/example/api/data/playlist/27-10749.json +1 -0
- package/example/api/data/playlist/27-10770.json +1 -0
- package/example/api/data/playlist/28-10749.json +1 -0
- package/example/api/data/playlist/28-10751.json +1 -0
- package/example/api/data/playlist/28-10770.json +1 -0
- package/example/api/data/playlist/28-16.json +1 -0
- package/example/api/data/playlist/28-18.json +1 -0
- package/example/api/data/playlist/28-36.json +1 -0
- package/example/api/data/playlist/28-37.json +1 -0
- package/example/api/data/playlist/28-53.json +1 -0
- package/example/api/data/playlist/28-80.json +1 -0
- package/example/api/data/playlist/28-99.json +1 -0
- package/example/api/data/playlist/35-10749.json +1 -0
- package/example/api/data/playlist/35-10751.json +1 -0
- package/example/api/data/playlist/35-10752.json +1 -0
- package/example/api/data/playlist/35-27.json +1 -0
- package/example/api/data/playlist/35-36.json +1 -0
- package/example/api/data/playlist/35-53.json +1 -0
- package/example/api/data/playlist/35-80.json +1 -0
- package/example/api/data/playlist/36-37.json +1 -0
- package/example/api/data/playlist/36-878.json +1 -0
- package/example/api/data/playlist/36-9648.json +1 -0
- package/example/api/data/playlist/53-10752.json +1 -0
- package/example/api/data/playlist/80-10770.json +1 -0
- package/example/api/data/playlist/80-14.json +1 -0
- package/example/api/data/playlist/80-18.json +1 -0
- package/example/api/data/playlist/80-37.json +1 -0
- package/example/api/data/playlist/878-37.json +1 -0
- package/example/api/data/playlist/9648-10770.json +1 -0
- package/example/api/data/playlist/9648-37.json +1 -0
- package/example/api/data/playlist/9648-53.json +1 -0
- package/example/api/data/playlist/9648-878.json +1 -0
- package/example/api/data/playlist/99-10749.json +1 -0
- package/example/api/data/playlist/99-14.json +1 -0
- package/example/api/data/playlist/99-18.json +1 -0
- package/example/api/data/playlist/99-27.json +1 -0
- package/example/api/data/playlist/99-53.json +1 -0
- package/example/api/data/playlist/99-9648.json +1 -0
- package/example/api/data/playlist/index.ts +73 -0
- package/example/api/data/rows.json +1 -0
- package/example/api/index.ts +36 -0
- package/example/app/(tabs)/_layout.tsx +60 -0
- package/example/app/(tabs)/cards.tsx +81 -0
- package/example/app/(tabs)/index.tsx +205 -0
- package/example/app/(tabs)/moviesL.tsx +7 -0
- package/example/app/(tabs)/moviesLR.tsx +7 -0
- package/example/app/+not-found.tsx +32 -0
- package/example/app/_layout.tsx +34 -0
- package/example/app/accurate-scrollto/index.tsx +125 -0
- package/example/app/accurate-scrollto-2/index.tsx +52 -0
- package/example/app/accurate-scrollto-huge/index.tsx +128 -0
- package/example/app/add-to-end/index.tsx +82 -0
- package/example/app/ai-chat/index.tsx +236 -0
- package/example/app/bidirectional-infinite-list/index.tsx +133 -0
- package/example/app/cards-columns/index.tsx +37 -0
- package/example/app/cards-flashlist/index.tsx +122 -0
- package/example/app/cards-flatlist/index.tsx +94 -0
- package/example/app/cards-no-recycle/index.tsx +110 -0
- package/example/app/cards-renderItem.tsx +354 -0
- package/example/app/chat-example/index.tsx +167 -0
- package/example/app/chat-infinite/index.tsx +239 -0
- package/example/app/chat-keyboard/index.tsx +248 -0
- package/example/app/chat-resize-outer/index.tsx +247 -0
- package/example/app/columns/index.tsx +78 -0
- package/example/app/countries/index.tsx +182 -0
- package/example/app/countries-flashlist/index.tsx +163 -0
- package/example/app/countries-reorder/index.tsx +187 -0
- package/example/app/extra-data/index.tsx +86 -0
- package/example/app/filter-elements/filter-data-provider.tsx +55 -0
- package/example/app/filter-elements/index.tsx +118 -0
- package/example/app/initial-scroll-index/index.tsx +106 -0
- package/example/app/initial-scroll-index/renderFixedItem.tsx +215 -0
- package/example/app/initial-scroll-index-free-height/index.tsx +70 -0
- package/example/app/initial-scroll-index-keyed/index.tsx +62 -0
- package/example/app/lazy-list/index.tsx +123 -0
- package/example/app/movies-flashlist/index.tsx +7 -0
- package/example/app/mutable-cells/index.tsx +104 -0
- package/example/app/video-feed/index.tsx +119 -0
- package/example/app.config.js +22 -0
- package/example/app.json +45 -0
- package/example/assets/fonts/SpaceMono-Regular.ttf +0 -0
- package/example/assets/images/adaptive-icon.png +0 -0
- package/example/assets/images/favicon.png +0 -0
- package/example/assets/images/icon.png +0 -0
- package/example/assets/images/partial-react-logo.png +0 -0
- package/example/assets/images/react-logo.png +0 -0
- package/example/assets/images/react-logo@2x.png +0 -0
- package/example/assets/images/react-logo@3x.png +0 -0
- package/example/assets/images/splash-icon.png +0 -0
- package/example/autoscroll.sh +101 -0
- package/example/bun.lock +2266 -0
- package/example/bunfig.toml +2 -0
- package/example/components/Breathe.tsx +54 -0
- package/example/components/Circle.tsx +69 -0
- package/example/components/Collapsible.tsx +44 -0
- package/example/components/ExternalLink.tsx +24 -0
- package/example/components/HapticTab.tsx +18 -0
- package/example/components/HelloWave.tsx +37 -0
- package/example/components/Movies.tsx +179 -0
- package/example/components/ParallaxScrollView.tsx +81 -0
- package/example/components/ThemedText.tsx +60 -0
- package/example/components/ThemedView.tsx +14 -0
- package/example/components/__tests__/ThemedText-test.tsx +10 -0
- package/example/components/__tests__/__snapshots__/ThemedText-test.tsx.snap +24 -0
- package/example/components/ui/IconSymbol.ios.tsx +32 -0
- package/example/components/ui/IconSymbol.tsx +43 -0
- package/example/components/ui/TabBarBackground.ios.tsx +22 -0
- package/example/components/ui/TabBarBackground.tsx +6 -0
- package/example/constants/Colors.ts +26 -0
- package/example/constants/constants.ts +5 -0
- package/example/constants/useScrollTest.ts +19 -0
- package/example/hooks/useColorScheme.ts +1 -0
- package/example/hooks/useColorScheme.web.ts +8 -0
- package/example/hooks/useThemeColor.ts +22 -0
- package/example/ios/.xcode.env +11 -0
- package/example/ios/Podfile +64 -0
- package/example/ios/Podfile.lock +2767 -0
- package/example/ios/Podfile.properties.json +5 -0
- package/example/ios/listtest/AppDelegate.swift +70 -0
- package/example/ios/listtest/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png +0 -0
- package/example/ios/listtest/Images.xcassets/AppIcon.appiconset/Contents.json +14 -0
- package/example/ios/listtest/Images.xcassets/Contents.json +6 -0
- package/example/ios/listtest/Images.xcassets/SplashScreenBackground.colorset/Contents.json +20 -0
- package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/Contents.json +23 -0
- package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image.png +0 -0
- package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image@2x.png +0 -0
- package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image@3x.png +0 -0
- package/example/ios/listtest/Info.plist +85 -0
- package/example/ios/listtest/PrivacyInfo.xcprivacy +48 -0
- package/example/ios/listtest/SplashScreen.storyboard +42 -0
- package/example/ios/listtest/Supporting/Expo.plist +12 -0
- package/example/ios/listtest/listtest-Bridging-Header.h +3 -0
- package/example/ios/listtest/listtest.entitlements +5 -0
- package/example/ios/listtest.xcodeproj/project.pbxproj +547 -0
- package/example/ios/listtest.xcodeproj/xcshareddata/xcschemes/listtest.xcscheme +88 -0
- package/example/ios/listtest.xcworkspace/contents.xcworkspacedata +10 -0
- package/example/metro.config.js +16 -0
- package/example/package.json +73 -0
- package/example/scripts/reset-project.js +84 -0
- package/example/tsconfig.json +26 -0
- package/package.json +88 -34
- package/posttsup.ts +24 -0
- package/src/Container.tsx +176 -0
- package/src/Containers.tsx +85 -0
- package/src/ContextContainer.ts +145 -0
- package/src/DebugView.tsx +83 -0
- package/src/LazyLegendList.tsx +41 -0
- package/src/LeanView.tsx +18 -0
- package/src/LegendList.tsx +558 -0
- package/src/ListComponent.tsx +191 -0
- package/src/ScrollAdjust.tsx +24 -0
- package/src/ScrollAdjustHandler.ts +26 -0
- package/src/Separator.tsx +14 -0
- package/src/animated.tsx +6 -0
- package/src/calculateItemsInView.ts +363 -0
- package/src/calculateOffsetForIndex.ts +23 -0
- package/src/calculateOffsetWithOffsetPosition.ts +26 -0
- package/src/checkAllSizesKnown.ts +17 -0
- package/src/checkAtBottom.ts +36 -0
- package/src/checkAtTop.ts +27 -0
- package/src/checkThreshold.ts +30 -0
- package/src/constants.ts +11 -0
- package/src/createColumnWrapperStyle.ts +16 -0
- package/src/doInitialAllocateContainers.ts +40 -0
- package/src/doMaintainScrollAtEnd.ts +34 -0
- package/src/findAvailableContainers.ts +98 -0
- package/src/finishScrollTo.ts +8 -0
- package/src/getId.ts +21 -0
- package/src/getItemSize.ts +52 -0
- package/src/getRenderedItem.ts +34 -0
- package/src/getScrollVelocity.ts +47 -0
- package/src/handleLayout.ts +70 -0
- package/src/helpers.ts +39 -0
- package/src/index.ts +11 -0
- package/src/keyboard-controller.tsx +63 -0
- package/src/onScroll.ts +66 -0
- package/src/prepareMVCP.ts +50 -0
- package/src/reanimated.tsx +63 -0
- package/src/requestAdjust.ts +41 -0
- package/src/scrollTo.ts +40 -0
- package/src/scrollToIndex.ts +34 -0
- package/src/setDidLayout.ts +25 -0
- package/src/setPaddingTop.ts +28 -0
- package/src/state.tsx +304 -0
- package/src/types.ts +610 -0
- package/src/updateAlignItemsPaddingTop.ts +18 -0
- package/src/updateAllPositions.ts +130 -0
- package/src/updateItemSize.ts +203 -0
- package/src/updateTotalSize.ts +44 -0
- package/src/useAnimatedValue.ts +6 -0
- package/src/useCombinedRef.ts +22 -0
- package/src/useInit.ts +17 -0
- package/src/useSyncLayout.tsx +68 -0
- package/src/useValue$.ts +53 -0
- package/src/viewability.ts +279 -0
- package/tsconfig.json +59 -0
- package/tsup.config.ts +21 -0
- /package/{animated.js → dist/animated.js} +0 -0
- /package/{animated.mjs → dist/animated.mjs} +0 -0
- /package/{keyboard-controller.js → dist/keyboard-controller.js} +0 -0
- /package/{keyboard-controller.mjs → dist/keyboard-controller.mjs} +0 -0
- /package/{reanimated.d.mts → dist/reanimated.d.mts} +0 -0
- /package/{reanimated.d.ts → dist/reanimated.d.ts} +0 -0
- /package/{reanimated.js → dist/reanimated.js} +0 -0
- /package/{reanimated.mjs → dist/reanimated.mjs} +0 -0
package/bunfig.toml
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
## 1.1.4
|
|
2
|
+
- Feat: Add sizes to getState()
|
|
3
|
+
|
|
4
|
+
## 1.1.3
|
|
5
|
+
- Fix: scrollToEnd was not always setting `viewPosition: 1` correctly
|
|
6
|
+
|
|
7
|
+
## 1.1.2
|
|
8
|
+
- Fix: Adding items in a list with item separators had a small layout jump as the previously last item re-rendered with a separator
|
|
9
|
+
|
|
10
|
+
## 1.1.1
|
|
11
|
+
- Fix: scrollTo accuracy when paddingTop changes
|
|
12
|
+
|
|
13
|
+
## 1.1.0
|
|
14
|
+
- Feat: Add LazyLegendList component for virtualizing regular children
|
|
15
|
+
- Feat: Support initialScrollIndex with viewOffset and viewPosition
|
|
16
|
+
- Feat: Add estimatedListSize prop for better initial size estimation
|
|
17
|
+
|
|
18
|
+
## 1.0.20
|
|
19
|
+
- Types: Fix type of ref in Reanimated LegendList
|
|
20
|
+
|
|
21
|
+
## 1.0.19
|
|
22
|
+
- Fix: scrollToEnd not including footerSize
|
|
23
|
+
|
|
24
|
+
## 1.0.18
|
|
25
|
+
- Feat: Add a useListScrollSize hook
|
|
26
|
+
- Fix: Support renderItem being a function component
|
|
27
|
+
- Fix: scrollToEnd being incorrect by the amount of the bottom padding
|
|
28
|
+
|
|
29
|
+
## 1.0.17
|
|
30
|
+
- Fix: initialScrollIndex not taking header component size into account
|
|
31
|
+
- Fix: PaddingAndAdjust for ListHeaderComponent
|
|
32
|
+
- Fix: ignore alignItemsAtEnd when the list is empty
|
|
33
|
+
|
|
34
|
+
## 1.0.16
|
|
35
|
+
- Fix: isAtEnd was going to false when overscrolling
|
|
36
|
+
- Fix: refreshControl not being top padded correctly
|
|
37
|
+
- Fix: type of useLastItem hook
|
|
38
|
+
- Fix: header component was not displaying if a list had no data
|
|
39
|
+
- Fix: scrollToIndex logic that fixes scroll after items layout was not using viewPosition/viewOffset
|
|
40
|
+
- Fix: Improve scrollToIndex accuracy
|
|
41
|
+
- Fix: Improve scrollToEnd accuracy
|
|
42
|
+
|
|
43
|
+
## 1.0.15
|
|
44
|
+
- Feat: Add a useIsLastItem hook
|
|
45
|
+
- Feat: Support horizontal lists without an intrinsic height, it takes the maximum height of list items
|
|
46
|
+
- Feat: Add onLoad prop
|
|
47
|
+
- Fix: maintainVisibleContentPosition not working on horizontal lists
|
|
48
|
+
- Perf: scrollForNextCalculateItemsInView was not taking drawDistance into account correctly
|
|
49
|
+
- Perf: Improved the algorithm for allocating containers to items
|
|
50
|
+
- Perf: Use useLayoutEffect in LegendList if available to get the outer ScrollView layout as soon as possible
|
|
51
|
+
|
|
52
|
+
## 1.0.14
|
|
53
|
+
- Fix: A container changing size while inactive but not yet recycled could potentially overlap with elements onscreen if large enough
|
|
54
|
+
|
|
55
|
+
## 1.0.13
|
|
56
|
+
- Fix: Missing React import in ListHeaderComponentContainer crashing some environments
|
|
57
|
+
- Fix: `initialScrollIndex` was off by padding if using "padding" or "paddingVertical" props
|
|
58
|
+
|
|
59
|
+
## 1.0.12
|
|
60
|
+
- Fix: Initial scroll index and scrollTo were not compensating for top padding
|
|
61
|
+
- Fix: Removed an overly aggressive optimization that was sometimes causing blank spaces after scrolling
|
|
62
|
+
- Fix: Adding a lot of items to the end with maintainScrollAtEnd could result in a large blank space
|
|
63
|
+
- Fix: ListHeaderComponent sometimes not positioned correctly with maintainVisibleContentPosition
|
|
64
|
+
- Fix: Gap styles not working with maintainVisibleContentPosition
|
|
65
|
+
|
|
66
|
+
## 1.0.11
|
|
67
|
+
- Fix: scrollTo was sometimes showing gaps at the bottom or bottom after reaching the destination
|
|
68
|
+
|
|
69
|
+
## 1.0.10
|
|
70
|
+
- Fix: Removed an optimization that only checked newly visible items, which could sometimes cause gaps in lists
|
|
71
|
+
- Fix: Scroll history resets properly during scroll operations, which was causing gaps after scroll
|
|
72
|
+
- Fix: Made scroll buffer calculations and scroll jump handling more reliable
|
|
73
|
+
|
|
74
|
+
## 1.0.9
|
|
75
|
+
- Fix: Use the `use-sync-external-store` shim to support older versions of react
|
|
76
|
+
- Fix: Lists sometimes leaving some gaps when reordering a list
|
|
77
|
+
- Fix: Sometimes precomputing next scroll position for calculation incorrectly
|
|
78
|
+
|
|
79
|
+
## 1.0.8
|
|
80
|
+
- Perf: The scroll buffering algorithm is smarter and adjusts based on scroll direction for better performance
|
|
81
|
+
- Perf: The container-finding logic keeps index order, reducing gaps in rendering
|
|
82
|
+
- Perf: Combine multiple hooks in Container to a single `useArray$` hook
|
|
83
|
+
|
|
84
|
+
## 1.0.7
|
|
85
|
+
- Fix: Containers that move out of view are handled better
|
|
86
|
+
|
|
87
|
+
## 1.0.6
|
|
88
|
+
- Fix: Average item size calculations are more accurate while scrolling
|
|
89
|
+
- Fix: Items in view are handled better when data changes
|
|
90
|
+
- Fix: Scroll position is maintained more accurately during updates
|
|
91
|
+
|
|
92
|
+
## 1.0.5
|
|
93
|
+
- Fix: Fast scrolling sometimes caused elements to disappear
|
|
94
|
+
- Fix: Out-of-range `scrollToIndex` calls are handled better
|
|
95
|
+
|
|
96
|
+
## 1.0.4
|
|
97
|
+
- Fix: Container allocation is more efficient
|
|
98
|
+
- Fix: Bidirectional infinite lists scroll better on the old architecture
|
|
99
|
+
- Fix: Item size updates are handled more reliably
|
|
100
|
+
- Fix: Container reuse logic is more accurate
|
|
101
|
+
- Fix: Zero-size layouts are handled better in the old architecture
|
|
102
|
+
|
|
103
|
+
## 1.0.3
|
|
104
|
+
- Fix: Items that are larger than the estimated size are handled correctly
|
|
105
|
+
|
|
106
|
+
## 1.0.2
|
|
107
|
+
- Fix: Initial layout works better in the old architecture
|
|
108
|
+
- Fix: Average size calculations are more accurate for bidirectional scrolling
|
|
109
|
+
- Fix: Initial scroll index behavior is more precise
|
|
110
|
+
- Fix: Item size calculations are more accurate overall
|
|
111
|
+
|
|
112
|
+
## 1.0.1
|
|
113
|
+
- Fix: Total size calculations are correct when using average sizes
|
|
114
|
+
- Fix: Keyboard avoiding behavior is improved for a smoother experience
|
|
115
|
+
|
|
116
|
+
## 1.0.0
|
|
117
|
+
Initial release! Major changes if you're coming from a beta version:
|
|
118
|
+
|
|
119
|
+
- Item hooks like `useRecyclingState` are no longer render props, but can be imported directly from `@legendapp/list`.
|
package/dist/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Moo.do LLC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/README.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Legend List
|
|
2
|
+
|
|
3
|
+
**Legend List** is a high-performance list component for **React Native**, written purely in Typescript with no native dependencies. It is a drop-in replacement for `FlatList` and `FlashList` with better performance, especially when handling dynamically sized items.
|
|
4
|
+
|
|
5
|
+
<video src="https://github.com/user-attachments/assets/8641e305-ab06-4fb3-a96a-fd220df84985"></video>
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 🤔 Why Legend List?
|
|
10
|
+
|
|
11
|
+
* **Performance:** Designed from the ground up and heavily optimized for performance, it is faster than FlatList and other list libraries in most scenarios.
|
|
12
|
+
* **Dynamic Item Sizes:** Natively supports items with varying heights without performance hits.
|
|
13
|
+
* **Drop-in Replacement:** API compatibility with `FlatList` and `FlashList` for easier migration.
|
|
14
|
+
* **100% JS:** No native module linking required, ensuring easy integration and compatibility across platforms.
|
|
15
|
+
* **Lightweight:** Our goal is to keep LegendList as small of a dependency as possible. For more advanced use cases, we plan on supporting optional plugins. This ensures that we keep the package size as small as possible.
|
|
16
|
+
* **Bidirectional infinite lists:** Supports infinite scrolling in both directions with no flashes or scroll jumping
|
|
17
|
+
* **Chat UIs without inverted:** Chat UIs can align their content to the bottom and maintain scroll at end, so that the list doesn't need to be inverted, which causes weird behavior (in animations, etc...)
|
|
18
|
+
|
|
19
|
+
For more information, listen to the Legend List episode of the [React Native Radio Podcast](https://infinite.red/react-native-radio/rnr-325-legend-list-with-jay-meistrich) and the [livestream with Expo](https://www.youtube.com/watch?v=XpZMveUCke8).
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
## ✨ Additional Features
|
|
23
|
+
|
|
24
|
+
Beyond standard `FlatList` capabilities:
|
|
25
|
+
|
|
26
|
+
* `recycleItems`: (boolean) Toggles item component recycling.
|
|
27
|
+
* `true`: Reuses item components for optimal performance. Be cautious if your item components contain local state, as it might be reused unexpectedly.
|
|
28
|
+
* `false` (default): Creates new item components every time. Less performant but safer if items have complex internal state.
|
|
29
|
+
* `maintainScrollAtEnd`: (boolean) If `true` and the user is scrolled near the bottom (within `maintainScrollAtEndThreshold * screen height`), the list automatically scrolls to the end when items are added or heights change. Useful for chat interfaces.
|
|
30
|
+
* `alignItemsAtEnd`: (boolean) Useful for chat UIs, content smaller than the View will be aligned to the bottom of the list.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 📚 Documentation
|
|
35
|
+
|
|
36
|
+
For comprehensive documentation, guides, and the full API reference, please visit:
|
|
37
|
+
|
|
38
|
+
➡️ **[Legend List Documentation Site](https://www.legendapp.com/open-source/list)**
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 💻 Usage
|
|
43
|
+
|
|
44
|
+
### Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Using Bun
|
|
48
|
+
bun add @legendapp/list
|
|
49
|
+
|
|
50
|
+
# Using npm
|
|
51
|
+
npm install @legendapp/list
|
|
52
|
+
|
|
53
|
+
# Using Yarn
|
|
54
|
+
yarn add @legendapp/list
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Example
|
|
58
|
+
```tsx
|
|
59
|
+
import React, { useRef } from "react"
|
|
60
|
+
import { View, Image, Text, StyleSheet } from "react-native"
|
|
61
|
+
import { LegendList, LegendListRef, LegendListRenderItemProps } from "@legendapp/list"
|
|
62
|
+
|
|
63
|
+
// Define the type for your data items
|
|
64
|
+
interface UserData {
|
|
65
|
+
id: string;
|
|
66
|
+
name: string;
|
|
67
|
+
photoUri: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const LegendListExample = () => {
|
|
71
|
+
// Optional: Ref for accessing list methods (e.g., scrollTo)
|
|
72
|
+
const listRef = useRef<LegendListRef | null>(null)
|
|
73
|
+
|
|
74
|
+
const data = []
|
|
75
|
+
|
|
76
|
+
const renderItem = ({ item }: LegendListRenderItemProps<UserData>) => {
|
|
77
|
+
return (
|
|
78
|
+
<View>
|
|
79
|
+
<Image source={{ uri: item.photoUri }} />
|
|
80
|
+
<Text>{item.name}</Text>
|
|
81
|
+
</View>
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<LegendList
|
|
87
|
+
// Required Props
|
|
88
|
+
data={data}
|
|
89
|
+
renderItem={renderItem}
|
|
90
|
+
|
|
91
|
+
// Recommended props (Improves performance)
|
|
92
|
+
keyExtractor={(item) => item.id}
|
|
93
|
+
recycleItems={true}
|
|
94
|
+
|
|
95
|
+
// Recommended if data can change
|
|
96
|
+
maintainVisibleContentPosition
|
|
97
|
+
|
|
98
|
+
ref={listRef}
|
|
99
|
+
/>
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export default LegendListExample
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## How to Build
|
|
110
|
+
|
|
111
|
+
1. `bun i`
|
|
112
|
+
2. `bun run build` will build the package to the `dist` folder.
|
|
113
|
+
|
|
114
|
+
## Running the Example
|
|
115
|
+
|
|
116
|
+
1. `cd example`
|
|
117
|
+
2. `bun i`
|
|
118
|
+
3. `bun run ios`
|
|
119
|
+
|
|
120
|
+
## PRs gladly accepted!
|
|
121
|
+
|
|
122
|
+
There's not a ton of code so hopefully it's easy to contribute. If you want to add a missing feature or fix a bug please post an issue to see if development is already in progress so we can make sure to not duplicate work 😀.
|
|
123
|
+
|
|
124
|
+
## Upcoming Roadmap
|
|
125
|
+
|
|
126
|
+
- [] Column spans
|
|
127
|
+
- [] overrideItemLayout
|
|
128
|
+
- [] Sticky headers
|
|
129
|
+
- [] Masonry layout
|
|
130
|
+
- [] getItemType
|
|
131
|
+
- [] React DOM implementation
|
|
132
|
+
|
|
133
|
+
## Community
|
|
134
|
+
|
|
135
|
+
Join us on [Discord](https://discord.gg/tuW2pAffjA) to get involved with the Legend community.
|
|
136
|
+
|
|
137
|
+
## 👩⚖️ License
|
|
138
|
+
|
|
139
|
+
[MIT](LICENSE)
|
|
@@ -31,7 +31,7 @@ declare const AnimatedLegendList: Animated.AnimatedComponent<(<T>(props: Omit<Om
|
|
|
31
31
|
ListFooterComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
32
32
|
ListHeaderComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
33
33
|
ListHeaderComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
34
|
-
maintainScrollAtEnd?: boolean;
|
|
34
|
+
maintainScrollAtEnd?: boolean | _legendapp_list.MaintainScrollAtEndOptions;
|
|
35
35
|
maintainScrollAtEndThreshold?: number;
|
|
36
36
|
maintainVisibleContentPosition?: boolean;
|
|
37
37
|
numColumns?: number;
|
|
@@ -31,7 +31,7 @@ declare const AnimatedLegendList: Animated.AnimatedComponent<(<T>(props: Omit<Om
|
|
|
31
31
|
ListFooterComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
32
32
|
ListHeaderComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
33
33
|
ListHeaderComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
34
|
-
maintainScrollAtEnd?: boolean;
|
|
34
|
+
maintainScrollAtEnd?: boolean | _legendapp_list.MaintainScrollAtEndOptions;
|
|
35
35
|
maintainScrollAtEndThreshold?: number;
|
|
36
36
|
maintainVisibleContentPosition?: boolean;
|
|
37
37
|
numColumns?: number;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React$1 from 'react';
|
|
2
2
|
import { ComponentProps, ReactNode, Dispatch, SetStateAction } from 'react';
|
|
3
3
|
import * as react_native from 'react-native';
|
|
4
|
-
import { View, ScrollView, StyleProp, ViewStyle, ScrollViewProps, NativeSyntheticEvent, NativeScrollEvent, ScrollViewComponent, ScrollResponderMixin } from 'react-native';
|
|
5
|
-
import Animated from 'react-native-reanimated';
|
|
4
|
+
import { View, ScrollView, Animated, StyleProp, ViewStyle, ScrollViewProps, LayoutRectangle, NativeSyntheticEvent, NativeScrollEvent, ScrollViewComponent, ScrollResponderMixin } from 'react-native';
|
|
5
|
+
import Animated$1 from 'react-native-reanimated';
|
|
6
6
|
import * as _legendapp_list_reanimated from '@legendapp/list/reanimated';
|
|
7
7
|
|
|
8
8
|
type ListenerType = "numContainers" | "numContainersPooled" | `containerItemKey${number}` | `containerItemData${number}` | `containerPosition${number}` | `containerColumn${number}` | "containersDidLayout" | "extraData" | "numColumns" | "lastItemKeys" | "totalSize" | "alignItemsPaddingTop" | "stylePaddingTop" | "scrollAdjust" | "scrollAdjustUserOffset" | "headerSize" | "footerSize" | "maintainVisibleContentPosition" | "debugRawScroll" | "debugComputedScroll" | "otherAxisSize" | "scrollSize";
|
|
@@ -26,7 +26,7 @@ declare class ScrollAdjustHandler {
|
|
|
26
26
|
setMounted(): void;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof ScrollView> | ComponentProps<typeof Animated.ScrollView>> = Omit<TScrollView, "contentOffset" | "contentInset" | "maintainVisibleContentPosition" | "stickyHeaderIndices" | "removeClippedSubviews" | "children"> & {
|
|
29
|
+
type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof ScrollView> | ComponentProps<typeof Animated.ScrollView> | ComponentProps<typeof Animated$1.ScrollView>> = Omit<TScrollView, "contentOffset" | "contentInset" | "maintainVisibleContentPosition" | "stickyHeaderIndices" | "removeClippedSubviews" | "children"> & {
|
|
30
30
|
/**
|
|
31
31
|
* If true, aligns items at the end of the list.
|
|
32
32
|
* @default false
|
|
@@ -122,7 +122,7 @@ type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof Scroll
|
|
|
122
122
|
* If true, auto-scrolls to end when new items are added.
|
|
123
123
|
* @default false
|
|
124
124
|
*/
|
|
125
|
-
maintainScrollAtEnd?: boolean;
|
|
125
|
+
maintainScrollAtEnd?: boolean | MaintainScrollAtEndOptions;
|
|
126
126
|
/**
|
|
127
127
|
* Distance threshold in percentage of screen size to trigger maintainScrollAtEnd.
|
|
128
128
|
* @default 0.1
|
|
@@ -233,6 +233,11 @@ type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof Scroll
|
|
|
233
233
|
elapsedTimeInMs: number;
|
|
234
234
|
}) => void;
|
|
235
235
|
};
|
|
236
|
+
interface MaintainScrollAtEndOptions {
|
|
237
|
+
onLayout?: boolean;
|
|
238
|
+
onItemLayout?: boolean;
|
|
239
|
+
onDataChange?: boolean;
|
|
240
|
+
}
|
|
236
241
|
interface ColumnWrapperStyle {
|
|
237
242
|
rowGap?: number;
|
|
238
243
|
gap?: number;
|
|
@@ -309,6 +314,7 @@ interface InternalState {
|
|
|
309
314
|
refScroller: React.RefObject<ScrollView>;
|
|
310
315
|
loadStartTime: number;
|
|
311
316
|
initialScroll: ScrollIndexWithOffsetPosition | undefined;
|
|
317
|
+
lastLayout: LayoutRectangle | undefined;
|
|
312
318
|
props: {
|
|
313
319
|
alignItemsAtEnd: boolean;
|
|
314
320
|
data: readonly any[];
|
|
@@ -316,7 +322,7 @@ interface InternalState {
|
|
|
316
322
|
getEstimatedItemSize: ((index: number, item: any) => number) | undefined;
|
|
317
323
|
horizontal: boolean;
|
|
318
324
|
keyExtractor: ((item: any, index: number) => string) | undefined;
|
|
319
|
-
maintainScrollAtEnd: boolean;
|
|
325
|
+
maintainScrollAtEnd: boolean | MaintainScrollAtEndOptions;
|
|
320
326
|
maintainScrollAtEndThreshold: number | undefined;
|
|
321
327
|
maintainVisibleContentPosition: boolean;
|
|
322
328
|
onEndReached: (((info: {
|
|
@@ -578,7 +584,7 @@ declare const LegendList: <T>(props: Omit<Omit<react_native.ScrollViewProps, "sc
|
|
|
578
584
|
ListFooterComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
579
585
|
ListHeaderComponent?: React$1.ComponentType<any> | React$1.ReactElement | null | undefined;
|
|
580
586
|
ListHeaderComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
581
|
-
maintainScrollAtEnd?: boolean;
|
|
587
|
+
maintainScrollAtEnd?: boolean | MaintainScrollAtEndOptions;
|
|
582
588
|
maintainScrollAtEndThreshold?: number;
|
|
583
589
|
maintainVisibleContentPosition?: boolean;
|
|
584
590
|
numColumns?: number;
|
|
@@ -646,7 +652,7 @@ declare const LazyLegendList: <ItemT, ListT extends (<T>(props: Omit<Omit<react_
|
|
|
646
652
|
ListFooterComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
647
653
|
ListHeaderComponent?: React$1.ComponentType<any> | React$1.ReactElement | null | undefined;
|
|
648
654
|
ListHeaderComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
649
|
-
maintainScrollAtEnd?: boolean;
|
|
655
|
+
maintainScrollAtEnd?: boolean | MaintainScrollAtEndOptions;
|
|
650
656
|
maintainScrollAtEndThreshold?: number;
|
|
651
657
|
maintainVisibleContentPosition?: boolean;
|
|
652
658
|
numColumns?: number;
|
|
@@ -708,7 +714,7 @@ declare const LazyLegendList: <ItemT, ListT extends (<T>(props: Omit<Omit<react_
|
|
|
708
714
|
ListFooterComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
709
715
|
ListHeaderComponent?: React$1.ComponentType<any> | React$1.ReactElement | null | undefined;
|
|
710
716
|
ListHeaderComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
711
|
-
maintainScrollAtEnd?: boolean;
|
|
717
|
+
maintainScrollAtEnd?: boolean | MaintainScrollAtEndOptions;
|
|
712
718
|
maintainScrollAtEndThreshold?: number;
|
|
713
719
|
maintainVisibleContentPosition?: boolean;
|
|
714
720
|
numColumns?: number;
|
|
@@ -772,7 +778,7 @@ declare const LazyLegendList: <ItemT, ListT extends (<T>(props: Omit<Omit<react_
|
|
|
772
778
|
ListFooterComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
773
779
|
ListHeaderComponent?: React$1.ComponentType<any> | React$1.ReactElement | null | undefined;
|
|
774
780
|
ListHeaderComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
775
|
-
maintainScrollAtEnd?: boolean;
|
|
781
|
+
maintainScrollAtEnd?: boolean | MaintainScrollAtEndOptions;
|
|
776
782
|
maintainScrollAtEndThreshold?: number;
|
|
777
783
|
maintainVisibleContentPosition?: boolean;
|
|
778
784
|
numColumns?: number;
|
|
@@ -818,4 +824,4 @@ declare function useListScrollSize(): {
|
|
|
818
824
|
height: number;
|
|
819
825
|
};
|
|
820
826
|
|
|
821
|
-
export { type ColumnWrapperStyle, type GetRenderedItem, type GetRenderedItemResult, type InternalState, LazyLegendList, type LazyLegendListProps, LegendList, type LegendListProps, type LegendListPropsBase, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type OnViewableItemsChanged, type ScrollIndexWithOffsetPosition, type ScrollState, type TypedForwardRef, type TypedMemo, type ViewAmountToken, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, type ViewableRange, typedForwardRef, typedMemo, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useViewability, useViewabilityAmount };
|
|
827
|
+
export { type ColumnWrapperStyle, type GetRenderedItem, type GetRenderedItemResult, type InternalState, LazyLegendList, type LazyLegendListProps, LegendList, type LegendListProps, type LegendListPropsBase, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type MaintainScrollAtEndOptions, type OnViewableItemsChanged, type ScrollIndexWithOffsetPosition, type ScrollState, type TypedForwardRef, type TypedMemo, type ViewAmountToken, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, type ViewableRange, typedForwardRef, typedMemo, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useViewability, useViewabilityAmount };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React$1 from 'react';
|
|
2
2
|
import { ComponentProps, ReactNode, Dispatch, SetStateAction } from 'react';
|
|
3
3
|
import * as react_native from 'react-native';
|
|
4
|
-
import { View, ScrollView, StyleProp, ViewStyle, ScrollViewProps, NativeSyntheticEvent, NativeScrollEvent, ScrollViewComponent, ScrollResponderMixin } from 'react-native';
|
|
5
|
-
import Animated from 'react-native-reanimated';
|
|
4
|
+
import { View, ScrollView, Animated, StyleProp, ViewStyle, ScrollViewProps, LayoutRectangle, NativeSyntheticEvent, NativeScrollEvent, ScrollViewComponent, ScrollResponderMixin } from 'react-native';
|
|
5
|
+
import Animated$1 from 'react-native-reanimated';
|
|
6
6
|
import * as _legendapp_list_reanimated from '@legendapp/list/reanimated';
|
|
7
7
|
|
|
8
8
|
type ListenerType = "numContainers" | "numContainersPooled" | `containerItemKey${number}` | `containerItemData${number}` | `containerPosition${number}` | `containerColumn${number}` | "containersDidLayout" | "extraData" | "numColumns" | "lastItemKeys" | "totalSize" | "alignItemsPaddingTop" | "stylePaddingTop" | "scrollAdjust" | "scrollAdjustUserOffset" | "headerSize" | "footerSize" | "maintainVisibleContentPosition" | "debugRawScroll" | "debugComputedScroll" | "otherAxisSize" | "scrollSize";
|
|
@@ -26,7 +26,7 @@ declare class ScrollAdjustHandler {
|
|
|
26
26
|
setMounted(): void;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof ScrollView> | ComponentProps<typeof Animated.ScrollView>> = Omit<TScrollView, "contentOffset" | "contentInset" | "maintainVisibleContentPosition" | "stickyHeaderIndices" | "removeClippedSubviews" | "children"> & {
|
|
29
|
+
type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof ScrollView> | ComponentProps<typeof Animated.ScrollView> | ComponentProps<typeof Animated$1.ScrollView>> = Omit<TScrollView, "contentOffset" | "contentInset" | "maintainVisibleContentPosition" | "stickyHeaderIndices" | "removeClippedSubviews" | "children"> & {
|
|
30
30
|
/**
|
|
31
31
|
* If true, aligns items at the end of the list.
|
|
32
32
|
* @default false
|
|
@@ -122,7 +122,7 @@ type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof Scroll
|
|
|
122
122
|
* If true, auto-scrolls to end when new items are added.
|
|
123
123
|
* @default false
|
|
124
124
|
*/
|
|
125
|
-
maintainScrollAtEnd?: boolean;
|
|
125
|
+
maintainScrollAtEnd?: boolean | MaintainScrollAtEndOptions;
|
|
126
126
|
/**
|
|
127
127
|
* Distance threshold in percentage of screen size to trigger maintainScrollAtEnd.
|
|
128
128
|
* @default 0.1
|
|
@@ -233,6 +233,11 @@ type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof Scroll
|
|
|
233
233
|
elapsedTimeInMs: number;
|
|
234
234
|
}) => void;
|
|
235
235
|
};
|
|
236
|
+
interface MaintainScrollAtEndOptions {
|
|
237
|
+
onLayout?: boolean;
|
|
238
|
+
onItemLayout?: boolean;
|
|
239
|
+
onDataChange?: boolean;
|
|
240
|
+
}
|
|
236
241
|
interface ColumnWrapperStyle {
|
|
237
242
|
rowGap?: number;
|
|
238
243
|
gap?: number;
|
|
@@ -309,6 +314,7 @@ interface InternalState {
|
|
|
309
314
|
refScroller: React.RefObject<ScrollView>;
|
|
310
315
|
loadStartTime: number;
|
|
311
316
|
initialScroll: ScrollIndexWithOffsetPosition | undefined;
|
|
317
|
+
lastLayout: LayoutRectangle | undefined;
|
|
312
318
|
props: {
|
|
313
319
|
alignItemsAtEnd: boolean;
|
|
314
320
|
data: readonly any[];
|
|
@@ -316,7 +322,7 @@ interface InternalState {
|
|
|
316
322
|
getEstimatedItemSize: ((index: number, item: any) => number) | undefined;
|
|
317
323
|
horizontal: boolean;
|
|
318
324
|
keyExtractor: ((item: any, index: number) => string) | undefined;
|
|
319
|
-
maintainScrollAtEnd: boolean;
|
|
325
|
+
maintainScrollAtEnd: boolean | MaintainScrollAtEndOptions;
|
|
320
326
|
maintainScrollAtEndThreshold: number | undefined;
|
|
321
327
|
maintainVisibleContentPosition: boolean;
|
|
322
328
|
onEndReached: (((info: {
|
|
@@ -578,7 +584,7 @@ declare const LegendList: <T>(props: Omit<Omit<react_native.ScrollViewProps, "sc
|
|
|
578
584
|
ListFooterComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
579
585
|
ListHeaderComponent?: React$1.ComponentType<any> | React$1.ReactElement | null | undefined;
|
|
580
586
|
ListHeaderComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
581
|
-
maintainScrollAtEnd?: boolean;
|
|
587
|
+
maintainScrollAtEnd?: boolean | MaintainScrollAtEndOptions;
|
|
582
588
|
maintainScrollAtEndThreshold?: number;
|
|
583
589
|
maintainVisibleContentPosition?: boolean;
|
|
584
590
|
numColumns?: number;
|
|
@@ -646,7 +652,7 @@ declare const LazyLegendList: <ItemT, ListT extends (<T>(props: Omit<Omit<react_
|
|
|
646
652
|
ListFooterComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
647
653
|
ListHeaderComponent?: React$1.ComponentType<any> | React$1.ReactElement | null | undefined;
|
|
648
654
|
ListHeaderComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
649
|
-
maintainScrollAtEnd?: boolean;
|
|
655
|
+
maintainScrollAtEnd?: boolean | MaintainScrollAtEndOptions;
|
|
650
656
|
maintainScrollAtEndThreshold?: number;
|
|
651
657
|
maintainVisibleContentPosition?: boolean;
|
|
652
658
|
numColumns?: number;
|
|
@@ -708,7 +714,7 @@ declare const LazyLegendList: <ItemT, ListT extends (<T>(props: Omit<Omit<react_
|
|
|
708
714
|
ListFooterComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
709
715
|
ListHeaderComponent?: React$1.ComponentType<any> | React$1.ReactElement | null | undefined;
|
|
710
716
|
ListHeaderComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
711
|
-
maintainScrollAtEnd?: boolean;
|
|
717
|
+
maintainScrollAtEnd?: boolean | MaintainScrollAtEndOptions;
|
|
712
718
|
maintainScrollAtEndThreshold?: number;
|
|
713
719
|
maintainVisibleContentPosition?: boolean;
|
|
714
720
|
numColumns?: number;
|
|
@@ -772,7 +778,7 @@ declare const LazyLegendList: <ItemT, ListT extends (<T>(props: Omit<Omit<react_
|
|
|
772
778
|
ListFooterComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
773
779
|
ListHeaderComponent?: React$1.ComponentType<any> | React$1.ReactElement | null | undefined;
|
|
774
780
|
ListHeaderComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
775
|
-
maintainScrollAtEnd?: boolean;
|
|
781
|
+
maintainScrollAtEnd?: boolean | MaintainScrollAtEndOptions;
|
|
776
782
|
maintainScrollAtEndThreshold?: number;
|
|
777
783
|
maintainVisibleContentPosition?: boolean;
|
|
778
784
|
numColumns?: number;
|
|
@@ -818,4 +824,4 @@ declare function useListScrollSize(): {
|
|
|
818
824
|
height: number;
|
|
819
825
|
};
|
|
820
826
|
|
|
821
|
-
export { type ColumnWrapperStyle, type GetRenderedItem, type GetRenderedItemResult, type InternalState, LazyLegendList, type LazyLegendListProps, LegendList, type LegendListProps, type LegendListPropsBase, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type OnViewableItemsChanged, type ScrollIndexWithOffsetPosition, type ScrollState, type TypedForwardRef, type TypedMemo, type ViewAmountToken, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, type ViewableRange, typedForwardRef, typedMemo, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useViewability, useViewabilityAmount };
|
|
827
|
+
export { type ColumnWrapperStyle, type GetRenderedItem, type GetRenderedItemResult, type InternalState, LazyLegendList, type LazyLegendListProps, LegendList, type LegendListProps, type LegendListPropsBase, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type MaintainScrollAtEndOptions, type OnViewableItemsChanged, type ScrollIndexWithOffsetPosition, type ScrollState, type TypedForwardRef, type TypedMemo, type ViewAmountToken, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, type ViewableRange, typedForwardRef, typedMemo, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useViewability, useViewabilityAmount };
|
|
@@ -932,26 +932,27 @@ function requestAdjust(ctx, state, positionDiff) {
|
|
|
932
932
|
};
|
|
933
933
|
state.scroll += positionDiff;
|
|
934
934
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
935
|
-
|
|
935
|
+
const didLayout = peek$(ctx, "containersDidLayout");
|
|
936
|
+
if (didLayout) {
|
|
936
937
|
doit();
|
|
938
|
+
const threshold = state.scroll - positionDiff / 2;
|
|
939
|
+
if (!state.ignoreScrollFromMVCP) {
|
|
940
|
+
state.ignoreScrollFromMVCP = {};
|
|
941
|
+
}
|
|
942
|
+
if (positionDiff > 0) {
|
|
943
|
+
state.ignoreScrollFromMVCP.lt = threshold;
|
|
944
|
+
} else {
|
|
945
|
+
state.ignoreScrollFromMVCP.gt = threshold;
|
|
946
|
+
}
|
|
947
|
+
if (state.ignoreScrollFromMVCPTimeout) {
|
|
948
|
+
clearTimeout(state.ignoreScrollFromMVCPTimeout);
|
|
949
|
+
}
|
|
950
|
+
state.ignoreScrollFromMVCPTimeout = setTimeout(() => {
|
|
951
|
+
state.ignoreScrollFromMVCP = void 0;
|
|
952
|
+
}, 100);
|
|
937
953
|
} else {
|
|
938
954
|
requestAnimationFrame(doit);
|
|
939
955
|
}
|
|
940
|
-
const threshold = state.scroll - positionDiff / 2;
|
|
941
|
-
if (!state.ignoreScrollFromMVCP) {
|
|
942
|
-
state.ignoreScrollFromMVCP = {};
|
|
943
|
-
}
|
|
944
|
-
if (positionDiff > 0) {
|
|
945
|
-
state.ignoreScrollFromMVCP.lt = threshold;
|
|
946
|
-
} else {
|
|
947
|
-
state.ignoreScrollFromMVCP.gt = threshold;
|
|
948
|
-
}
|
|
949
|
-
if (state.ignoreScrollFromMVCPTimeout) {
|
|
950
|
-
clearTimeout(state.ignoreScrollFromMVCPTimeout);
|
|
951
|
-
}
|
|
952
|
-
state.ignoreScrollFromMVCPTimeout = setTimeout(() => {
|
|
953
|
-
state.ignoreScrollFromMVCP = void 0;
|
|
954
|
-
}, 100);
|
|
955
956
|
}
|
|
956
957
|
}
|
|
957
958
|
|
|
@@ -1845,9 +1846,12 @@ function getRenderedItem(ctx, state, key) {
|
|
|
1845
1846
|
}
|
|
1846
1847
|
|
|
1847
1848
|
// src/handleLayout.ts
|
|
1848
|
-
function handleLayout(ctx, state,
|
|
1849
|
-
const
|
|
1850
|
-
const
|
|
1849
|
+
function handleLayout(ctx, state, layout, setCanRender) {
|
|
1850
|
+
const { maintainScrollAtEnd } = state.props;
|
|
1851
|
+
const scrollLength = layout[state.props.horizontal ? "width" : "height"];
|
|
1852
|
+
const otherAxisSize = layout[state.props.horizontal ? "height" : "width"];
|
|
1853
|
+
const needsCalculate = !state.lastLayout || scrollLength > state.scrollLength || state.lastLayout.x !== layout.x || state.lastLayout.y !== layout.y;
|
|
1854
|
+
state.lastLayout = layout;
|
|
1851
1855
|
const didChange = scrollLength !== state.scrollLength;
|
|
1852
1856
|
const prevOtherAxisSize = state.otherAxisSize;
|
|
1853
1857
|
state.scrollLength = scrollLength;
|
|
@@ -1855,13 +1859,15 @@ function handleLayout(ctx, state, size, setCanRender) {
|
|
|
1855
1859
|
state.lastBatchingAction = Date.now();
|
|
1856
1860
|
state.scrollForNextCalculateItemsInView = void 0;
|
|
1857
1861
|
doInitialAllocateContainers(ctx, state);
|
|
1858
|
-
if (
|
|
1862
|
+
if (needsCalculate) {
|
|
1859
1863
|
calculateItemsInView(ctx, state, { doMVCP: true });
|
|
1860
1864
|
}
|
|
1861
1865
|
if (didChange || otherAxisSize !== prevOtherAxisSize) {
|
|
1862
|
-
set$(ctx, "scrollSize", { width:
|
|
1866
|
+
set$(ctx, "scrollSize", { width: layout.width, height: layout.height });
|
|
1867
|
+
}
|
|
1868
|
+
if (maintainScrollAtEnd === true || maintainScrollAtEnd.onLayout) {
|
|
1869
|
+
doMaintainScrollAtEnd(ctx, state, false);
|
|
1863
1870
|
}
|
|
1864
|
-
doMaintainScrollAtEnd(ctx, state, false);
|
|
1865
1871
|
updateAlignItemsPaddingTop(ctx, state);
|
|
1866
1872
|
checkAtBottom(ctx, state);
|
|
1867
1873
|
checkAtTop(state);
|
|
@@ -1874,7 +1880,6 @@ function handleLayout(ctx, state, size, setCanRender) {
|
|
|
1874
1880
|
`List ${state.props.horizontal ? "width" : "height"} is 0. You may need to set a style or \`flex: \` for the list, because children are absolutely positioned.`
|
|
1875
1881
|
);
|
|
1876
1882
|
}
|
|
1877
|
-
calculateItemsInView(ctx, state, { doMVCP: true });
|
|
1878
1883
|
setCanRender(true);
|
|
1879
1884
|
}
|
|
1880
1885
|
|
|
@@ -1920,7 +1925,14 @@ function updateScroll(ctx, state, newScroll) {
|
|
|
1920
1925
|
function updateItemSizes(ctx, state, itemUpdates) {
|
|
1921
1926
|
var _a;
|
|
1922
1927
|
const {
|
|
1923
|
-
props: {
|
|
1928
|
+
props: {
|
|
1929
|
+
horizontal,
|
|
1930
|
+
maintainVisibleContentPosition,
|
|
1931
|
+
suggestEstimatedItemSize,
|
|
1932
|
+
onItemSizeChanged,
|
|
1933
|
+
data,
|
|
1934
|
+
maintainScrollAtEnd
|
|
1935
|
+
}
|
|
1924
1936
|
} = state;
|
|
1925
1937
|
if (!data) return;
|
|
1926
1938
|
let needsRecalculate = false;
|
|
@@ -1990,12 +2002,13 @@ function updateItemSizes(ctx, state, itemUpdates) {
|
|
|
1990
2002
|
calculateItemsInView(ctx, state, { doMVCP: true });
|
|
1991
2003
|
}
|
|
1992
2004
|
if (shouldMaintainScrollAtEnd) {
|
|
1993
|
-
|
|
2005
|
+
if (maintainScrollAtEnd === true || maintainScrollAtEnd.onItemLayout) {
|
|
2006
|
+
doMaintainScrollAtEnd(ctx, state, false);
|
|
2007
|
+
}
|
|
1994
2008
|
}
|
|
1995
2009
|
}
|
|
1996
2010
|
}
|
|
1997
2011
|
function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
1998
|
-
var _a, _b;
|
|
1999
2012
|
if (IsNewArchitecture) {
|
|
2000
2013
|
const { sizesKnown } = state;
|
|
2001
2014
|
const numContainers = ctx.values.get("numContainers");
|
|
@@ -2006,8 +2019,11 @@ function updateItemSize(ctx, state, itemKey, sizeObj) {
|
|
|
2006
2019
|
changes.push({ itemKey, sizeObj });
|
|
2007
2020
|
} else if (!sizesKnown.has(containerItemKey) && containerItemKey !== void 0) {
|
|
2008
2021
|
const containerRef = ctx.viewRefs.get(i);
|
|
2009
|
-
if (containerRef) {
|
|
2010
|
-
|
|
2022
|
+
if (containerRef == null ? void 0 : containerRef.current) {
|
|
2023
|
+
let measured;
|
|
2024
|
+
containerRef.current.measure((x, y, width, height) => {
|
|
2025
|
+
measured = { x, y, width, height };
|
|
2026
|
+
});
|
|
2011
2027
|
if (measured) {
|
|
2012
2028
|
changes.push({ itemKey: containerItemKey, sizeObj: measured });
|
|
2013
2029
|
}
|
|
@@ -2177,7 +2193,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2177
2193
|
props: {},
|
|
2178
2194
|
refScroller: void 0,
|
|
2179
2195
|
loadStartTime: Date.now(),
|
|
2180
|
-
initialScroll
|
|
2196
|
+
initialScroll,
|
|
2197
|
+
lastLayout: void 0
|
|
2181
2198
|
};
|
|
2182
2199
|
set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
|
|
2183
2200
|
set$(ctx, "extraData", extraData);
|
|
@@ -2219,7 +2236,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2219
2236
|
state2.props.data = dataProp;
|
|
2220
2237
|
if (!isFirst2) {
|
|
2221
2238
|
calculateItemsInView(ctx, state2, { dataChanged: true, doMVCP: true });
|
|
2222
|
-
const
|
|
2239
|
+
const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
|
|
2240
|
+
const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, state2, false);
|
|
2223
2241
|
if (!didMaintainScrollAtEnd && dataProp.length > state2.props.data.length) {
|
|
2224
2242
|
state2.isEndReached = false;
|
|
2225
2243
|
}
|
|
@@ -2273,9 +2291,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2273
2291
|
}
|
|
2274
2292
|
}
|
|
2275
2293
|
React3.useLayoutEffect(() => {
|
|
2276
|
-
var _a2, _b;
|
|
2277
2294
|
if (IsNewArchitecture) {
|
|
2278
|
-
|
|
2295
|
+
let measured;
|
|
2296
|
+
refScroller.current.measure((x, y, width, height) => {
|
|
2297
|
+
measured = { x, y, width, height };
|
|
2298
|
+
});
|
|
2279
2299
|
if (measured) {
|
|
2280
2300
|
const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
|
|
2281
2301
|
if (size) {
|