@legendapp/list 0.1.1 → 0.1.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/README.md +8 -0
- package/index.d.mts +28 -2
- package/index.d.ts +28 -2
- package/index.js +17 -19
- package/index.mjs +18 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -70,3 +70,11 @@ There's not a lot of code here so hopefully it's easy to contribute. If you want
|
|
|
70
70
|
- Other important missing features from FlatList or other lists libraries
|
|
71
71
|
- Optimizations:
|
|
72
72
|
- Loop over only potentially changed items when adjusting heights rather than data array
|
|
73
|
+
|
|
74
|
+
## Community
|
|
75
|
+
|
|
76
|
+
Join us on [Discord](https://discord.gg/tuW2pAffjA) to get involved with the Legend community.
|
|
77
|
+
|
|
78
|
+
## 👩⚖️ License
|
|
79
|
+
|
|
80
|
+
[MIT](LICENSE)
|
package/index.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { ComponentProps, ReactNode } from 'react';
|
|
3
|
-
import
|
|
3
|
+
import * as react_native from 'react-native';
|
|
4
|
+
import { ScrollView, StyleProp, ViewStyle } from 'react-native';
|
|
4
5
|
|
|
5
6
|
type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset'> & {
|
|
6
7
|
data: ArrayLike<any> & T[];
|
|
@@ -19,6 +20,10 @@ type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset
|
|
|
19
20
|
keyExtractor?: (item: T, index: number) => string;
|
|
20
21
|
renderItem?: (props: LegendListRenderItemInfo<T>) => ReactNode;
|
|
21
22
|
onViewableRangeChanged?: (range: ViewableRange<T>) => void;
|
|
23
|
+
ListHeaderComponent?: ReactNode;
|
|
24
|
+
ListHeaderComponentStyle?: StyleProp<ViewStyle> | undefined;
|
|
25
|
+
ListFooterComponent?: ReactNode;
|
|
26
|
+
ListFooterComponentStyle?: StyleProp<ViewStyle> | undefined;
|
|
22
27
|
};
|
|
23
28
|
interface ViewableRange<T> {
|
|
24
29
|
startBuffered: number;
|
|
@@ -32,6 +37,27 @@ interface LegendListRenderItemInfo<ItemT> {
|
|
|
32
37
|
index: number;
|
|
33
38
|
}
|
|
34
39
|
|
|
35
|
-
declare
|
|
40
|
+
declare const LegendList: React.ForwardRefExoticComponent<Omit<react_native.ScrollViewProps, "contentOffset"> & {
|
|
41
|
+
data: ArrayLike<any> & unknown[];
|
|
42
|
+
initialScrollOffset?: number;
|
|
43
|
+
initialScrollIndex?: number;
|
|
44
|
+
drawDistance?: number;
|
|
45
|
+
initialContainers?: number;
|
|
46
|
+
recycleItems?: boolean;
|
|
47
|
+
onEndReachedThreshold?: number | null | undefined;
|
|
48
|
+
autoScrollToBottom?: boolean;
|
|
49
|
+
autoScrollToBottomThreshold?: number;
|
|
50
|
+
estimatedItemLength: (index: number) => number;
|
|
51
|
+
onEndReached?: ((info: {
|
|
52
|
+
distanceFromEnd: number;
|
|
53
|
+
}) => void) | null | undefined;
|
|
54
|
+
keyExtractor?: ((item: unknown, index: number) => string) | undefined;
|
|
55
|
+
renderItem?: ((props: LegendListRenderItemInfo<unknown>) => React.ReactNode) | undefined;
|
|
56
|
+
onViewableRangeChanged?: ((range: ViewableRange<unknown>) => void) | undefined;
|
|
57
|
+
ListHeaderComponent?: React.ReactNode;
|
|
58
|
+
ListHeaderComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
59
|
+
ListFooterComponent?: React.ReactNode;
|
|
60
|
+
ListFooterComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
61
|
+
} & React.RefAttributes<ScrollView>>;
|
|
36
62
|
|
|
37
63
|
export { LegendList, type LegendListProps, type LegendListRenderItemInfo, type ViewableRange };
|
package/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { ComponentProps, ReactNode } from 'react';
|
|
3
|
-
import
|
|
3
|
+
import * as react_native from 'react-native';
|
|
4
|
+
import { ScrollView, StyleProp, ViewStyle } from 'react-native';
|
|
4
5
|
|
|
5
6
|
type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset'> & {
|
|
6
7
|
data: ArrayLike<any> & T[];
|
|
@@ -19,6 +20,10 @@ type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset
|
|
|
19
20
|
keyExtractor?: (item: T, index: number) => string;
|
|
20
21
|
renderItem?: (props: LegendListRenderItemInfo<T>) => ReactNode;
|
|
21
22
|
onViewableRangeChanged?: (range: ViewableRange<T>) => void;
|
|
23
|
+
ListHeaderComponent?: ReactNode;
|
|
24
|
+
ListHeaderComponentStyle?: StyleProp<ViewStyle> | undefined;
|
|
25
|
+
ListFooterComponent?: ReactNode;
|
|
26
|
+
ListFooterComponentStyle?: StyleProp<ViewStyle> | undefined;
|
|
22
27
|
};
|
|
23
28
|
interface ViewableRange<T> {
|
|
24
29
|
startBuffered: number;
|
|
@@ -32,6 +37,27 @@ interface LegendListRenderItemInfo<ItemT> {
|
|
|
32
37
|
index: number;
|
|
33
38
|
}
|
|
34
39
|
|
|
35
|
-
declare
|
|
40
|
+
declare const LegendList: React.ForwardRefExoticComponent<Omit<react_native.ScrollViewProps, "contentOffset"> & {
|
|
41
|
+
data: ArrayLike<any> & unknown[];
|
|
42
|
+
initialScrollOffset?: number;
|
|
43
|
+
initialScrollIndex?: number;
|
|
44
|
+
drawDistance?: number;
|
|
45
|
+
initialContainers?: number;
|
|
46
|
+
recycleItems?: boolean;
|
|
47
|
+
onEndReachedThreshold?: number | null | undefined;
|
|
48
|
+
autoScrollToBottom?: boolean;
|
|
49
|
+
autoScrollToBottomThreshold?: number;
|
|
50
|
+
estimatedItemLength: (index: number) => number;
|
|
51
|
+
onEndReached?: ((info: {
|
|
52
|
+
distanceFromEnd: number;
|
|
53
|
+
}) => void) | null | undefined;
|
|
54
|
+
keyExtractor?: ((item: unknown, index: number) => string) | undefined;
|
|
55
|
+
renderItem?: ((props: LegendListRenderItemInfo<unknown>) => React.ReactNode) | undefined;
|
|
56
|
+
onViewableRangeChanged?: ((range: ViewableRange<unknown>) => void) | undefined;
|
|
57
|
+
ListHeaderComponent?: React.ReactNode;
|
|
58
|
+
ListHeaderComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
59
|
+
ListFooterComponent?: React.ReactNode;
|
|
60
|
+
ListFooterComponentStyle?: react_native.StyleProp<react_native.ViewStyle> | undefined;
|
|
61
|
+
} & React.RefAttributes<ScrollView>>;
|
|
36
62
|
|
|
37
63
|
export { LegendList, type LegendListProps, type LegendListRenderItemInfo, type ViewableRange };
|
package/index.js
CHANGED
|
@@ -71,7 +71,7 @@ var Container = ({
|
|
|
71
71
|
enableReactNativeComponents.enableReactNativeComponents();
|
|
72
72
|
var DEFAULT_SCROLL_BUFFER = 0;
|
|
73
73
|
var POSITION_OUT_OF_VIEW = -1e4;
|
|
74
|
-
|
|
74
|
+
var LegendList = React2.forwardRef((props, forwardedRef) => {
|
|
75
75
|
const {
|
|
76
76
|
data,
|
|
77
77
|
initialScrollIndex,
|
|
@@ -81,7 +81,7 @@ function LegendList(props) {
|
|
|
81
81
|
contentContainerStyle,
|
|
82
82
|
initialContainers,
|
|
83
83
|
drawDistance,
|
|
84
|
-
recycleItems =
|
|
84
|
+
recycleItems = true,
|
|
85
85
|
onEndReachedThreshold,
|
|
86
86
|
autoScrollToBottom = false,
|
|
87
87
|
autoScrollToBottomThreshold = 0.1,
|
|
@@ -90,11 +90,14 @@ function LegendList(props) {
|
|
|
90
90
|
estimatedItemLength,
|
|
91
91
|
onEndReached,
|
|
92
92
|
onViewableRangeChanged,
|
|
93
|
-
|
|
93
|
+
ListHeaderComponent,
|
|
94
|
+
ListHeaderComponentStyle,
|
|
95
|
+
ListFooterComponent,
|
|
96
|
+
ListFooterComponentStyle,
|
|
94
97
|
...rest
|
|
95
98
|
} = props;
|
|
96
|
-
const
|
|
97
|
-
const refScroller =
|
|
99
|
+
const internalRef = React2.useRef(null);
|
|
100
|
+
const refScroller = forwardedRef || internalRef;
|
|
98
101
|
const containers$ = react.useObservable(() => []);
|
|
99
102
|
const visibleRange$ = react.useObservable(() => ({
|
|
100
103
|
start: 0,
|
|
@@ -111,7 +114,7 @@ function LegendList(props) {
|
|
|
111
114
|
if (!data2) {
|
|
112
115
|
return "";
|
|
113
116
|
}
|
|
114
|
-
const ret = index <
|
|
117
|
+
const ret = index < data2.length ? keyExtractor ? keyExtractor(data2[index], index) : index : null;
|
|
115
118
|
return ret + "";
|
|
116
119
|
};
|
|
117
120
|
if (!refPositions.current) {
|
|
@@ -125,13 +128,11 @@ function LegendList(props) {
|
|
|
125
128
|
isAtBottom: false,
|
|
126
129
|
data,
|
|
127
130
|
idsInFirstRender: void 0,
|
|
128
|
-
hasScrolled: false
|
|
129
|
-
childrenArray
|
|
131
|
+
hasScrolled: false
|
|
130
132
|
};
|
|
131
|
-
refPositions.current.idsInFirstRender = new Set(
|
|
133
|
+
refPositions.current.idsInFirstRender = new Set(data.map((_, i) => getId(i)));
|
|
132
134
|
}
|
|
133
135
|
refPositions.current.data = data;
|
|
134
|
-
refPositions.current.childrenArray = childrenArray;
|
|
135
136
|
const SCREEN_LENGTH = reactNative.Dimensions.get("window")[horizontal ? "width" : "height"];
|
|
136
137
|
const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : initialScrollIndex ? initialScrollIndex * estimatedItemLength(initialScrollIndex) : void 0;
|
|
137
138
|
const allocateContainers = React2.useCallback(() => {
|
|
@@ -148,15 +149,10 @@ function LegendList(props) {
|
|
|
148
149
|
}, []);
|
|
149
150
|
const getRenderedItem = React2.useCallback(
|
|
150
151
|
(index) => {
|
|
151
|
-
var _a
|
|
152
|
+
var _a;
|
|
152
153
|
const data2 = (_a = refPositions.current) == null ? void 0 : _a.data;
|
|
153
154
|
if (!data2) {
|
|
154
|
-
|
|
155
|
-
if (childrenArray2) {
|
|
156
|
-
return childrenArray2[index];
|
|
157
|
-
} else {
|
|
158
|
-
return null;
|
|
159
|
-
}
|
|
155
|
+
return null;
|
|
160
156
|
}
|
|
161
157
|
const renderedItem = renderItem == null ? void 0 : renderItem({
|
|
162
158
|
item: data2[index],
|
|
@@ -375,6 +371,7 @@ function LegendList(props) {
|
|
|
375
371
|
...rest,
|
|
376
372
|
ref: refScroller
|
|
377
373
|
},
|
|
374
|
+
ListHeaderComponent && /* @__PURE__ */ React2__namespace.createElement(react.Reactive.View, { $style: ListHeaderComponentStyle }, ListHeaderComponent),
|
|
378
375
|
/* @__PURE__ */ React2__namespace.createElement(
|
|
379
376
|
react.Reactive.View,
|
|
380
377
|
{
|
|
@@ -395,8 +392,9 @@ function LegendList(props) {
|
|
|
395
392
|
onLayout: updateItemLength
|
|
396
393
|
}
|
|
397
394
|
))
|
|
398
|
-
)
|
|
395
|
+
),
|
|
396
|
+
ListFooterComponent && /* @__PURE__ */ React2__namespace.createElement(react.Reactive.View, { $style: ListFooterComponentStyle }, ListFooterComponent)
|
|
399
397
|
);
|
|
400
|
-
}
|
|
398
|
+
});
|
|
401
399
|
|
|
402
400
|
exports.LegendList = LegendList;
|
package/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React2 from 'react';
|
|
2
|
-
import { useRef, useCallback, useMemo, useEffect } from 'react';
|
|
2
|
+
import { forwardRef, useRef, useCallback, useMemo, useEffect } from 'react';
|
|
3
3
|
import { beginBatch, endBatch } from '@legendapp/state';
|
|
4
4
|
import { enableReactNativeComponents } from '@legendapp/state/config/enableReactNativeComponents';
|
|
5
5
|
import { useObservable, use$, Reactive } from '@legendapp/state/react';
|
|
@@ -50,7 +50,7 @@ var Container = ({
|
|
|
50
50
|
enableReactNativeComponents();
|
|
51
51
|
var DEFAULT_SCROLL_BUFFER = 0;
|
|
52
52
|
var POSITION_OUT_OF_VIEW = -1e4;
|
|
53
|
-
|
|
53
|
+
var LegendList = forwardRef((props, forwardedRef) => {
|
|
54
54
|
const {
|
|
55
55
|
data,
|
|
56
56
|
initialScrollIndex,
|
|
@@ -60,7 +60,7 @@ function LegendList(props) {
|
|
|
60
60
|
contentContainerStyle,
|
|
61
61
|
initialContainers,
|
|
62
62
|
drawDistance,
|
|
63
|
-
recycleItems =
|
|
63
|
+
recycleItems = true,
|
|
64
64
|
onEndReachedThreshold,
|
|
65
65
|
autoScrollToBottom = false,
|
|
66
66
|
autoScrollToBottomThreshold = 0.1,
|
|
@@ -69,11 +69,14 @@ function LegendList(props) {
|
|
|
69
69
|
estimatedItemLength,
|
|
70
70
|
onEndReached,
|
|
71
71
|
onViewableRangeChanged,
|
|
72
|
-
|
|
72
|
+
ListHeaderComponent,
|
|
73
|
+
ListHeaderComponentStyle,
|
|
74
|
+
ListFooterComponent,
|
|
75
|
+
ListFooterComponentStyle,
|
|
73
76
|
...rest
|
|
74
77
|
} = props;
|
|
75
|
-
const
|
|
76
|
-
const refScroller =
|
|
78
|
+
const internalRef = useRef(null);
|
|
79
|
+
const refScroller = forwardedRef || internalRef;
|
|
77
80
|
const containers$ = useObservable(() => []);
|
|
78
81
|
const visibleRange$ = useObservable(() => ({
|
|
79
82
|
start: 0,
|
|
@@ -90,7 +93,7 @@ function LegendList(props) {
|
|
|
90
93
|
if (!data2) {
|
|
91
94
|
return "";
|
|
92
95
|
}
|
|
93
|
-
const ret = index <
|
|
96
|
+
const ret = index < data2.length ? keyExtractor ? keyExtractor(data2[index], index) : index : null;
|
|
94
97
|
return ret + "";
|
|
95
98
|
};
|
|
96
99
|
if (!refPositions.current) {
|
|
@@ -104,13 +107,11 @@ function LegendList(props) {
|
|
|
104
107
|
isAtBottom: false,
|
|
105
108
|
data,
|
|
106
109
|
idsInFirstRender: void 0,
|
|
107
|
-
hasScrolled: false
|
|
108
|
-
childrenArray
|
|
110
|
+
hasScrolled: false
|
|
109
111
|
};
|
|
110
|
-
refPositions.current.idsInFirstRender = new Set(
|
|
112
|
+
refPositions.current.idsInFirstRender = new Set(data.map((_, i) => getId(i)));
|
|
111
113
|
}
|
|
112
114
|
refPositions.current.data = data;
|
|
113
|
-
refPositions.current.childrenArray = childrenArray;
|
|
114
115
|
const SCREEN_LENGTH = Dimensions.get("window")[horizontal ? "width" : "height"];
|
|
115
116
|
const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : initialScrollIndex ? initialScrollIndex * estimatedItemLength(initialScrollIndex) : void 0;
|
|
116
117
|
const allocateContainers = useCallback(() => {
|
|
@@ -127,15 +128,10 @@ function LegendList(props) {
|
|
|
127
128
|
}, []);
|
|
128
129
|
const getRenderedItem = useCallback(
|
|
129
130
|
(index) => {
|
|
130
|
-
var _a
|
|
131
|
+
var _a;
|
|
131
132
|
const data2 = (_a = refPositions.current) == null ? void 0 : _a.data;
|
|
132
133
|
if (!data2) {
|
|
133
|
-
|
|
134
|
-
if (childrenArray2) {
|
|
135
|
-
return childrenArray2[index];
|
|
136
|
-
} else {
|
|
137
|
-
return null;
|
|
138
|
-
}
|
|
134
|
+
return null;
|
|
139
135
|
}
|
|
140
136
|
const renderedItem = renderItem == null ? void 0 : renderItem({
|
|
141
137
|
item: data2[index],
|
|
@@ -354,6 +350,7 @@ function LegendList(props) {
|
|
|
354
350
|
...rest,
|
|
355
351
|
ref: refScroller
|
|
356
352
|
},
|
|
353
|
+
ListHeaderComponent && /* @__PURE__ */ React2.createElement(Reactive.View, { $style: ListHeaderComponentStyle }, ListHeaderComponent),
|
|
357
354
|
/* @__PURE__ */ React2.createElement(
|
|
358
355
|
Reactive.View,
|
|
359
356
|
{
|
|
@@ -374,8 +371,9 @@ function LegendList(props) {
|
|
|
374
371
|
onLayout: updateItemLength
|
|
375
372
|
}
|
|
376
373
|
))
|
|
377
|
-
)
|
|
374
|
+
),
|
|
375
|
+
ListFooterComponent && /* @__PURE__ */ React2.createElement(Reactive.View, { $style: ListFooterComponentStyle }, ListFooterComponent)
|
|
378
376
|
);
|
|
379
|
-
}
|
|
377
|
+
});
|
|
380
378
|
|
|
381
379
|
export { LegendList };
|