@legendapp/list 2.0.0-next.2 → 2.0.0-next.20
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/{dist/animated.d.mts → animated.d.mts} +7 -2
- package/{dist/animated.d.ts → animated.d.ts} +7 -2
- package/{dist/animated.js → animated.js} +2 -2
- package/{dist/animated.mjs → animated.mjs} +2 -2
- package/{dist/index.d.mts → index.d.mts} +106 -56
- package/{dist/index.d.ts → index.d.ts} +106 -56
- package/{dist/index.js → index.js} +1589 -1095
- package/{dist/index.mjs → index.mjs} +1591 -1097
- package/{dist/keyboard-controller.d.mts → keyboard-controller.d.mts} +28 -8
- package/{dist/keyboard-controller.d.ts → keyboard-controller.d.ts} +28 -8
- package/{dist/keyboard-controller.js → keyboard-controller.js} +4 -4
- package/{dist/keyboard-controller.mjs → keyboard-controller.mjs} +4 -4
- package/package.json +34 -88
- package/{dist/reanimated.d.mts → reanimated.d.mts} +2 -2
- package/{dist/reanimated.d.ts → reanimated.d.ts} +2 -2
- package/{dist/reanimated.js → reanimated.js} +7 -7
- package/{dist/reanimated.mjs → reanimated.mjs} +7 -7
- package/.claude/settings.local.json +0 -8
- package/.cursor/rules/changelog.mdc +0 -60
- package/.github/FUNDING.yml +0 -15
- package/.gitignore +0 -5
- package/.prettierrc.json +0 -5
- package/.vscode/settings.json +0 -14
- package/CLAUDE.md +0 -126
- package/biome.json +0 -46
- package/bun.lock +0 -1289
- package/bunfig.toml +0 -2
- package/dist/CHANGELOG.md +0 -119
- package/dist/LICENSE +0 -21
- package/dist/README.md +0 -139
- package/dist/package.json +0 -35
- package/example/README.md +0 -40
- package/example/api/data/genres.json +0 -23
- package/example/api/data/playlist/10402-10749.json +0 -1
- package/example/api/data/playlist/10402-10770.json +0 -1
- package/example/api/data/playlist/10402-37.json +0 -1
- package/example/api/data/playlist/10749-10752.json +0 -1
- package/example/api/data/playlist/10749-10770.json +0 -1
- package/example/api/data/playlist/10749-37.json +0 -1
- package/example/api/data/playlist/10749-878.json +0 -1
- package/example/api/data/playlist/10751-10402.json +0 -1
- package/example/api/data/playlist/10751-10752.json +0 -1
- package/example/api/data/playlist/10751-37.json +0 -1
- package/example/api/data/playlist/10751-53.json +0 -1
- package/example/api/data/playlist/10751-878.json +0 -1
- package/example/api/data/playlist/10751-9648.json +0 -1
- package/example/api/data/playlist/10752-37.json +0 -1
- package/example/api/data/playlist/12-10402.json +0 -1
- package/example/api/data/playlist/12-10749.json +0 -1
- package/example/api/data/playlist/12-18.json +0 -1
- package/example/api/data/playlist/12-27.json +0 -1
- package/example/api/data/playlist/12-35.json +0 -1
- package/example/api/data/playlist/14-36.json +0 -1
- package/example/api/data/playlist/14-878.json +0 -1
- package/example/api/data/playlist/16-10751.json +0 -1
- package/example/api/data/playlist/16-10770.json +0 -1
- package/example/api/data/playlist/16-35.json +0 -1
- package/example/api/data/playlist/16-36.json +0 -1
- package/example/api/data/playlist/16-53.json +0 -1
- package/example/api/data/playlist/18-10751.json +0 -1
- package/example/api/data/playlist/18-10752.json +0 -1
- package/example/api/data/playlist/18-37.json +0 -1
- package/example/api/data/playlist/18-53.json +0 -1
- package/example/api/data/playlist/18-878.json +0 -1
- package/example/api/data/playlist/27-10749.json +0 -1
- package/example/api/data/playlist/27-10770.json +0 -1
- package/example/api/data/playlist/28-10749.json +0 -1
- package/example/api/data/playlist/28-10751.json +0 -1
- package/example/api/data/playlist/28-10770.json +0 -1
- package/example/api/data/playlist/28-16.json +0 -1
- package/example/api/data/playlist/28-18.json +0 -1
- package/example/api/data/playlist/28-36.json +0 -1
- package/example/api/data/playlist/28-37.json +0 -1
- package/example/api/data/playlist/28-53.json +0 -1
- package/example/api/data/playlist/28-80.json +0 -1
- package/example/api/data/playlist/28-99.json +0 -1
- package/example/api/data/playlist/35-10749.json +0 -1
- package/example/api/data/playlist/35-10751.json +0 -1
- package/example/api/data/playlist/35-10752.json +0 -1
- package/example/api/data/playlist/35-27.json +0 -1
- package/example/api/data/playlist/35-36.json +0 -1
- package/example/api/data/playlist/35-53.json +0 -1
- package/example/api/data/playlist/35-80.json +0 -1
- package/example/api/data/playlist/36-37.json +0 -1
- package/example/api/data/playlist/36-878.json +0 -1
- package/example/api/data/playlist/36-9648.json +0 -1
- package/example/api/data/playlist/53-10752.json +0 -1
- package/example/api/data/playlist/80-10770.json +0 -1
- package/example/api/data/playlist/80-14.json +0 -1
- package/example/api/data/playlist/80-18.json +0 -1
- package/example/api/data/playlist/80-37.json +0 -1
- package/example/api/data/playlist/878-37.json +0 -1
- package/example/api/data/playlist/9648-10770.json +0 -1
- package/example/api/data/playlist/9648-37.json +0 -1
- package/example/api/data/playlist/9648-53.json +0 -1
- package/example/api/data/playlist/9648-878.json +0 -1
- package/example/api/data/playlist/99-10749.json +0 -1
- package/example/api/data/playlist/99-14.json +0 -1
- package/example/api/data/playlist/99-18.json +0 -1
- package/example/api/data/playlist/99-27.json +0 -1
- package/example/api/data/playlist/99-53.json +0 -1
- package/example/api/data/playlist/99-9648.json +0 -1
- package/example/api/data/playlist/index.ts +0 -73
- package/example/api/data/rows.json +0 -1
- package/example/api/index.ts +0 -36
- package/example/app/(tabs)/_layout.tsx +0 -60
- package/example/app/(tabs)/cards.tsx +0 -81
- package/example/app/(tabs)/index.tsx +0 -205
- package/example/app/(tabs)/moviesL.tsx +0 -7
- package/example/app/(tabs)/moviesLR.tsx +0 -7
- package/example/app/+not-found.tsx +0 -32
- package/example/app/_layout.tsx +0 -34
- package/example/app/accurate-scrollto/index.tsx +0 -125
- package/example/app/accurate-scrollto-2/index.tsx +0 -52
- package/example/app/accurate-scrollto-huge/index.tsx +0 -128
- package/example/app/add-to-end/index.tsx +0 -82
- package/example/app/ai-chat/index.tsx +0 -236
- package/example/app/bidirectional-infinite-list/index.tsx +0 -133
- package/example/app/cards-columns/index.tsx +0 -37
- package/example/app/cards-flashlist/index.tsx +0 -122
- package/example/app/cards-flatlist/index.tsx +0 -94
- package/example/app/cards-no-recycle/index.tsx +0 -110
- package/example/app/cards-renderItem.tsx +0 -354
- package/example/app/chat-example/index.tsx +0 -167
- package/example/app/chat-infinite/index.tsx +0 -239
- package/example/app/chat-keyboard/index.tsx +0 -248
- package/example/app/chat-resize-outer/index.tsx +0 -247
- package/example/app/columns/index.tsx +0 -78
- package/example/app/countries/index.tsx +0 -182
- package/example/app/countries-flashlist/index.tsx +0 -163
- package/example/app/countries-reorder/index.tsx +0 -187
- package/example/app/extra-data/index.tsx +0 -86
- package/example/app/filter-elements/filter-data-provider.tsx +0 -55
- package/example/app/filter-elements/index.tsx +0 -118
- package/example/app/initial-scroll-index/index.tsx +0 -106
- package/example/app/initial-scroll-index/renderFixedItem.tsx +0 -215
- package/example/app/initial-scroll-index-free-height/index.tsx +0 -70
- package/example/app/initial-scroll-index-keyed/index.tsx +0 -62
- package/example/app/lazy-list/index.tsx +0 -123
- package/example/app/movies-flashlist/index.tsx +0 -7
- package/example/app/mutable-cells/index.tsx +0 -104
- package/example/app/video-feed/index.tsx +0 -119
- package/example/app.config.js +0 -22
- package/example/app.json +0 -45
- 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 +0 -101
- package/example/bun.lock +0 -2266
- package/example/bunfig.toml +0 -2
- package/example/components/Breathe.tsx +0 -54
- package/example/components/Circle.tsx +0 -69
- package/example/components/Collapsible.tsx +0 -44
- package/example/components/ExternalLink.tsx +0 -24
- package/example/components/HapticTab.tsx +0 -18
- package/example/components/HelloWave.tsx +0 -37
- package/example/components/Movies.tsx +0 -179
- package/example/components/ParallaxScrollView.tsx +0 -81
- package/example/components/ThemedText.tsx +0 -60
- package/example/components/ThemedView.tsx +0 -14
- package/example/components/__tests__/ThemedText-test.tsx +0 -10
- package/example/components/__tests__/__snapshots__/ThemedText-test.tsx.snap +0 -24
- package/example/components/ui/IconSymbol.ios.tsx +0 -32
- package/example/components/ui/IconSymbol.tsx +0 -43
- package/example/components/ui/TabBarBackground.ios.tsx +0 -22
- package/example/components/ui/TabBarBackground.tsx +0 -6
- package/example/constants/Colors.ts +0 -26
- package/example/constants/constants.ts +0 -5
- package/example/constants/useScrollTest.ts +0 -19
- package/example/hooks/useColorScheme.ts +0 -1
- package/example/hooks/useColorScheme.web.ts +0 -8
- package/example/hooks/useThemeColor.ts +0 -22
- package/example/ios/.xcode.env +0 -11
- package/example/ios/Podfile +0 -64
- package/example/ios/Podfile.lock +0 -2767
- package/example/ios/Podfile.properties.json +0 -5
- package/example/ios/listtest/AppDelegate.swift +0 -70
- 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 +0 -14
- package/example/ios/listtest/Images.xcassets/Contents.json +0 -6
- package/example/ios/listtest/Images.xcassets/SplashScreenBackground.colorset/Contents.json +0 -20
- package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/Contents.json +0 -23
- 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 +0 -85
- package/example/ios/listtest/PrivacyInfo.xcprivacy +0 -48
- package/example/ios/listtest/SplashScreen.storyboard +0 -42
- package/example/ios/listtest/Supporting/Expo.plist +0 -12
- package/example/ios/listtest/listtest-Bridging-Header.h +0 -3
- package/example/ios/listtest/listtest.entitlements +0 -5
- package/example/ios/listtest.xcodeproj/project.pbxproj +0 -547
- package/example/ios/listtest.xcodeproj/xcshareddata/xcschemes/listtest.xcscheme +0 -88
- package/example/ios/listtest.xcworkspace/contents.xcworkspacedata +0 -10
- package/example/metro.config.js +0 -16
- package/example/package.json +0 -73
- package/example/scripts/reset-project.js +0 -84
- package/example/tsconfig.json +0 -26
- package/posttsup.ts +0 -24
- package/src/Container.tsx +0 -176
- package/src/Containers.tsx +0 -85
- package/src/ContextContainer.ts +0 -145
- package/src/DebugView.tsx +0 -83
- package/src/LazyLegendList.tsx +0 -41
- package/src/LeanView.tsx +0 -18
- package/src/LegendList.tsx +0 -558
- package/src/ListComponent.tsx +0 -191
- package/src/ScrollAdjust.tsx +0 -24
- package/src/ScrollAdjustHandler.ts +0 -26
- package/src/Separator.tsx +0 -14
- package/src/animated.tsx +0 -6
- package/src/calculateItemsInView.ts +0 -363
- package/src/calculateOffsetForIndex.ts +0 -23
- package/src/calculateOffsetWithOffsetPosition.ts +0 -26
- package/src/checkAllSizesKnown.ts +0 -17
- package/src/checkAtBottom.ts +0 -36
- package/src/checkAtTop.ts +0 -27
- package/src/checkThreshold.ts +0 -30
- package/src/constants.ts +0 -11
- package/src/createColumnWrapperStyle.ts +0 -16
- package/src/doInitialAllocateContainers.ts +0 -40
- package/src/doMaintainScrollAtEnd.ts +0 -34
- package/src/findAvailableContainers.ts +0 -98
- package/src/finishScrollTo.ts +0 -8
- package/src/getId.ts +0 -21
- package/src/getItemSize.ts +0 -52
- package/src/getRenderedItem.ts +0 -34
- package/src/getScrollVelocity.ts +0 -47
- package/src/handleLayout.ts +0 -70
- package/src/helpers.ts +0 -39
- package/src/index.ts +0 -11
- package/src/keyboard-controller.tsx +0 -63
- package/src/onScroll.ts +0 -66
- package/src/prepareMVCP.ts +0 -50
- package/src/reanimated.tsx +0 -63
- package/src/requestAdjust.ts +0 -41
- package/src/scrollTo.ts +0 -40
- package/src/scrollToIndex.ts +0 -34
- package/src/setDidLayout.ts +0 -25
- package/src/setPaddingTop.ts +0 -28
- package/src/state.tsx +0 -304
- package/src/types.ts +0 -610
- package/src/updateAlignItemsPaddingTop.ts +0 -18
- package/src/updateAllPositions.ts +0 -130
- package/src/updateItemSize.ts +0 -203
- package/src/updateTotalSize.ts +0 -44
- package/src/useAnimatedValue.ts +0 -6
- package/src/useCombinedRef.ts +0 -22
- package/src/useInit.ts +0 -17
- package/src/useSyncLayout.tsx +0 -68
- package/src/useValue$.ts +0 -53
- package/src/viewability.ts +0 -279
- package/tsconfig.json +0 -59
- package/tsup.config.ts +0 -21
package/src/checkAtBottom.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { checkThreshold } from "./checkThreshold";
|
|
2
|
-
import { getContentSize } from "./state";
|
|
3
|
-
import type { StateContext } from "./state";
|
|
4
|
-
import type { InternalState } from "./types";
|
|
5
|
-
|
|
6
|
-
export function checkAtBottom(ctx: StateContext, state: InternalState) {
|
|
7
|
-
if (!state) {
|
|
8
|
-
return;
|
|
9
|
-
}
|
|
10
|
-
const {
|
|
11
|
-
queuedInitialLayout,
|
|
12
|
-
scrollLength,
|
|
13
|
-
scroll,
|
|
14
|
-
maintainingScrollAtEnd,
|
|
15
|
-
props: { maintainScrollAtEndThreshold, onEndReachedThreshold },
|
|
16
|
-
} = state;
|
|
17
|
-
const contentSize = getContentSize(ctx);
|
|
18
|
-
if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
|
|
19
|
-
// Check if at end
|
|
20
|
-
const distanceFromEnd = contentSize - scroll - scrollLength;
|
|
21
|
-
const isContentLess = contentSize < scrollLength;
|
|
22
|
-
state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold!;
|
|
23
|
-
|
|
24
|
-
state.isEndReached = checkThreshold(
|
|
25
|
-
distanceFromEnd,
|
|
26
|
-
isContentLess,
|
|
27
|
-
onEndReachedThreshold! * scrollLength,
|
|
28
|
-
state.isEndReached,
|
|
29
|
-
state.endReachedBlockedByTimer,
|
|
30
|
-
(distance) => state.props.onEndReached?.({ distanceFromEnd: distance }),
|
|
31
|
-
(block) => {
|
|
32
|
-
state.endReachedBlockedByTimer = block;
|
|
33
|
-
},
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
}
|
package/src/checkAtTop.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { checkThreshold } from "./checkThreshold";
|
|
2
|
-
import type { InternalState } from "./types";
|
|
3
|
-
|
|
4
|
-
export function checkAtTop(state: InternalState) {
|
|
5
|
-
if (!state) {
|
|
6
|
-
return;
|
|
7
|
-
}
|
|
8
|
-
const {
|
|
9
|
-
scrollLength,
|
|
10
|
-
scroll,
|
|
11
|
-
props: { onStartReachedThreshold },
|
|
12
|
-
} = state;
|
|
13
|
-
const distanceFromTop = scroll;
|
|
14
|
-
state.isAtStart = distanceFromTop <= 0;
|
|
15
|
-
|
|
16
|
-
state.isStartReached = checkThreshold(
|
|
17
|
-
distanceFromTop,
|
|
18
|
-
false,
|
|
19
|
-
onStartReachedThreshold! * scrollLength,
|
|
20
|
-
state.isStartReached,
|
|
21
|
-
state.startReachedBlockedByTimer,
|
|
22
|
-
(distance) => state.props.onStartReached?.({ distanceFromStart: distance }),
|
|
23
|
-
(block) => {
|
|
24
|
-
state.startReachedBlockedByTimer = block;
|
|
25
|
-
},
|
|
26
|
-
);
|
|
27
|
-
}
|
package/src/checkThreshold.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
export const checkThreshold = (
|
|
2
|
-
distance: number,
|
|
3
|
-
atThreshold: boolean,
|
|
4
|
-
threshold: number,
|
|
5
|
-
isReached: boolean,
|
|
6
|
-
isBlockedByTimer: boolean,
|
|
7
|
-
onReached?: (distance: number) => void,
|
|
8
|
-
blockTimer?: (block: boolean) => void,
|
|
9
|
-
) => {
|
|
10
|
-
const distanceAbs = Math.abs(distance);
|
|
11
|
-
const isAtThreshold = atThreshold || distanceAbs < threshold;
|
|
12
|
-
|
|
13
|
-
if (!isReached && !isBlockedByTimer) {
|
|
14
|
-
if (isAtThreshold) {
|
|
15
|
-
onReached?.(distance);
|
|
16
|
-
blockTimer?.(true);
|
|
17
|
-
setTimeout(() => {
|
|
18
|
-
blockTimer?.(false);
|
|
19
|
-
}, 700);
|
|
20
|
-
return true;
|
|
21
|
-
}
|
|
22
|
-
} else {
|
|
23
|
-
// reset flag when user scrolls back out of the threshold
|
|
24
|
-
// add hysteresis to avoid multiple events triggered
|
|
25
|
-
if (distance >= 1.3 * threshold) {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return isReached;
|
|
30
|
-
};
|
package/src/constants.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export const POSITION_OUT_OF_VIEW = -10000000;
|
|
2
|
-
|
|
3
|
-
// use colorful overlays to visualize the padding and scroll adjustments
|
|
4
|
-
// green means paddingTop (used for aligning elements at the bottom)
|
|
5
|
-
// lightblue means scrollAdjust (used for maintainVisibleContentPosition) positive values
|
|
6
|
-
// blue arrow at the rights means negative scrollAdjust (used for maintainVisibleContentPosition) negative values
|
|
7
|
-
export const ENABLE_DEVMODE = __DEV__ && false;
|
|
8
|
-
export const ENABLE_DEBUG_VIEW = __DEV__ && false;
|
|
9
|
-
|
|
10
|
-
// @ts-expect-error nativeFabricUIManager is not defined in the global object types
|
|
11
|
-
export const IsNewArchitecture = global.nativeFabricUIManager != null;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { ViewStyle } from "react-native";
|
|
2
|
-
import type { ColumnWrapperStyle } from "./types";
|
|
3
|
-
|
|
4
|
-
export function createColumnWrapperStyle(contentContainerStyle: ViewStyle): ColumnWrapperStyle | undefined {
|
|
5
|
-
const { gap, columnGap, rowGap } = contentContainerStyle;
|
|
6
|
-
if (gap || columnGap || rowGap) {
|
|
7
|
-
contentContainerStyle.gap = undefined;
|
|
8
|
-
contentContainerStyle.columnGap = undefined;
|
|
9
|
-
contentContainerStyle.rowGap = undefined;
|
|
10
|
-
return {
|
|
11
|
-
gap: gap as number,
|
|
12
|
-
columnGap: columnGap as number,
|
|
13
|
-
rowGap: rowGap as number,
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { calculateItemsInView } from "./calculateItemsInView";
|
|
2
|
-
import { IsNewArchitecture, POSITION_OUT_OF_VIEW } from "./constants";
|
|
3
|
-
import { type StateContext, peek$, set$ } from "./state";
|
|
4
|
-
import type { InternalState } from "./types";
|
|
5
|
-
|
|
6
|
-
export function doInitialAllocateContainers(ctx: StateContext, state: InternalState): boolean | undefined {
|
|
7
|
-
// Allocate containers
|
|
8
|
-
const { scrollLength } = state;
|
|
9
|
-
const data = state.props.data;
|
|
10
|
-
if (scrollLength > 0 && data.length > 0 && !peek$(ctx, "numContainers")) {
|
|
11
|
-
const averageItemSize = state.props.getEstimatedItemSize
|
|
12
|
-
? state.props.getEstimatedItemSize(0, data[0])
|
|
13
|
-
: state.props.estimatedItemSize;
|
|
14
|
-
const Extra = 1.5; // TODO make it a prop, experiment with whether it's faster with more containers
|
|
15
|
-
const numContainers = Math.ceil(
|
|
16
|
-
((scrollLength + state.props.scrollBuffer * 2) / averageItemSize!) * state.props.numColumns * Extra,
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
for (let i = 0; i < numContainers; i++) {
|
|
20
|
-
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
21
|
-
set$(ctx, `containerColumn${i}`, -1);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
set$(ctx, "numContainers", numContainers);
|
|
25
|
-
set$(ctx, "numContainersPooled", numContainers * state.props.initialContainerPoolRatio);
|
|
26
|
-
|
|
27
|
-
if (!IsNewArchitecture) {
|
|
28
|
-
if (state.props.initialScroll) {
|
|
29
|
-
requestAnimationFrame(() => {
|
|
30
|
-
// immediate render causes issues with initial index position
|
|
31
|
-
calculateItemsInView(ctx, state);
|
|
32
|
-
});
|
|
33
|
-
} else {
|
|
34
|
-
calculateItemsInView(ctx, state);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { peek$ } from "./state";
|
|
2
|
-
import type { StateContext } from "./state";
|
|
3
|
-
import type { InternalState } from "./types";
|
|
4
|
-
|
|
5
|
-
export function doMaintainScrollAtEnd(ctx: StateContext, state: InternalState, animated: boolean) {
|
|
6
|
-
const {
|
|
7
|
-
refScroller,
|
|
8
|
-
props: { maintainScrollAtEnd },
|
|
9
|
-
} = state;
|
|
10
|
-
// Run this only if scroll is at the bottom and after initial layout
|
|
11
|
-
if (state?.isAtEnd && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
|
|
12
|
-
// Set scroll to the bottom of the list so that checkAtTop/checkAtBottom is correct
|
|
13
|
-
const paddingTop = peek$(ctx, "alignItemsPaddingTop");
|
|
14
|
-
if (paddingTop > 0) {
|
|
15
|
-
// if paddingTop exists, list is shorter then a screen, so scroll should be 0 anyways
|
|
16
|
-
state.scroll = 0;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
requestAnimationFrame(() => {
|
|
20
|
-
state.maintainingScrollAtEnd = true;
|
|
21
|
-
refScroller.current?.scrollToEnd({
|
|
22
|
-
animated,
|
|
23
|
-
});
|
|
24
|
-
setTimeout(
|
|
25
|
-
() => {
|
|
26
|
-
state.maintainingScrollAtEnd = false;
|
|
27
|
-
},
|
|
28
|
-
animated ? 500 : 0,
|
|
29
|
-
);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
return true;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { comparatorDefault } from "./helpers";
|
|
2
|
-
import { type StateContext, peek$ } from "./state";
|
|
3
|
-
import type { InternalState } from "./types";
|
|
4
|
-
|
|
5
|
-
export function findAvailableContainers(
|
|
6
|
-
ctx: StateContext,
|
|
7
|
-
state: InternalState,
|
|
8
|
-
numNeeded: number,
|
|
9
|
-
startBuffered: number,
|
|
10
|
-
endBuffered: number,
|
|
11
|
-
pendingRemoval: number[],
|
|
12
|
-
): number[] {
|
|
13
|
-
const numContainers = peek$(ctx, "numContainers") as number;
|
|
14
|
-
|
|
15
|
-
const result: number[] = [];
|
|
16
|
-
const availableContainers: Array<{ index: number; distance: number }> = [];
|
|
17
|
-
|
|
18
|
-
// First pass: collect unallocated containers (most efficient to use)
|
|
19
|
-
for (let u = 0; u < numContainers; u++) {
|
|
20
|
-
const key = peek$(ctx, `containerItemKey${u}`);
|
|
21
|
-
let isOk = key === undefined;
|
|
22
|
-
if (!isOk) {
|
|
23
|
-
const index = pendingRemoval.indexOf(u);
|
|
24
|
-
if (index !== -1) {
|
|
25
|
-
pendingRemoval.splice(index, 1);
|
|
26
|
-
isOk = true;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
// Hasn't been allocated yet or is pending removal, so use it
|
|
30
|
-
if (isOk) {
|
|
31
|
-
result.push(u);
|
|
32
|
-
if (result.length >= numNeeded) {
|
|
33
|
-
return result; // Early exit if we have enough unallocated containers
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Second pass: collect containers that are out of view
|
|
39
|
-
for (let u = 0; u < numContainers; u++) {
|
|
40
|
-
const key = peek$(ctx, `containerItemKey${u}`);
|
|
41
|
-
if (key === undefined) continue; // Skip already collected containers
|
|
42
|
-
|
|
43
|
-
const index = state.indexByKey.get(key)!;
|
|
44
|
-
if (index < startBuffered) {
|
|
45
|
-
availableContainers.push({ index: u, distance: startBuffered - index });
|
|
46
|
-
} else if (index > endBuffered) {
|
|
47
|
-
availableContainers.push({ index: u, distance: index - endBuffered });
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// If we need more containers than we have available so far
|
|
52
|
-
const remaining = numNeeded - result.length;
|
|
53
|
-
if (remaining > 0) {
|
|
54
|
-
if (availableContainers.length > 0) {
|
|
55
|
-
// Only sort if we need to
|
|
56
|
-
if (availableContainers.length > remaining) {
|
|
57
|
-
// Sort by distance (furthest first)
|
|
58
|
-
availableContainers.sort(comparatorByDistance);
|
|
59
|
-
// Take just what we need
|
|
60
|
-
availableContainers.length = remaining;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Add to result, keeping track of original indices
|
|
64
|
-
for (const container of availableContainers) {
|
|
65
|
-
result.push(container.index);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// If we still need more, create new containers
|
|
70
|
-
const stillNeeded = numNeeded - result.length;
|
|
71
|
-
if (stillNeeded > 0) {
|
|
72
|
-
for (let i = 0; i < stillNeeded; i++) {
|
|
73
|
-
result.push(numContainers + i);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (__DEV__ && numContainers + stillNeeded > peek$(ctx, "numContainersPooled")) {
|
|
77
|
-
console.warn(
|
|
78
|
-
"[legend-list] No unused container available, so creating one on demand. This can be a minor performance issue and is likely caused by the estimatedItemSize being too large. Consider decreasing estimatedItemSize or increasing initialContainerPoolRatio.",
|
|
79
|
-
{
|
|
80
|
-
debugInfo: {
|
|
81
|
-
numContainers,
|
|
82
|
-
numNeeded,
|
|
83
|
-
stillNeeded,
|
|
84
|
-
numContainersPooled: peek$(ctx, "numContainersPooled"),
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Sort by index for consistent ordering
|
|
93
|
-
return result.sort(comparatorDefault);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function comparatorByDistance(a: { distance: number }, b: { distance: number }) {
|
|
97
|
-
return b.distance - a.distance;
|
|
98
|
-
}
|
package/src/finishScrollTo.ts
DELETED
package/src/getId.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { InternalState } from "./types";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Generates and caches a unique ID for a list item at the given index.
|
|
5
|
-
*
|
|
6
|
-
* @param state - The internal state containing data, keyExtractor, and ID cache
|
|
7
|
-
* @param index - The index of the item to get the ID for
|
|
8
|
-
* @returns The unique ID for the item, or empty string if data is not available
|
|
9
|
-
*/
|
|
10
|
-
export function getId(state: InternalState, index: number): string {
|
|
11
|
-
const { data, keyExtractor } = state.props;
|
|
12
|
-
if (!data) {
|
|
13
|
-
return "";
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Generate and cache the ID
|
|
17
|
-
const ret = index < data.length ? (keyExtractor ? keyExtractor(data[index], index) : index) : null;
|
|
18
|
-
const id = ret as string;
|
|
19
|
-
state.idCache.set(index, id);
|
|
20
|
-
return id;
|
|
21
|
-
}
|
package/src/getItemSize.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { IsNewArchitecture } from "./constants";
|
|
2
|
-
import type { InternalState } from "./types";
|
|
3
|
-
|
|
4
|
-
export function getItemSize(
|
|
5
|
-
state: InternalState,
|
|
6
|
-
key: string,
|
|
7
|
-
index: number,
|
|
8
|
-
data: any,
|
|
9
|
-
useAverageSize?: number | undefined,
|
|
10
|
-
) {
|
|
11
|
-
const {
|
|
12
|
-
sizesKnown,
|
|
13
|
-
sizes,
|
|
14
|
-
scrollingTo,
|
|
15
|
-
props: { estimatedItemSize, getEstimatedItemSize },
|
|
16
|
-
} = state;
|
|
17
|
-
const sizeKnown = sizesKnown.get(key)!;
|
|
18
|
-
if (sizeKnown !== undefined) {
|
|
19
|
-
return sizeKnown;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
let size: number | undefined;
|
|
23
|
-
|
|
24
|
-
// Using average size is not supported on old architecture because it can't layout immediately
|
|
25
|
-
if (
|
|
26
|
-
IsNewArchitecture &&
|
|
27
|
-
useAverageSize !== undefined &&
|
|
28
|
-
sizeKnown === undefined &&
|
|
29
|
-
!getEstimatedItemSize &&
|
|
30
|
-
!scrollingTo
|
|
31
|
-
) {
|
|
32
|
-
// TODO: Hook this up to actual item type later once we have item types
|
|
33
|
-
size = useAverageSize;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (size === undefined) {
|
|
37
|
-
size = sizes.get(key)!;
|
|
38
|
-
|
|
39
|
-
if (size !== undefined) {
|
|
40
|
-
return size;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (size === undefined) {
|
|
45
|
-
// Get estimated size if we don't have an average or already cached size
|
|
46
|
-
size = getEstimatedItemSize ? getEstimatedItemSize(index, data) : estimatedItemSize!;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Save to rendered sizes
|
|
50
|
-
sizes.set(key, size);
|
|
51
|
-
return size;
|
|
52
|
-
}
|
package/src/getRenderedItem.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { type StateContext, peek$ } from "./state";
|
|
3
|
-
import type { InternalState } from "./types";
|
|
4
|
-
|
|
5
|
-
export function getRenderedItem(ctx: StateContext, state: InternalState, key: string) {
|
|
6
|
-
if (!state) {
|
|
7
|
-
return null;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const {
|
|
11
|
-
indexByKey,
|
|
12
|
-
props: { data, renderItem },
|
|
13
|
-
} = state;
|
|
14
|
-
|
|
15
|
-
const index = indexByKey.get(key);
|
|
16
|
-
|
|
17
|
-
if (index === undefined) {
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
let renderedItem: React.ReactNode = null;
|
|
22
|
-
|
|
23
|
-
if (renderItem) {
|
|
24
|
-
const itemProps = {
|
|
25
|
-
item: data[index],
|
|
26
|
-
index,
|
|
27
|
-
extraData: peek$(ctx, "extraData"),
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
renderedItem = React.createElement(renderItem, itemProps);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return { index, item: data[index], renderedItem };
|
|
34
|
-
}
|
package/src/getScrollVelocity.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import type { InternalState } from "./types";
|
|
2
|
-
|
|
3
|
-
export const getScrollVelocity = (state: InternalState) => {
|
|
4
|
-
const { scrollHistory } = state;
|
|
5
|
-
let velocity = 0;
|
|
6
|
-
if (scrollHistory.length >= 1) {
|
|
7
|
-
const newest = scrollHistory[scrollHistory.length - 1];
|
|
8
|
-
let oldest: (typeof scrollHistory)[0] | undefined;
|
|
9
|
-
let start = 0;
|
|
10
|
-
|
|
11
|
-
// If there's a change in direction, remove all entries before that point
|
|
12
|
-
for (let i = 0; i < scrollHistory.length - 1; i++) {
|
|
13
|
-
const entry = scrollHistory[i];
|
|
14
|
-
const nextEntry = scrollHistory[i + 1];
|
|
15
|
-
|
|
16
|
-
// Check if direction changes - if so, remove older entries
|
|
17
|
-
if (i > 0) {
|
|
18
|
-
const prevEntry = scrollHistory[i - 1];
|
|
19
|
-
const prevDirection = entry.scroll - prevEntry.scroll;
|
|
20
|
-
const currentDirection = nextEntry.scroll - entry.scroll;
|
|
21
|
-
|
|
22
|
-
// If direction changed, remove all entries before this point
|
|
23
|
-
if ((prevDirection > 0 && currentDirection < 0) || (prevDirection < 0 && currentDirection > 0)) {
|
|
24
|
-
start = i;
|
|
25
|
-
break;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Find oldest recent event
|
|
31
|
-
for (let i = start; i < scrollHistory.length - 1; i++) {
|
|
32
|
-
const entry = scrollHistory[i];
|
|
33
|
-
if (newest.time - entry.time <= 1000) {
|
|
34
|
-
oldest = entry;
|
|
35
|
-
break;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (oldest) {
|
|
40
|
-
const scrollDiff = newest.scroll - oldest.scroll;
|
|
41
|
-
const timeDiff = newest.time - oldest.time;
|
|
42
|
-
velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return velocity;
|
|
47
|
-
};
|
package/src/handleLayout.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import type { LayoutRectangle } from "react-native";
|
|
2
|
-
import { calculateItemsInView } from "./calculateItemsInView";
|
|
3
|
-
import { checkAtBottom } from "./checkAtBottom";
|
|
4
|
-
import { checkAtTop } from "./checkAtTop";
|
|
5
|
-
import { doInitialAllocateContainers } from "./doInitialAllocateContainers";
|
|
6
|
-
import { doMaintainScrollAtEnd } from "./doMaintainScrollAtEnd";
|
|
7
|
-
import { warnDevOnce } from "./helpers";
|
|
8
|
-
import { type StateContext, set$ } from "./state";
|
|
9
|
-
import type { InternalState, MaintainScrollAtEndOptions } from "./types";
|
|
10
|
-
import { updateAlignItemsPaddingTop } from "./updateAlignItemsPaddingTop";
|
|
11
|
-
|
|
12
|
-
export function handleLayout(
|
|
13
|
-
ctx: StateContext,
|
|
14
|
-
state: InternalState,
|
|
15
|
-
layout: LayoutRectangle,
|
|
16
|
-
setCanRender: (canRender: boolean) => void,
|
|
17
|
-
) {
|
|
18
|
-
const { maintainScrollAtEnd } = state.props;
|
|
19
|
-
|
|
20
|
-
const scrollLength = layout[state.props.horizontal ? "width" : "height"];
|
|
21
|
-
const otherAxisSize = layout[state.props.horizontal ? "height" : "width"];
|
|
22
|
-
|
|
23
|
-
const needsCalculate =
|
|
24
|
-
!state.lastLayout ||
|
|
25
|
-
scrollLength > state.scrollLength ||
|
|
26
|
-
state.lastLayout.x !== layout.x ||
|
|
27
|
-
state.lastLayout.y !== layout.y;
|
|
28
|
-
|
|
29
|
-
state.lastLayout = layout;
|
|
30
|
-
|
|
31
|
-
const didChange = scrollLength !== state.scrollLength;
|
|
32
|
-
const prevOtherAxisSize = state.otherAxisSize;
|
|
33
|
-
state.scrollLength = scrollLength;
|
|
34
|
-
state.otherAxisSize = otherAxisSize;
|
|
35
|
-
state.lastBatchingAction = Date.now();
|
|
36
|
-
state.scrollForNextCalculateItemsInView = undefined;
|
|
37
|
-
|
|
38
|
-
doInitialAllocateContainers(ctx, state);
|
|
39
|
-
|
|
40
|
-
if (needsCalculate) {
|
|
41
|
-
calculateItemsInView(ctx, state, { doMVCP: true });
|
|
42
|
-
}
|
|
43
|
-
if (didChange || otherAxisSize !== prevOtherAxisSize) {
|
|
44
|
-
set$(ctx, "scrollSize", { width: layout.width, height: layout.height });
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (maintainScrollAtEnd === true || (maintainScrollAtEnd as MaintainScrollAtEndOptions).onLayout) {
|
|
48
|
-
doMaintainScrollAtEnd(ctx, state, false);
|
|
49
|
-
}
|
|
50
|
-
updateAlignItemsPaddingTop(ctx, state);
|
|
51
|
-
checkAtBottom(ctx, state);
|
|
52
|
-
checkAtTop(state);
|
|
53
|
-
|
|
54
|
-
if (state) {
|
|
55
|
-
// If otherAxisSize minus padding is less than 10, we need to set the size of the other axis
|
|
56
|
-
// from the item height. 10 is just a magic number to account for border/outline or rounding errors.
|
|
57
|
-
state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (__DEV__ && scrollLength === 0) {
|
|
61
|
-
warnDevOnce(
|
|
62
|
-
"height0",
|
|
63
|
-
`List ${
|
|
64
|
-
state.props.horizontal ? "width" : "height"
|
|
65
|
-
} is 0. You may need to set a style or \`flex: \` for the list, because children are absolutely positioned.`,
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
setCanRender(true);
|
|
70
|
-
}
|
package/src/helpers.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { ViewStyle } from "react-native";
|
|
2
|
-
|
|
3
|
-
export function isFunction(obj: unknown): obj is (...args: any[]) => any {
|
|
4
|
-
return typeof obj === "function";
|
|
5
|
-
}
|
|
6
|
-
export function isArray(obj: unknown): obj is Array<any> {
|
|
7
|
-
return Array.isArray(obj);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const warned = new Set<string>();
|
|
11
|
-
export function warnDevOnce(id: string, text: string) {
|
|
12
|
-
if (__DEV__ && !warned.has(id)) {
|
|
13
|
-
warned.add(id);
|
|
14
|
-
console.warn(`[legend-list] ${text}`);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function roundSize(size: number) {
|
|
19
|
-
return Math.floor(size * 8) / 8; // Round to nearest quater pixel to avoid accumulating rounding errors
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function isNullOrUndefined(value: unknown) {
|
|
23
|
-
return value === null || value === undefined;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function comparatorDefault(a: number, b: number) {
|
|
27
|
-
return a - b;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function byIndex(a: { index: number }) {
|
|
31
|
-
return a.index;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function getPadding(s: ViewStyle, type: "Top" | "Bottom") {
|
|
35
|
-
return (s[`padding${type}`] ?? s.paddingVertical ?? s.padding ?? 0) as number;
|
|
36
|
-
}
|
|
37
|
-
export function extractPadding(style: ViewStyle, contentContainerStyle: ViewStyle, type: "Top" | "Bottom") {
|
|
38
|
-
return getPadding(style, type) + getPadding(contentContainerStyle, type);
|
|
39
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export { LegendList } from "./LegendList";
|
|
2
|
-
export { LazyLegendList, type LazyLegendListProps } from "./LazyLegendList";
|
|
3
|
-
export {
|
|
4
|
-
useIsLastItem,
|
|
5
|
-
useListScrollSize,
|
|
6
|
-
useRecyclingEffect,
|
|
7
|
-
useRecyclingState,
|
|
8
|
-
useViewability,
|
|
9
|
-
useViewabilityAmount,
|
|
10
|
-
} from "./ContextContainer";
|
|
11
|
-
export type * from "./types";
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { LegendList as LegendListBase, type LegendListProps, type LegendListRef } from "@legendapp/list";
|
|
2
|
-
import type { AnimatedLegendList } from "@legendapp/list/animated";
|
|
3
|
-
import type { AnimatedLegendList as ReanimatedLegendList } from "@legendapp/list/reanimated";
|
|
4
|
-
// biome-ignore lint/style/useImportType: Leaving this out makes it crash in some environments
|
|
5
|
-
import * as React from "react";
|
|
6
|
-
import { type ForwardedRef, forwardRef, useState } from "react";
|
|
7
|
-
import { type Insets, StyleSheet } from "react-native";
|
|
8
|
-
import { useKeyboardHandler } from "react-native-keyboard-controller";
|
|
9
|
-
import { runOnJS } from "react-native-reanimated";
|
|
10
|
-
|
|
11
|
-
// biome-ignore lint/complexity/noBannedTypes: This is a workaround for the fact that forwardRef is not typed
|
|
12
|
-
type TypedForwardRef = <T, P = {}>(
|
|
13
|
-
render: (props: P, ref: React.Ref<T>) => React.ReactNode,
|
|
14
|
-
) => (props: P & React.RefAttributes<T>) => React.ReactNode;
|
|
15
|
-
|
|
16
|
-
const typedForwardRef = forwardRef as TypedForwardRef;
|
|
17
|
-
|
|
18
|
-
export const LegendList = typedForwardRef(function LegendList<
|
|
19
|
-
ItemT,
|
|
20
|
-
ListT extends
|
|
21
|
-
| typeof LegendListBase
|
|
22
|
-
| typeof AnimatedLegendList
|
|
23
|
-
| typeof ReanimatedLegendList = typeof LegendListBase,
|
|
24
|
-
>(props: LegendListProps<ItemT> & { LegendList?: ListT }, forwardedRef: ForwardedRef<LegendListRef>) {
|
|
25
|
-
const {
|
|
26
|
-
LegendList: LegendListProp,
|
|
27
|
-
contentContainerStyle: contentContainerStyleProp,
|
|
28
|
-
scrollIndicatorInsets: scrollIndicatorInsetsProp,
|
|
29
|
-
...rest
|
|
30
|
-
} = props;
|
|
31
|
-
const [padding, setPadding] = useState(0);
|
|
32
|
-
|
|
33
|
-
// Define this function outside the worklet
|
|
34
|
-
const updatePadding = (height: number) => {
|
|
35
|
-
setPadding(height);
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
useKeyboardHandler({
|
|
39
|
-
onEnd: (e) => {
|
|
40
|
-
"worklet";
|
|
41
|
-
runOnJS(updatePadding)(e.height);
|
|
42
|
-
},
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
const LegendListComponent = LegendListProp ?? LegendListBase;
|
|
46
|
-
|
|
47
|
-
const contentContainerStyleFlattened = StyleSheet.flatten(contentContainerStyleProp) || {};
|
|
48
|
-
const contentContainerStyle = { ...contentContainerStyleFlattened, paddingTop: padding };
|
|
49
|
-
const scrollIndicatorInsets: Insets = scrollIndicatorInsetsProp ? { ...scrollIndicatorInsetsProp } : {};
|
|
50
|
-
if (!props.horizontal) {
|
|
51
|
-
scrollIndicatorInsets.top = (scrollIndicatorInsets?.top || 0) + padding;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return (
|
|
55
|
-
// @ts-expect-error TODO: Fix this type
|
|
56
|
-
<LegendListComponent
|
|
57
|
-
{...rest}
|
|
58
|
-
contentContainerStyle={contentContainerStyle}
|
|
59
|
-
scrollIndicatorInsets={scrollIndicatorInsets}
|
|
60
|
-
ref={forwardedRef}
|
|
61
|
-
/>
|
|
62
|
-
);
|
|
63
|
-
});
|