@legendapp/list 0.1.2 → 0.2.1
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/index.d.mts +6 -25
- package/index.d.ts +6 -25
- package/index.js +58 -27
- package/index.mjs +58 -27
- package/package.json +1 -1
package/index.d.mts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { ComponentProps, ReactNode } from 'react';
|
|
3
|
-
import * as react_native from 'react-native';
|
|
1
|
+
import { ComponentProps, ReactNode, ForwardedRef, ReactElement } from 'react';
|
|
4
2
|
import { ScrollView, StyleProp, ViewStyle } from 'react-native';
|
|
5
3
|
|
|
6
4
|
type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset'> & {
|
|
@@ -13,6 +11,7 @@ type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset
|
|
|
13
11
|
onEndReachedThreshold?: number | null | undefined;
|
|
14
12
|
autoScrollToBottom?: boolean;
|
|
15
13
|
autoScrollToBottomThreshold?: number;
|
|
14
|
+
startAtBottom?: boolean;
|
|
16
15
|
estimatedItemLength: (index: number) => number;
|
|
17
16
|
onEndReached?: ((info: {
|
|
18
17
|
distanceFromEnd: number;
|
|
@@ -24,6 +23,7 @@ type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset
|
|
|
24
23
|
ListHeaderComponentStyle?: StyleProp<ViewStyle> | undefined;
|
|
25
24
|
ListFooterComponent?: ReactNode;
|
|
26
25
|
ListFooterComponentStyle?: StyleProp<ViewStyle> | undefined;
|
|
26
|
+
ItemSeparatorComponent?: ReactNode;
|
|
27
27
|
};
|
|
28
28
|
interface ViewableRange<T> {
|
|
29
29
|
startBuffered: number;
|
|
@@ -37,27 +37,8 @@ interface LegendListRenderItemInfo<ItemT> {
|
|
|
37
37
|
index: number;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
declare const LegendList:
|
|
41
|
-
|
|
42
|
-
|
|
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>>;
|
|
40
|
+
declare const LegendList: <T>(props: LegendListProps<T> & {
|
|
41
|
+
ref?: ForwardedRef<ScrollView>;
|
|
42
|
+
}) => ReactElement;
|
|
62
43
|
|
|
63
44
|
export { LegendList, type LegendListProps, type LegendListRenderItemInfo, type ViewableRange };
|
package/index.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { ComponentProps, ReactNode } from 'react';
|
|
3
|
-
import * as react_native from 'react-native';
|
|
1
|
+
import { ComponentProps, ReactNode, ForwardedRef, ReactElement } from 'react';
|
|
4
2
|
import { ScrollView, StyleProp, ViewStyle } from 'react-native';
|
|
5
3
|
|
|
6
4
|
type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset'> & {
|
|
@@ -13,6 +11,7 @@ type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset
|
|
|
13
11
|
onEndReachedThreshold?: number | null | undefined;
|
|
14
12
|
autoScrollToBottom?: boolean;
|
|
15
13
|
autoScrollToBottomThreshold?: number;
|
|
14
|
+
startAtBottom?: boolean;
|
|
16
15
|
estimatedItemLength: (index: number) => number;
|
|
17
16
|
onEndReached?: ((info: {
|
|
18
17
|
distanceFromEnd: number;
|
|
@@ -24,6 +23,7 @@ type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset
|
|
|
24
23
|
ListHeaderComponentStyle?: StyleProp<ViewStyle> | undefined;
|
|
25
24
|
ListFooterComponent?: ReactNode;
|
|
26
25
|
ListFooterComponentStyle?: StyleProp<ViewStyle> | undefined;
|
|
26
|
+
ItemSeparatorComponent?: ReactNode;
|
|
27
27
|
};
|
|
28
28
|
interface ViewableRange<T> {
|
|
29
29
|
startBuffered: number;
|
|
@@ -37,27 +37,8 @@ interface LegendListRenderItemInfo<ItemT> {
|
|
|
37
37
|
index: number;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
declare const LegendList:
|
|
41
|
-
|
|
42
|
-
|
|
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>>;
|
|
40
|
+
declare const LegendList: <T>(props: LegendListProps<T> & {
|
|
41
|
+
ref?: ForwardedRef<ScrollView>;
|
|
42
|
+
}) => ReactElement;
|
|
62
43
|
|
|
63
44
|
export { LegendList, type LegendListProps, type LegendListRenderItemInfo, type ViewableRange };
|
package/index.js
CHANGED
|
@@ -33,13 +33,15 @@ var Container = ({
|
|
|
33
33
|
recycleItems,
|
|
34
34
|
listProps,
|
|
35
35
|
getRenderedItem,
|
|
36
|
-
onLayout
|
|
36
|
+
onLayout,
|
|
37
|
+
ItemSeparatorComponent
|
|
37
38
|
}) => {
|
|
38
39
|
const { horizontal } = listProps;
|
|
39
40
|
const { id } = $container.peek();
|
|
40
41
|
const itemIndex = react.use$($container.itemIndex);
|
|
41
42
|
const key = recycleItems ? void 0 : itemIndex;
|
|
42
43
|
const createStyle = () => horizontal ? {
|
|
44
|
+
flexDirection: "row",
|
|
43
45
|
position: "absolute",
|
|
44
46
|
top: 0,
|
|
45
47
|
bottom: 0,
|
|
@@ -63,7 +65,8 @@ var Container = ({
|
|
|
63
65
|
onLayout(index, length);
|
|
64
66
|
}
|
|
65
67
|
},
|
|
66
|
-
/* @__PURE__ */ React2__namespace.createElement(reactNative.View, { key }, getRenderedItem(itemIndex))
|
|
68
|
+
/* @__PURE__ */ React2__namespace.createElement(reactNative.View, { key }, getRenderedItem(itemIndex)),
|
|
69
|
+
ItemSeparatorComponent && itemIndex !== listProps.data.length - 1 && /* @__PURE__ */ React2__namespace.createElement(react.Reactive.View, null, ItemSeparatorComponent)
|
|
67
70
|
);
|
|
68
71
|
};
|
|
69
72
|
|
|
@@ -71,7 +74,7 @@ var Container = ({
|
|
|
71
74
|
enableReactNativeComponents.enableReactNativeComponents();
|
|
72
75
|
var DEFAULT_SCROLL_BUFFER = 0;
|
|
73
76
|
var POSITION_OUT_OF_VIEW = -1e4;
|
|
74
|
-
var LegendList = React2.forwardRef((props, forwardedRef)
|
|
77
|
+
var LegendList = React2.forwardRef(function LegendList2(props, forwardedRef) {
|
|
75
78
|
const {
|
|
76
79
|
data,
|
|
77
80
|
initialScrollIndex,
|
|
@@ -85,6 +88,7 @@ var LegendList = React2.forwardRef((props, forwardedRef) => {
|
|
|
85
88
|
onEndReachedThreshold,
|
|
86
89
|
autoScrollToBottom = false,
|
|
87
90
|
autoScrollToBottomThreshold = 0.1,
|
|
91
|
+
startAtBottom = false,
|
|
88
92
|
keyExtractor,
|
|
89
93
|
renderItem,
|
|
90
94
|
estimatedItemLength,
|
|
@@ -94,11 +98,13 @@ var LegendList = React2.forwardRef((props, forwardedRef) => {
|
|
|
94
98
|
ListHeaderComponentStyle,
|
|
95
99
|
ListFooterComponent,
|
|
96
100
|
ListFooterComponentStyle,
|
|
101
|
+
ItemSeparatorComponent,
|
|
97
102
|
...rest
|
|
98
103
|
} = props;
|
|
99
104
|
const internalRef = React2.useRef(null);
|
|
100
105
|
const refScroller = forwardedRef || internalRef;
|
|
101
106
|
const containers$ = react.useObservable(() => []);
|
|
107
|
+
const paddingTop$ = react.useObservable(0);
|
|
102
108
|
const visibleRange$ = react.useObservable(() => ({
|
|
103
109
|
start: 0,
|
|
104
110
|
end: 0,
|
|
@@ -128,15 +134,24 @@ var LegendList = React2.forwardRef((props, forwardedRef) => {
|
|
|
128
134
|
isAtBottom: false,
|
|
129
135
|
data,
|
|
130
136
|
idsInFirstRender: void 0,
|
|
131
|
-
hasScrolled: false
|
|
137
|
+
hasScrolled: false,
|
|
138
|
+
scrollLength: reactNative.Dimensions.get("window")[horizontal ? "width" : "height"]
|
|
132
139
|
};
|
|
133
140
|
refPositions.current.idsInFirstRender = new Set(data.map((_, i) => getId(i)));
|
|
134
141
|
}
|
|
135
142
|
refPositions.current.data = data;
|
|
136
|
-
const SCREEN_LENGTH = reactNative.Dimensions.get("window")[horizontal ? "width" : "height"];
|
|
137
143
|
const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : initialScrollIndex ? initialScrollIndex * estimatedItemLength(initialScrollIndex) : void 0;
|
|
144
|
+
const setTotalLength = (length) => {
|
|
145
|
+
visibleRange$.totalLength.set(length);
|
|
146
|
+
const screenLength = refPositions.current.scrollLength;
|
|
147
|
+
if (startAtBottom) {
|
|
148
|
+
const listPaddingTop = ((style == null ? void 0 : style.paddingTop) || 0) + ((contentContainerStyle == null ? void 0 : contentContainerStyle.paddingTop) || 0);
|
|
149
|
+
paddingTop$.set(Math.max(0, screenLength - length - listPaddingTop));
|
|
150
|
+
}
|
|
151
|
+
};
|
|
138
152
|
const allocateContainers = React2.useCallback(() => {
|
|
139
|
-
const
|
|
153
|
+
const scrollLength = refPositions.current.scrollLength;
|
|
154
|
+
const numContainers = initialContainers || Math.ceil((scrollLength + scrollBuffer * 2) / estimatedItemLength(0)) + 4;
|
|
140
155
|
const containers2 = [];
|
|
141
156
|
for (let i = 0; i < numContainers; i++) {
|
|
142
157
|
containers2.push({
|
|
@@ -164,7 +179,7 @@ var LegendList = React2.forwardRef((props, forwardedRef) => {
|
|
|
164
179
|
);
|
|
165
180
|
const calculateItemsInView = React2.useCallback(() => {
|
|
166
181
|
var _a, _b;
|
|
167
|
-
const data2 = refPositions.current
|
|
182
|
+
const { data: data2, scrollLength } = refPositions.current;
|
|
168
183
|
if (!data2) {
|
|
169
184
|
return;
|
|
170
185
|
}
|
|
@@ -190,10 +205,10 @@ var LegendList = React2.forwardRef((props, forwardedRef) => {
|
|
|
190
205
|
startBuffered = i;
|
|
191
206
|
}
|
|
192
207
|
if (startNoBuffer !== null) {
|
|
193
|
-
if (top <= scroll +
|
|
208
|
+
if (top <= scroll + scrollLength) {
|
|
194
209
|
endNoBuffer = i;
|
|
195
210
|
}
|
|
196
|
-
if (top <= scroll +
|
|
211
|
+
if (top <= scroll + scrollLength + scrollBuffer) {
|
|
197
212
|
endBuffered = i;
|
|
198
213
|
} else {
|
|
199
214
|
break;
|
|
@@ -282,12 +297,34 @@ var LegendList = React2.forwardRef((props, forwardedRef) => {
|
|
|
282
297
|
const id = getId(i);
|
|
283
298
|
totalLength += (_b = lengths.get(id)) != null ? _b : estimatedItemLength(i);
|
|
284
299
|
}
|
|
285
|
-
|
|
300
|
+
setTotalLength(totalLength);
|
|
286
301
|
}, []);
|
|
302
|
+
const checkAtBottom = () => {
|
|
303
|
+
var _a;
|
|
304
|
+
const scrollLength = refPositions.current.scrollLength;
|
|
305
|
+
const newScroll = visibleRange$.scroll.peek();
|
|
306
|
+
const distanceFromEnd = visibleRange$.totalLength.peek() - newScroll - scrollLength;
|
|
307
|
+
if (refPositions.current) {
|
|
308
|
+
refPositions.current.isAtBottom = distanceFromEnd < scrollLength * autoScrollToBottomThreshold;
|
|
309
|
+
}
|
|
310
|
+
if (onEndReached && !((_a = refPositions.current) == null ? void 0 : _a.isEndReached)) {
|
|
311
|
+
if (distanceFromEnd < (onEndReachedThreshold || 0.5) * scrollLength) {
|
|
312
|
+
if (refPositions.current) {
|
|
313
|
+
refPositions.current.isEndReached = true;
|
|
314
|
+
}
|
|
315
|
+
onEndReached({ distanceFromEnd });
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
};
|
|
287
319
|
React2.useMemo(() => {
|
|
320
|
+
var _a;
|
|
288
321
|
if (refPositions.current) {
|
|
289
|
-
refPositions.current.
|
|
322
|
+
if (!((_a = refPositions.current) == null ? void 0 : _a.isAtBottom)) {
|
|
323
|
+
refPositions.current.isEndReached = false;
|
|
324
|
+
}
|
|
290
325
|
}
|
|
326
|
+
calculateItemsInView();
|
|
327
|
+
checkAtBottom();
|
|
291
328
|
}, [data]);
|
|
292
329
|
const containers = react.use$(containers$, { shallow: true });
|
|
293
330
|
const updateItemLength = React2.useCallback((index, length) => {
|
|
@@ -303,7 +340,7 @@ var LegendList = React2.forwardRef((props, forwardedRef) => {
|
|
|
303
340
|
if (!prevLength || prevLength !== length) {
|
|
304
341
|
state.beginBatch();
|
|
305
342
|
lengths.set(id, length);
|
|
306
|
-
visibleRange$.totalLength.
|
|
343
|
+
setTotalLength(visibleRange$.totalLength.peek() + (length - prevLength));
|
|
307
344
|
if (((_d = refPositions.current) == null ? void 0 : _d.isAtBottom) && autoScrollToBottom) {
|
|
308
345
|
requestAnimationFrame(() => {
|
|
309
346
|
var _a2;
|
|
@@ -319,25 +356,16 @@ var LegendList = React2.forwardRef((props, forwardedRef) => {
|
|
|
319
356
|
}
|
|
320
357
|
}, []);
|
|
321
358
|
const handleScrollDebounced = React2.useCallback(() => {
|
|
322
|
-
var _a;
|
|
323
|
-
const newScroll = visibleRange$.scroll.peek();
|
|
324
359
|
calculateItemsInView();
|
|
325
|
-
|
|
326
|
-
if (refPositions.current) {
|
|
327
|
-
refPositions.current.isAtBottom = distanceFromEnd < SCREEN_LENGTH * autoScrollToBottomThreshold;
|
|
328
|
-
}
|
|
329
|
-
if (onEndReached && !((_a = refPositions.current) == null ? void 0 : _a.isEndReached)) {
|
|
330
|
-
if (distanceFromEnd < (onEndReachedThreshold || 0.5) * SCREEN_LENGTH) {
|
|
331
|
-
if (refPositions.current) {
|
|
332
|
-
refPositions.current.isEndReached = true;
|
|
333
|
-
}
|
|
334
|
-
onEndReached({ distanceFromEnd });
|
|
335
|
-
}
|
|
336
|
-
}
|
|
360
|
+
checkAtBottom();
|
|
337
361
|
if (refPositions.current) {
|
|
338
362
|
refPositions.current.animFrame = null;
|
|
339
363
|
}
|
|
340
364
|
}, []);
|
|
365
|
+
const onLayout = (event) => {
|
|
366
|
+
const scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
367
|
+
refPositions.current.scrollLength = scrollLength;
|
|
368
|
+
};
|
|
341
369
|
const handleScroll = React2.useCallback((event) => {
|
|
342
370
|
refPositions.current.hasScrolled = true;
|
|
343
371
|
const newScroll = event.nativeEvent.contentOffset[horizontal ? "x" : "y"];
|
|
@@ -365,12 +393,14 @@ var LegendList = React2.forwardRef((props, forwardedRef) => {
|
|
|
365
393
|
} : {}
|
|
366
394
|
],
|
|
367
395
|
onScroll: handleScroll,
|
|
396
|
+
onLayout,
|
|
368
397
|
scrollEventThrottle: 32,
|
|
369
398
|
horizontal,
|
|
370
399
|
contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
|
|
371
400
|
...rest,
|
|
372
401
|
ref: refScroller
|
|
373
402
|
},
|
|
403
|
+
startAtBottom && /* @__PURE__ */ React2__namespace.createElement(react.Reactive.View, { $style: () => ({ height: paddingTop$.get() }) }),
|
|
374
404
|
ListHeaderComponent && /* @__PURE__ */ React2__namespace.createElement(react.Reactive.View, { $style: ListHeaderComponentStyle }, ListHeaderComponent),
|
|
375
405
|
/* @__PURE__ */ React2__namespace.createElement(
|
|
376
406
|
react.Reactive.View,
|
|
@@ -389,7 +419,8 @@ var LegendList = React2.forwardRef((props, forwardedRef) => {
|
|
|
389
419
|
$container: containers$[i],
|
|
390
420
|
listProps: props,
|
|
391
421
|
getRenderedItem,
|
|
392
|
-
onLayout: updateItemLength
|
|
422
|
+
onLayout: updateItemLength,
|
|
423
|
+
ItemSeparatorComponent
|
|
393
424
|
}
|
|
394
425
|
))
|
|
395
426
|
),
|
package/index.mjs
CHANGED
|
@@ -12,13 +12,15 @@ var Container = ({
|
|
|
12
12
|
recycleItems,
|
|
13
13
|
listProps,
|
|
14
14
|
getRenderedItem,
|
|
15
|
-
onLayout
|
|
15
|
+
onLayout,
|
|
16
|
+
ItemSeparatorComponent
|
|
16
17
|
}) => {
|
|
17
18
|
const { horizontal } = listProps;
|
|
18
19
|
const { id } = $container.peek();
|
|
19
20
|
const itemIndex = use$($container.itemIndex);
|
|
20
21
|
const key = recycleItems ? void 0 : itemIndex;
|
|
21
22
|
const createStyle = () => horizontal ? {
|
|
23
|
+
flexDirection: "row",
|
|
22
24
|
position: "absolute",
|
|
23
25
|
top: 0,
|
|
24
26
|
bottom: 0,
|
|
@@ -42,7 +44,8 @@ var Container = ({
|
|
|
42
44
|
onLayout(index, length);
|
|
43
45
|
}
|
|
44
46
|
},
|
|
45
|
-
/* @__PURE__ */ React2.createElement(View, { key }, getRenderedItem(itemIndex))
|
|
47
|
+
/* @__PURE__ */ React2.createElement(View, { key }, getRenderedItem(itemIndex)),
|
|
48
|
+
ItemSeparatorComponent && itemIndex !== listProps.data.length - 1 && /* @__PURE__ */ React2.createElement(Reactive.View, null, ItemSeparatorComponent)
|
|
46
49
|
);
|
|
47
50
|
};
|
|
48
51
|
|
|
@@ -50,7 +53,7 @@ var Container = ({
|
|
|
50
53
|
enableReactNativeComponents();
|
|
51
54
|
var DEFAULT_SCROLL_BUFFER = 0;
|
|
52
55
|
var POSITION_OUT_OF_VIEW = -1e4;
|
|
53
|
-
var LegendList = forwardRef((props, forwardedRef)
|
|
56
|
+
var LegendList = forwardRef(function LegendList2(props, forwardedRef) {
|
|
54
57
|
const {
|
|
55
58
|
data,
|
|
56
59
|
initialScrollIndex,
|
|
@@ -64,6 +67,7 @@ var LegendList = forwardRef((props, forwardedRef) => {
|
|
|
64
67
|
onEndReachedThreshold,
|
|
65
68
|
autoScrollToBottom = false,
|
|
66
69
|
autoScrollToBottomThreshold = 0.1,
|
|
70
|
+
startAtBottom = false,
|
|
67
71
|
keyExtractor,
|
|
68
72
|
renderItem,
|
|
69
73
|
estimatedItemLength,
|
|
@@ -73,11 +77,13 @@ var LegendList = forwardRef((props, forwardedRef) => {
|
|
|
73
77
|
ListHeaderComponentStyle,
|
|
74
78
|
ListFooterComponent,
|
|
75
79
|
ListFooterComponentStyle,
|
|
80
|
+
ItemSeparatorComponent,
|
|
76
81
|
...rest
|
|
77
82
|
} = props;
|
|
78
83
|
const internalRef = useRef(null);
|
|
79
84
|
const refScroller = forwardedRef || internalRef;
|
|
80
85
|
const containers$ = useObservable(() => []);
|
|
86
|
+
const paddingTop$ = useObservable(0);
|
|
81
87
|
const visibleRange$ = useObservable(() => ({
|
|
82
88
|
start: 0,
|
|
83
89
|
end: 0,
|
|
@@ -107,15 +113,24 @@ var LegendList = forwardRef((props, forwardedRef) => {
|
|
|
107
113
|
isAtBottom: false,
|
|
108
114
|
data,
|
|
109
115
|
idsInFirstRender: void 0,
|
|
110
|
-
hasScrolled: false
|
|
116
|
+
hasScrolled: false,
|
|
117
|
+
scrollLength: Dimensions.get("window")[horizontal ? "width" : "height"]
|
|
111
118
|
};
|
|
112
119
|
refPositions.current.idsInFirstRender = new Set(data.map((_, i) => getId(i)));
|
|
113
120
|
}
|
|
114
121
|
refPositions.current.data = data;
|
|
115
|
-
const SCREEN_LENGTH = Dimensions.get("window")[horizontal ? "width" : "height"];
|
|
116
122
|
const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : initialScrollIndex ? initialScrollIndex * estimatedItemLength(initialScrollIndex) : void 0;
|
|
123
|
+
const setTotalLength = (length) => {
|
|
124
|
+
visibleRange$.totalLength.set(length);
|
|
125
|
+
const screenLength = refPositions.current.scrollLength;
|
|
126
|
+
if (startAtBottom) {
|
|
127
|
+
const listPaddingTop = ((style == null ? void 0 : style.paddingTop) || 0) + ((contentContainerStyle == null ? void 0 : contentContainerStyle.paddingTop) || 0);
|
|
128
|
+
paddingTop$.set(Math.max(0, screenLength - length - listPaddingTop));
|
|
129
|
+
}
|
|
130
|
+
};
|
|
117
131
|
const allocateContainers = useCallback(() => {
|
|
118
|
-
const
|
|
132
|
+
const scrollLength = refPositions.current.scrollLength;
|
|
133
|
+
const numContainers = initialContainers || Math.ceil((scrollLength + scrollBuffer * 2) / estimatedItemLength(0)) + 4;
|
|
119
134
|
const containers2 = [];
|
|
120
135
|
for (let i = 0; i < numContainers; i++) {
|
|
121
136
|
containers2.push({
|
|
@@ -143,7 +158,7 @@ var LegendList = forwardRef((props, forwardedRef) => {
|
|
|
143
158
|
);
|
|
144
159
|
const calculateItemsInView = useCallback(() => {
|
|
145
160
|
var _a, _b;
|
|
146
|
-
const data2 = refPositions.current
|
|
161
|
+
const { data: data2, scrollLength } = refPositions.current;
|
|
147
162
|
if (!data2) {
|
|
148
163
|
return;
|
|
149
164
|
}
|
|
@@ -169,10 +184,10 @@ var LegendList = forwardRef((props, forwardedRef) => {
|
|
|
169
184
|
startBuffered = i;
|
|
170
185
|
}
|
|
171
186
|
if (startNoBuffer !== null) {
|
|
172
|
-
if (top <= scroll +
|
|
187
|
+
if (top <= scroll + scrollLength) {
|
|
173
188
|
endNoBuffer = i;
|
|
174
189
|
}
|
|
175
|
-
if (top <= scroll +
|
|
190
|
+
if (top <= scroll + scrollLength + scrollBuffer) {
|
|
176
191
|
endBuffered = i;
|
|
177
192
|
} else {
|
|
178
193
|
break;
|
|
@@ -261,12 +276,34 @@ var LegendList = forwardRef((props, forwardedRef) => {
|
|
|
261
276
|
const id = getId(i);
|
|
262
277
|
totalLength += (_b = lengths.get(id)) != null ? _b : estimatedItemLength(i);
|
|
263
278
|
}
|
|
264
|
-
|
|
279
|
+
setTotalLength(totalLength);
|
|
265
280
|
}, []);
|
|
281
|
+
const checkAtBottom = () => {
|
|
282
|
+
var _a;
|
|
283
|
+
const scrollLength = refPositions.current.scrollLength;
|
|
284
|
+
const newScroll = visibleRange$.scroll.peek();
|
|
285
|
+
const distanceFromEnd = visibleRange$.totalLength.peek() - newScroll - scrollLength;
|
|
286
|
+
if (refPositions.current) {
|
|
287
|
+
refPositions.current.isAtBottom = distanceFromEnd < scrollLength * autoScrollToBottomThreshold;
|
|
288
|
+
}
|
|
289
|
+
if (onEndReached && !((_a = refPositions.current) == null ? void 0 : _a.isEndReached)) {
|
|
290
|
+
if (distanceFromEnd < (onEndReachedThreshold || 0.5) * scrollLength) {
|
|
291
|
+
if (refPositions.current) {
|
|
292
|
+
refPositions.current.isEndReached = true;
|
|
293
|
+
}
|
|
294
|
+
onEndReached({ distanceFromEnd });
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
};
|
|
266
298
|
useMemo(() => {
|
|
299
|
+
var _a;
|
|
267
300
|
if (refPositions.current) {
|
|
268
|
-
refPositions.current.
|
|
301
|
+
if (!((_a = refPositions.current) == null ? void 0 : _a.isAtBottom)) {
|
|
302
|
+
refPositions.current.isEndReached = false;
|
|
303
|
+
}
|
|
269
304
|
}
|
|
305
|
+
calculateItemsInView();
|
|
306
|
+
checkAtBottom();
|
|
270
307
|
}, [data]);
|
|
271
308
|
const containers = use$(containers$, { shallow: true });
|
|
272
309
|
const updateItemLength = useCallback((index, length) => {
|
|
@@ -282,7 +319,7 @@ var LegendList = forwardRef((props, forwardedRef) => {
|
|
|
282
319
|
if (!prevLength || prevLength !== length) {
|
|
283
320
|
beginBatch();
|
|
284
321
|
lengths.set(id, length);
|
|
285
|
-
visibleRange$.totalLength.
|
|
322
|
+
setTotalLength(visibleRange$.totalLength.peek() + (length - prevLength));
|
|
286
323
|
if (((_d = refPositions.current) == null ? void 0 : _d.isAtBottom) && autoScrollToBottom) {
|
|
287
324
|
requestAnimationFrame(() => {
|
|
288
325
|
var _a2;
|
|
@@ -298,25 +335,16 @@ var LegendList = forwardRef((props, forwardedRef) => {
|
|
|
298
335
|
}
|
|
299
336
|
}, []);
|
|
300
337
|
const handleScrollDebounced = useCallback(() => {
|
|
301
|
-
var _a;
|
|
302
|
-
const newScroll = visibleRange$.scroll.peek();
|
|
303
338
|
calculateItemsInView();
|
|
304
|
-
|
|
305
|
-
if (refPositions.current) {
|
|
306
|
-
refPositions.current.isAtBottom = distanceFromEnd < SCREEN_LENGTH * autoScrollToBottomThreshold;
|
|
307
|
-
}
|
|
308
|
-
if (onEndReached && !((_a = refPositions.current) == null ? void 0 : _a.isEndReached)) {
|
|
309
|
-
if (distanceFromEnd < (onEndReachedThreshold || 0.5) * SCREEN_LENGTH) {
|
|
310
|
-
if (refPositions.current) {
|
|
311
|
-
refPositions.current.isEndReached = true;
|
|
312
|
-
}
|
|
313
|
-
onEndReached({ distanceFromEnd });
|
|
314
|
-
}
|
|
315
|
-
}
|
|
339
|
+
checkAtBottom();
|
|
316
340
|
if (refPositions.current) {
|
|
317
341
|
refPositions.current.animFrame = null;
|
|
318
342
|
}
|
|
319
343
|
}, []);
|
|
344
|
+
const onLayout = (event) => {
|
|
345
|
+
const scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
346
|
+
refPositions.current.scrollLength = scrollLength;
|
|
347
|
+
};
|
|
320
348
|
const handleScroll = useCallback((event) => {
|
|
321
349
|
refPositions.current.hasScrolled = true;
|
|
322
350
|
const newScroll = event.nativeEvent.contentOffset[horizontal ? "x" : "y"];
|
|
@@ -344,12 +372,14 @@ var LegendList = forwardRef((props, forwardedRef) => {
|
|
|
344
372
|
} : {}
|
|
345
373
|
],
|
|
346
374
|
onScroll: handleScroll,
|
|
375
|
+
onLayout,
|
|
347
376
|
scrollEventThrottle: 32,
|
|
348
377
|
horizontal,
|
|
349
378
|
contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
|
|
350
379
|
...rest,
|
|
351
380
|
ref: refScroller
|
|
352
381
|
},
|
|
382
|
+
startAtBottom && /* @__PURE__ */ React2.createElement(Reactive.View, { $style: () => ({ height: paddingTop$.get() }) }),
|
|
353
383
|
ListHeaderComponent && /* @__PURE__ */ React2.createElement(Reactive.View, { $style: ListHeaderComponentStyle }, ListHeaderComponent),
|
|
354
384
|
/* @__PURE__ */ React2.createElement(
|
|
355
385
|
Reactive.View,
|
|
@@ -368,7 +398,8 @@ var LegendList = forwardRef((props, forwardedRef) => {
|
|
|
368
398
|
$container: containers$[i],
|
|
369
399
|
listProps: props,
|
|
370
400
|
getRenderedItem,
|
|
371
|
-
onLayout: updateItemLength
|
|
401
|
+
onLayout: updateItemLength,
|
|
402
|
+
ItemSeparatorComponent
|
|
372
403
|
}
|
|
373
404
|
))
|
|
374
405
|
),
|