@legendapp/list 1.0.0-beta.4 → 1.0.0-beta.41
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/README.md +93 -37
- package/animated.d.mts +53 -4
- package/animated.d.ts +53 -4
- package/index.d.mts +330 -61
- package/index.d.ts +330 -61
- package/index.js +975 -398
- package/index.mjs +950 -373
- package/keyboard-controller.d.mts +396 -0
- package/keyboard-controller.d.ts +396 -0
- package/keyboard-controller.js +45 -0
- package/keyboard-controller.mjs +24 -0
- package/package.json +3 -6
- package/reanimated.d.mts +13 -9
- package/reanimated.d.ts +13 -9
- package/reanimated.js +20 -16
- package/reanimated.mjs +21 -17
package/README.md
CHANGED
|
@@ -1,64 +1,120 @@
|
|
|
1
|
-
# Legend List
|
|
1
|
+
# Legend List
|
|
2
2
|
|
|
3
|
-
Legend List aims to be a drop-in replacement for FlatList with
|
|
3
|
+
**Legend List** is a high-performance list component for **React Native**, written purely in Javascript / Typescript (no native dependencies). It aims to be a drop-in replacement for `FlatList` and/or `FlashList` with better performance, especially when handling dynamically sized items.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
---
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## ⚠️ Caution: Experimental ⚠️
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
This is an early release to test and gather feedback. It's not used in production yet and needs more work to reach parity with FlatList (and FlashList) features.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
---
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
- `maintainScrollAtEnd`: If true and scroll is within `maintainScrollAtEndThreshold * screen height` then changing items or heights will scroll to the bottom. This can be useful for chat interfaces.
|
|
15
|
-
- `recycleItems` prop enables toggling recycling of list items. If enabled it will reuse item components for improved performance, but it will reuse any local state in items. So if you have local state in items you likely want this disabled.
|
|
13
|
+
## 🤔 Why Legend List?
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
* **Performance:** Designed from the ground up for speed, aiming to outperform `FlatList` in common scenarios.
|
|
16
|
+
* **Dynamic Item Sizes:** Natively supports items with varying heights without performance hits. Just provide an `estimatedItemSize`.
|
|
17
|
+
* **Drop-in Potential:** Aims for API compatibility with `FlatList` for easier migration.
|
|
18
|
+
* **Pure JS/TS:** No native module linking required, ensuring easier integration and compatibility across platforms.
|
|
19
|
+
* **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.
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
For more information, listen to the podcast we had on [React Native Radio](https://infinite.red/react-native-radio/rnr-325-legend-list-with-jay-meistrich)!
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
---
|
|
24
|
+
## ✨ Additional Features
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
Beyond standard `FlatList` capabilities:
|
|
24
27
|
|
|
25
|
-
`
|
|
28
|
+
* `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. Ideal for chat interfaces.
|
|
29
|
+
* `recycleItems`: (boolean) Toggles item component recycling.
|
|
30
|
+
* `true`: Reuses item components for optimal performance. Be cautious if your item components contain local state, as it might be reused unexpectedly.
|
|
31
|
+
* `false` (default): Creates new item components every time. Less performant but safer if items have complex internal state.
|
|
26
32
|
|
|
27
|
-
|
|
33
|
+
---
|
|
28
34
|
|
|
29
|
-
|
|
35
|
+
## 📚 Documentation (In Progress)
|
|
30
36
|
|
|
31
|
-
|
|
37
|
+
For comprehensive documentation, guides, and the full API reference, please visit:
|
|
32
38
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
```
|
|
39
|
+
➡️ **[Legend List Documentation Site](https://www.legendapp.com/open-source/list)**
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 💻 Usage
|
|
40
44
|
|
|
41
|
-
|
|
45
|
+
### Installation
|
|
42
46
|
|
|
47
|
+
```bash
|
|
48
|
+
# Using Bun
|
|
49
|
+
bun add @legendapp/list
|
|
50
|
+
|
|
51
|
+
# Using npm
|
|
52
|
+
npm install @legendapp/list
|
|
53
|
+
|
|
54
|
+
# Using Yarn
|
|
55
|
+
yarn add @legendapp/list
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Example
|
|
43
59
|
```ts
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
60
|
+
import React, { useRef } from "react";
|
|
61
|
+
import { View, Image, Text, StyleSheet } from "react-native";
|
|
62
|
+
import { LegendList, LegendListRef, LegendListRenderItemProps } from "@legendapp/list";
|
|
63
|
+
import { userData } from "../userData"; // Assuming userData is defined elsewhere
|
|
64
|
+
|
|
65
|
+
// Define the type for your data items
|
|
66
|
+
interface UserData {
|
|
67
|
+
id: string;
|
|
68
|
+
name: string;
|
|
69
|
+
photoUri: string;
|
|
54
70
|
}
|
|
71
|
+
|
|
72
|
+
const LegendListExample = () => {
|
|
73
|
+
|
|
74
|
+
// Optional: Ref for accessing list methods (e.g., scrollTo)
|
|
75
|
+
const listRef = useRef<LegendListRef | null>(null);
|
|
76
|
+
|
|
77
|
+
const renderItem = ({ item }: LegendListRenderItemProps<UserData>) => {
|
|
78
|
+
return (
|
|
79
|
+
<View style={styles.itemContainer}>
|
|
80
|
+
<Image style={styles.profilePic} source={{ uri: item.photoUri }} />
|
|
81
|
+
<Text style={styles.name}>{item.name}</Text>
|
|
82
|
+
</View>
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<LegendList<UserData>
|
|
88
|
+
// Required Props
|
|
89
|
+
data={data}
|
|
90
|
+
renderItem={renderItem}
|
|
91
|
+
estimatedItemSize={70}
|
|
92
|
+
|
|
93
|
+
// Strongly Recommended Prop (Improves performance)
|
|
94
|
+
keyExtractor={(item) => item.id}
|
|
95
|
+
|
|
96
|
+
// Optional Props
|
|
97
|
+
ref={listRef}
|
|
98
|
+
recycleItems={true}
|
|
99
|
+
maintainScrollAtEnd={false}
|
|
100
|
+
maintainScrollAtEndThreshold={1}
|
|
101
|
+
|
|
102
|
+
// See docs for all available props!
|
|
103
|
+
/>
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export default LegendListExample;
|
|
108
|
+
|
|
55
109
|
```
|
|
56
110
|
|
|
57
|
-
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## How to Build
|
|
58
114
|
|
|
59
115
|
`npm run build` will build the package to the `dist` folder.
|
|
60
116
|
|
|
61
|
-
##
|
|
117
|
+
## Running the Example
|
|
62
118
|
|
|
63
119
|
1. `cd example`
|
|
64
120
|
2. `npm i`
|
package/animated.d.mts
CHANGED
|
@@ -1,9 +1,58 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as React$1 from 'react';
|
|
2
2
|
import * as _legendapp_list from '@legendapp/list';
|
|
3
|
+
import * as react_native from 'react-native';
|
|
3
4
|
import { Animated } from 'react-native';
|
|
4
5
|
|
|
5
|
-
declare const AnimatedLegendList: Animated.AnimatedComponent<(<T>(props:
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
declare const AnimatedLegendList: Animated.AnimatedComponent<(<T>(props: Omit<react_native.ScrollViewProps, "contentOffset" | "contentInset" | "maintainVisibleContentPosition" | "stickyHeaderIndices"> & {
|
|
7
|
+
alignItemsAtEnd?: boolean;
|
|
8
|
+
columnWrapperStyle?: _legendapp_list.ColumnWrapperStyle;
|
|
9
|
+
data: readonly T[];
|
|
10
|
+
drawDistance?: number;
|
|
11
|
+
estimatedItemSize?: number;
|
|
12
|
+
extraData?: any;
|
|
13
|
+
getEstimatedItemSize?: ((index: number, item: T) => number) | undefined;
|
|
14
|
+
initialContainerPoolRatio?: number | undefined;
|
|
15
|
+
initialScrollOffset?: number;
|
|
16
|
+
initialScrollIndex?: number;
|
|
17
|
+
ItemSeparatorComponent?: React$1.ComponentType<{
|
|
18
|
+
leadingItem: T;
|
|
19
|
+
}> | undefined;
|
|
20
|
+
keyExtractor?: ((item: T, index: number) => string) | undefined;
|
|
21
|
+
ListEmptyComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
22
|
+
ListFooterComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
23
|
+
ListFooterComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
24
|
+
ListHeaderComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
25
|
+
ListHeaderComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
26
|
+
maintainScrollAtEnd?: boolean;
|
|
27
|
+
maintainScrollAtEndThreshold?: number;
|
|
28
|
+
maintainVisibleContentPosition?: boolean;
|
|
29
|
+
numColumns?: number;
|
|
30
|
+
onEndReached?: ((info: {
|
|
31
|
+
distanceFromEnd: number;
|
|
32
|
+
}) => void) | null | undefined;
|
|
33
|
+
onEndReachedThreshold?: number | null | undefined;
|
|
34
|
+
onItemSizeChanged?: ((info: {
|
|
35
|
+
size: number;
|
|
36
|
+
previous: number;
|
|
37
|
+
index: number;
|
|
38
|
+
itemKey: string;
|
|
39
|
+
itemData: T;
|
|
40
|
+
}) => void) | undefined;
|
|
41
|
+
onRefresh?: () => void;
|
|
42
|
+
onStartReached?: ((info: {
|
|
43
|
+
distanceFromStart: number;
|
|
44
|
+
}) => void) | null | undefined;
|
|
45
|
+
onStartReachedThreshold?: number | null | undefined;
|
|
46
|
+
onViewableItemsChanged?: _legendapp_list.OnViewableItemsChanged | undefined;
|
|
47
|
+
progressViewOffset?: number;
|
|
48
|
+
recycleItems?: boolean;
|
|
49
|
+
refScrollView?: React.Ref<react_native.ScrollView>;
|
|
50
|
+
refreshing?: boolean;
|
|
51
|
+
renderItem?: ((props: _legendapp_list.LegendListRenderItemProps<T>) => React$1.ReactNode) | undefined;
|
|
52
|
+
renderScrollComponent?: (props: react_native.ScrollViewProps) => React.ReactElement<react_native.ScrollViewProps>;
|
|
53
|
+
viewabilityConfig?: _legendapp_list.ViewabilityConfig;
|
|
54
|
+
viewabilityConfigCallbackPairs?: _legendapp_list.ViewabilityConfigCallbackPairs | undefined;
|
|
55
|
+
waitForInitialLayout?: boolean;
|
|
56
|
+
} & React$1.RefAttributes<_legendapp_list.LegendListRef>) => React.ReactNode)>;
|
|
8
57
|
|
|
9
58
|
export { AnimatedLegendList };
|
package/animated.d.ts
CHANGED
|
@@ -1,9 +1,58 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as React$1 from 'react';
|
|
2
2
|
import * as _legendapp_list from '@legendapp/list';
|
|
3
|
+
import * as react_native from 'react-native';
|
|
3
4
|
import { Animated } from 'react-native';
|
|
4
5
|
|
|
5
|
-
declare const AnimatedLegendList: Animated.AnimatedComponent<(<T>(props:
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
declare const AnimatedLegendList: Animated.AnimatedComponent<(<T>(props: Omit<react_native.ScrollViewProps, "contentOffset" | "contentInset" | "maintainVisibleContentPosition" | "stickyHeaderIndices"> & {
|
|
7
|
+
alignItemsAtEnd?: boolean;
|
|
8
|
+
columnWrapperStyle?: _legendapp_list.ColumnWrapperStyle;
|
|
9
|
+
data: readonly T[];
|
|
10
|
+
drawDistance?: number;
|
|
11
|
+
estimatedItemSize?: number;
|
|
12
|
+
extraData?: any;
|
|
13
|
+
getEstimatedItemSize?: ((index: number, item: T) => number) | undefined;
|
|
14
|
+
initialContainerPoolRatio?: number | undefined;
|
|
15
|
+
initialScrollOffset?: number;
|
|
16
|
+
initialScrollIndex?: number;
|
|
17
|
+
ItemSeparatorComponent?: React$1.ComponentType<{
|
|
18
|
+
leadingItem: T;
|
|
19
|
+
}> | undefined;
|
|
20
|
+
keyExtractor?: ((item: T, index: number) => string) | undefined;
|
|
21
|
+
ListEmptyComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
22
|
+
ListFooterComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
23
|
+
ListFooterComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
24
|
+
ListHeaderComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
25
|
+
ListHeaderComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
26
|
+
maintainScrollAtEnd?: boolean;
|
|
27
|
+
maintainScrollAtEndThreshold?: number;
|
|
28
|
+
maintainVisibleContentPosition?: boolean;
|
|
29
|
+
numColumns?: number;
|
|
30
|
+
onEndReached?: ((info: {
|
|
31
|
+
distanceFromEnd: number;
|
|
32
|
+
}) => void) | null | undefined;
|
|
33
|
+
onEndReachedThreshold?: number | null | undefined;
|
|
34
|
+
onItemSizeChanged?: ((info: {
|
|
35
|
+
size: number;
|
|
36
|
+
previous: number;
|
|
37
|
+
index: number;
|
|
38
|
+
itemKey: string;
|
|
39
|
+
itemData: T;
|
|
40
|
+
}) => void) | undefined;
|
|
41
|
+
onRefresh?: () => void;
|
|
42
|
+
onStartReached?: ((info: {
|
|
43
|
+
distanceFromStart: number;
|
|
44
|
+
}) => void) | null | undefined;
|
|
45
|
+
onStartReachedThreshold?: number | null | undefined;
|
|
46
|
+
onViewableItemsChanged?: _legendapp_list.OnViewableItemsChanged | undefined;
|
|
47
|
+
progressViewOffset?: number;
|
|
48
|
+
recycleItems?: boolean;
|
|
49
|
+
refScrollView?: React.Ref<react_native.ScrollView>;
|
|
50
|
+
refreshing?: boolean;
|
|
51
|
+
renderItem?: ((props: _legendapp_list.LegendListRenderItemProps<T>) => React$1.ReactNode) | undefined;
|
|
52
|
+
renderScrollComponent?: (props: react_native.ScrollViewProps) => React.ReactElement<react_native.ScrollViewProps>;
|
|
53
|
+
viewabilityConfig?: _legendapp_list.ViewabilityConfig;
|
|
54
|
+
viewabilityConfigCallbackPairs?: _legendapp_list.ViewabilityConfigCallbackPairs | undefined;
|
|
55
|
+
waitForInitialLayout?: boolean;
|
|
56
|
+
} & React$1.RefAttributes<_legendapp_list.LegendListRef>) => React.ReactNode)>;
|
|
8
57
|
|
|
9
58
|
export { AnimatedLegendList };
|