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