@legendapp/list 0.4.2 → 0.4.4
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 +0 -1
- package/index.d.mts +13 -2
- package/index.d.ts +13 -2
- package/index.js +98 -39
- package/index.mjs +98 -39
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,7 +48,6 @@ interface PropsOptional {
|
|
|
48
48
|
maintainScrollAtEndThreshold?: number;
|
|
49
49
|
onEndReached?: ((info: { distanceFromEnd: number }) => void) | null | undefined;
|
|
50
50
|
keyExtractor?: (item: T, index: number) => string;
|
|
51
|
-
onViewableRangeChanged?: (range: ViewableRange<T>) => void;
|
|
52
51
|
}
|
|
53
52
|
```
|
|
54
53
|
|
package/index.d.mts
CHANGED
|
@@ -19,11 +19,12 @@ type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset
|
|
|
19
19
|
}) => void) | null | undefined;
|
|
20
20
|
keyExtractor?: (item: T, index: number) => string;
|
|
21
21
|
renderItem?: (props: LegendListRenderItemProps<T>) => ReactNode;
|
|
22
|
-
onViewableRangeChanged?: (range: ViewableRange<T>) => void;
|
|
23
22
|
ListHeaderComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
24
23
|
ListHeaderComponentStyle?: StyleProp<ViewStyle> | undefined;
|
|
25
24
|
ListFooterComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
26
25
|
ListFooterComponentStyle?: StyleProp<ViewStyle> | undefined;
|
|
26
|
+
ListEmptyComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
27
|
+
ListEmptyComponentStyle?: StyleProp<ViewStyle> | undefined;
|
|
27
28
|
ItemSeparatorComponent?: React.ComponentType<any>;
|
|
28
29
|
viewabilityConfigCallbackPairs?: ViewabilityConfigCallbackPairs | undefined;
|
|
29
30
|
viewabilityConfig?: ViewabilityConfig;
|
|
@@ -63,6 +64,7 @@ interface LegendListRenderItemProps<ItemT> {
|
|
|
63
64
|
item: ItemT;
|
|
64
65
|
index: number;
|
|
65
66
|
useViewability: (configId: string, callback: ViewabilityCallback) => void;
|
|
67
|
+
useViewabilityAmount: (callback: ViewabilityAmountCallback) => void;
|
|
66
68
|
useRecyclingEffect: (effect: (info: LegendListRecyclingState<ItemT>) => void | (() => void)) => void;
|
|
67
69
|
useRecyclingState: <T>(updateState: (info: LegendListRecyclingState<ItemT>) => T) => [T, React.Dispatch<T>];
|
|
68
70
|
}
|
|
@@ -107,6 +109,14 @@ interface ViewToken<ItemT = any> {
|
|
|
107
109
|
index: number;
|
|
108
110
|
isViewable: boolean;
|
|
109
111
|
}
|
|
112
|
+
interface ViewAmountToken<ItemT = any> extends ViewToken<ItemT> {
|
|
113
|
+
sizeVisible: number;
|
|
114
|
+
size: number;
|
|
115
|
+
percentVisible: number;
|
|
116
|
+
percentOfScroller: number;
|
|
117
|
+
position: number;
|
|
118
|
+
scrollSize: number;
|
|
119
|
+
}
|
|
110
120
|
interface ViewabilityConfigCallbackPair {
|
|
111
121
|
viewabilityConfig: ViewabilityConfig;
|
|
112
122
|
onViewableItemsChanged?: OnViewableItemsChanged;
|
|
@@ -146,6 +156,7 @@ interface ViewabilityConfig {
|
|
|
146
156
|
waitForInteraction?: boolean | undefined;
|
|
147
157
|
}
|
|
148
158
|
type ViewabilityCallback = (viewToken: ViewToken) => void;
|
|
159
|
+
type ViewabilityAmountCallback = (viewToken: ViewAmountToken) => void;
|
|
149
160
|
interface LegendListRecyclingState<T> {
|
|
150
161
|
item: T;
|
|
151
162
|
prevItem: T | undefined;
|
|
@@ -157,4 +168,4 @@ declare const LegendList: <T>(props: LegendListProps<T> & {
|
|
|
157
168
|
ref?: ForwardedRef<LegendListRef>;
|
|
158
169
|
}) => ReactElement;
|
|
159
170
|
|
|
160
|
-
export { type InternalState, LegendList, type LegendListProps, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type OnViewableItemsChanged, type ViewToken, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, type ViewableRange };
|
|
171
|
+
export { type InternalState, LegendList, type LegendListProps, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type OnViewableItemsChanged, type ViewAmountToken, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, type ViewableRange };
|
package/index.d.ts
CHANGED
|
@@ -19,11 +19,12 @@ type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset
|
|
|
19
19
|
}) => void) | null | undefined;
|
|
20
20
|
keyExtractor?: (item: T, index: number) => string;
|
|
21
21
|
renderItem?: (props: LegendListRenderItemProps<T>) => ReactNode;
|
|
22
|
-
onViewableRangeChanged?: (range: ViewableRange<T>) => void;
|
|
23
22
|
ListHeaderComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
24
23
|
ListHeaderComponentStyle?: StyleProp<ViewStyle> | undefined;
|
|
25
24
|
ListFooterComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
26
25
|
ListFooterComponentStyle?: StyleProp<ViewStyle> | undefined;
|
|
26
|
+
ListEmptyComponent?: React.ComponentType<any> | React.ReactElement | null | undefined;
|
|
27
|
+
ListEmptyComponentStyle?: StyleProp<ViewStyle> | undefined;
|
|
27
28
|
ItemSeparatorComponent?: React.ComponentType<any>;
|
|
28
29
|
viewabilityConfigCallbackPairs?: ViewabilityConfigCallbackPairs | undefined;
|
|
29
30
|
viewabilityConfig?: ViewabilityConfig;
|
|
@@ -63,6 +64,7 @@ interface LegendListRenderItemProps<ItemT> {
|
|
|
63
64
|
item: ItemT;
|
|
64
65
|
index: number;
|
|
65
66
|
useViewability: (configId: string, callback: ViewabilityCallback) => void;
|
|
67
|
+
useViewabilityAmount: (callback: ViewabilityAmountCallback) => void;
|
|
66
68
|
useRecyclingEffect: (effect: (info: LegendListRecyclingState<ItemT>) => void | (() => void)) => void;
|
|
67
69
|
useRecyclingState: <T>(updateState: (info: LegendListRecyclingState<ItemT>) => T) => [T, React.Dispatch<T>];
|
|
68
70
|
}
|
|
@@ -107,6 +109,14 @@ interface ViewToken<ItemT = any> {
|
|
|
107
109
|
index: number;
|
|
108
110
|
isViewable: boolean;
|
|
109
111
|
}
|
|
112
|
+
interface ViewAmountToken<ItemT = any> extends ViewToken<ItemT> {
|
|
113
|
+
sizeVisible: number;
|
|
114
|
+
size: number;
|
|
115
|
+
percentVisible: number;
|
|
116
|
+
percentOfScroller: number;
|
|
117
|
+
position: number;
|
|
118
|
+
scrollSize: number;
|
|
119
|
+
}
|
|
110
120
|
interface ViewabilityConfigCallbackPair {
|
|
111
121
|
viewabilityConfig: ViewabilityConfig;
|
|
112
122
|
onViewableItemsChanged?: OnViewableItemsChanged;
|
|
@@ -146,6 +156,7 @@ interface ViewabilityConfig {
|
|
|
146
156
|
waitForInteraction?: boolean | undefined;
|
|
147
157
|
}
|
|
148
158
|
type ViewabilityCallback = (viewToken: ViewToken) => void;
|
|
159
|
+
type ViewabilityAmountCallback = (viewToken: ViewAmountToken) => void;
|
|
149
160
|
interface LegendListRecyclingState<T> {
|
|
150
161
|
item: T;
|
|
151
162
|
prevItem: T | undefined;
|
|
@@ -157,4 +168,4 @@ declare const LegendList: <T>(props: LegendListProps<T> & {
|
|
|
157
168
|
ref?: ForwardedRef<LegendListRef>;
|
|
158
169
|
}) => ReactElement;
|
|
159
170
|
|
|
160
|
-
export { type InternalState, LegendList, type LegendListProps, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type OnViewableItemsChanged, type ViewToken, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, type ViewableRange };
|
|
171
|
+
export { type InternalState, LegendList, type LegendListProps, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type OnViewableItemsChanged, type ViewAmountToken, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, type ViewableRange };
|
package/index.js
CHANGED
|
@@ -213,6 +213,8 @@ var ListComponent = React6__namespace.memo(function ListComponent2({
|
|
|
213
213
|
ListHeaderComponentStyle,
|
|
214
214
|
ListFooterComponent,
|
|
215
215
|
ListFooterComponentStyle,
|
|
216
|
+
ListEmptyComponent,
|
|
217
|
+
ListEmptyComponentStyle,
|
|
216
218
|
getRenderedItem,
|
|
217
219
|
updateItemSize,
|
|
218
220
|
addTotalSize,
|
|
@@ -254,6 +256,13 @@ var ListComponent = React6__namespace.memo(function ListComponent2({
|
|
|
254
256
|
},
|
|
255
257
|
getComponent(ListHeaderComponent)
|
|
256
258
|
),
|
|
259
|
+
ListEmptyComponent && /* @__PURE__ */ React6__namespace.createElement(
|
|
260
|
+
reactNative.View,
|
|
261
|
+
{
|
|
262
|
+
style: ListEmptyComponentStyle
|
|
263
|
+
},
|
|
264
|
+
getComponent(ListEmptyComponent)
|
|
265
|
+
),
|
|
257
266
|
/* @__PURE__ */ React6__namespace.createElement(
|
|
258
267
|
Containers,
|
|
259
268
|
{
|
|
@@ -271,6 +280,9 @@ var ListComponent = React6__namespace.memo(function ListComponent2({
|
|
|
271
280
|
// src/viewability.ts
|
|
272
281
|
var mapViewabilityConfigCallbackPairs = /* @__PURE__ */ new Map();
|
|
273
282
|
var mapViewabilityCallbacks = /* @__PURE__ */ new Map();
|
|
283
|
+
var mapViewabilityValues = /* @__PURE__ */ new Map();
|
|
284
|
+
var mapViewabilityAmountCallbacks = /* @__PURE__ */ new Map();
|
|
285
|
+
var mapViewabilityAmountValues = /* @__PURE__ */ new Map();
|
|
274
286
|
function setupViewability(props) {
|
|
275
287
|
let { viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged } = props;
|
|
276
288
|
viewabilityConfigCallbackPairs = viewabilityConfigCallbackPairs || [
|
|
@@ -315,7 +327,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
|
|
|
315
327
|
const changed = [];
|
|
316
328
|
if (previousViewableItems) {
|
|
317
329
|
for (const viewToken of previousViewableItems) {
|
|
318
|
-
if (!isViewable(state, ctx, viewabilityConfig, viewToken.key, scrollSize)) {
|
|
330
|
+
if (!isViewable(state, ctx, viewabilityConfig, viewToken.key, scrollSize, viewToken.item, viewToken.index)) {
|
|
319
331
|
viewToken.isViewable = false;
|
|
320
332
|
changed.push(viewToken);
|
|
321
333
|
}
|
|
@@ -326,7 +338,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
|
|
|
326
338
|
const item = data[i];
|
|
327
339
|
if (item) {
|
|
328
340
|
const key = getId(i);
|
|
329
|
-
if (isViewable(state, ctx, viewabilityConfig, key, scrollSize)) {
|
|
341
|
+
if (isViewable(state, ctx, viewabilityConfig, key, scrollSize, item, i)) {
|
|
330
342
|
const viewToken = {
|
|
331
343
|
item,
|
|
332
344
|
key,
|
|
@@ -342,7 +354,6 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
|
|
|
342
354
|
}
|
|
343
355
|
Object.assign(viewabilityState, { viewableItems, previousStart: start, previousEnd: end });
|
|
344
356
|
if (changed.length > 0) {
|
|
345
|
-
console.log("changed", changed);
|
|
346
357
|
viewabilityState.viewableItems = viewableItems;
|
|
347
358
|
for (let i = 0; i < changed.length; i++) {
|
|
348
359
|
const change = changed[i];
|
|
@@ -353,7 +364,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
|
|
|
353
364
|
}
|
|
354
365
|
}
|
|
355
366
|
}
|
|
356
|
-
function isViewable(state, ctx, viewabilityConfig, key, scrollSize) {
|
|
367
|
+
function isViewable(state, ctx, viewabilityConfig, key, scrollSize, item, index) {
|
|
357
368
|
const { sizes, positions, scroll } = state;
|
|
358
369
|
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
359
370
|
const { itemVisiblePercentThreshold, viewAreaCoveragePercentThreshold } = viewabilityConfig;
|
|
@@ -363,25 +374,60 @@ function isViewable(state, ctx, viewabilityConfig, key, scrollSize) {
|
|
|
363
374
|
const size = sizes.get(key) || 0;
|
|
364
375
|
const bottom = top + size;
|
|
365
376
|
const isEntirelyVisible = top >= 0 && bottom <= scrollSize && bottom > top;
|
|
366
|
-
|
|
367
|
-
|
|
377
|
+
const sizeVisible = isEntirelyVisible ? size : Math.min(bottom, scrollSize) - Math.max(top, 0);
|
|
378
|
+
const percentVisible = size ? isEntirelyVisible ? 100 : 100 * (sizeVisible / size) : 0;
|
|
379
|
+
const percentOfScroller = size ? 100 * (sizeVisible / scrollSize) : 0;
|
|
380
|
+
const percent = isEntirelyVisible ? 100 : viewAreaMode ? percentOfScroller : percentVisible;
|
|
381
|
+
const isViewable2 = percent >= viewablePercentThreshold;
|
|
382
|
+
const containerId = findContainerId(state, ctx, index);
|
|
383
|
+
const value = {
|
|
384
|
+
index,
|
|
385
|
+
isViewable: isViewable2,
|
|
386
|
+
item,
|
|
387
|
+
key,
|
|
388
|
+
percentVisible,
|
|
389
|
+
percentOfScroller,
|
|
390
|
+
sizeVisible,
|
|
391
|
+
size,
|
|
392
|
+
position: top,
|
|
393
|
+
scrollSize
|
|
394
|
+
};
|
|
395
|
+
mapViewabilityAmountValues.set(containerId, value);
|
|
396
|
+
const cb = mapViewabilityAmountCallbacks.get(containerId);
|
|
397
|
+
if (cb) {
|
|
398
|
+
cb(value);
|
|
399
|
+
}
|
|
400
|
+
return isViewable2;
|
|
401
|
+
}
|
|
402
|
+
function findContainerId(state, ctx, index) {
|
|
403
|
+
const numContainers = peek$(ctx, "numContainers");
|
|
404
|
+
for (let i = 0; i < numContainers; i++) {
|
|
405
|
+
const itemIndex = peek$(ctx, `containerIndex${i}`);
|
|
406
|
+
if (itemIndex === index) {
|
|
407
|
+
return i;
|
|
408
|
+
}
|
|
368
409
|
}
|
|
369
|
-
|
|
370
|
-
const percent = 100 * (visibleHeight / (viewAreaMode ? scrollSize : size));
|
|
371
|
-
return percent >= viewablePercentThreshold;
|
|
410
|
+
return -1;
|
|
372
411
|
}
|
|
373
412
|
function maybeUpdateViewabilityCallback(configId, viewToken) {
|
|
374
413
|
const key = viewToken.key + configId;
|
|
414
|
+
mapViewabilityValues.set(key, viewToken);
|
|
375
415
|
const cb = mapViewabilityCallbacks.get(key);
|
|
376
416
|
cb == null ? void 0 : cb(viewToken);
|
|
377
417
|
}
|
|
378
|
-
function registerViewabilityCallback(
|
|
379
|
-
const key =
|
|
418
|
+
function registerViewabilityCallback(containerId, configId, callback) {
|
|
419
|
+
const key = containerId + configId;
|
|
380
420
|
mapViewabilityCallbacks.set(key, callback);
|
|
381
421
|
return () => {
|
|
382
422
|
mapViewabilityCallbacks.delete(key);
|
|
383
423
|
};
|
|
384
424
|
}
|
|
425
|
+
function registerViewabilityAmountCallback(containerId, callback) {
|
|
426
|
+
mapViewabilityAmountCallbacks.set(containerId, callback);
|
|
427
|
+
return () => {
|
|
428
|
+
mapViewabilityAmountCallbacks.delete(containerId);
|
|
429
|
+
};
|
|
430
|
+
}
|
|
385
431
|
|
|
386
432
|
// src/LegendList.tsx
|
|
387
433
|
var DEFAULT_SCROLL_BUFFER = 0;
|
|
@@ -411,7 +457,7 @@ var LegendListInner = React6.forwardRef(function LegendListInner2(props, forward
|
|
|
411
457
|
estimatedItemSize,
|
|
412
458
|
getEstimatedItemSize,
|
|
413
459
|
onEndReached,
|
|
414
|
-
|
|
460
|
+
ListEmptyComponent,
|
|
415
461
|
...rest
|
|
416
462
|
} = props;
|
|
417
463
|
const ctx = useStateContext();
|
|
@@ -509,9 +555,23 @@ var LegendListInner = React6.forwardRef(function LegendListInner2(props, forward
|
|
|
509
555
|
if (!data2) {
|
|
510
556
|
return null;
|
|
511
557
|
}
|
|
512
|
-
const itemKey = getId(index);
|
|
513
558
|
const useViewability = (configId, callback) => {
|
|
514
|
-
React6.
|
|
559
|
+
React6.useMemo(() => {
|
|
560
|
+
const value = mapViewabilityValues.get(containerIndex + configId);
|
|
561
|
+
if (value) {
|
|
562
|
+
callback(value);
|
|
563
|
+
}
|
|
564
|
+
}, []);
|
|
565
|
+
React6.useEffect(() => registerViewabilityCallback(containerIndex, configId, callback), []);
|
|
566
|
+
};
|
|
567
|
+
const useViewabilityAmount = (callback) => {
|
|
568
|
+
React6.useMemo(() => {
|
|
569
|
+
const value = mapViewabilityAmountValues.get(containerIndex);
|
|
570
|
+
if (value) {
|
|
571
|
+
callback(value);
|
|
572
|
+
}
|
|
573
|
+
}, []);
|
|
574
|
+
React6.useEffect(() => registerViewabilityAmountCallback(containerIndex, callback), []);
|
|
515
575
|
};
|
|
516
576
|
const useRecyclingEffect = (effect) => {
|
|
517
577
|
React6.useEffect(() => {
|
|
@@ -549,7 +609,6 @@ var LegendListInner = React6.forwardRef(function LegendListInner2(props, forward
|
|
|
549
609
|
);
|
|
550
610
|
useRecyclingEffect((state) => {
|
|
551
611
|
const newState = updateState(state);
|
|
552
|
-
console.log("setting state", newState);
|
|
553
612
|
stateInfo[1](newState);
|
|
554
613
|
});
|
|
555
614
|
return stateInfo;
|
|
@@ -558,6 +617,7 @@ var LegendListInner = React6.forwardRef(function LegendListInner2(props, forward
|
|
|
558
617
|
item: data2[index],
|
|
559
618
|
index,
|
|
560
619
|
useViewability,
|
|
620
|
+
useViewabilityAmount,
|
|
561
621
|
useRecyclingEffect,
|
|
562
622
|
useRecyclingState
|
|
563
623
|
});
|
|
@@ -701,31 +761,20 @@ var LegendListInner = React6.forwardRef(function LegendListInner2(props, forward
|
|
|
701
761
|
}
|
|
702
762
|
}
|
|
703
763
|
}
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
if (refState.current.viewabilityConfigCallbackPairs) {
|
|
716
|
-
updateViewableItems(
|
|
717
|
-
refState.current,
|
|
718
|
-
ctx,
|
|
719
|
-
refState.current.viewabilityConfigCallbackPairs,
|
|
720
|
-
getId,
|
|
721
|
-
scrollLength,
|
|
722
|
-
startNoBuffer,
|
|
723
|
-
endNoBuffer
|
|
724
|
-
);
|
|
725
|
-
}
|
|
764
|
+
}
|
|
765
|
+
if (refState.current.viewabilityConfigCallbackPairs) {
|
|
766
|
+
updateViewableItems(
|
|
767
|
+
refState.current,
|
|
768
|
+
ctx,
|
|
769
|
+
refState.current.viewabilityConfigCallbackPairs,
|
|
770
|
+
getId,
|
|
771
|
+
scrollLength,
|
|
772
|
+
startNoBuffer,
|
|
773
|
+
endNoBuffer
|
|
774
|
+
);
|
|
726
775
|
}
|
|
727
776
|
});
|
|
728
|
-
}, [
|
|
777
|
+
}, []);
|
|
729
778
|
React6.useMemo(() => {
|
|
730
779
|
var _a2, _b2;
|
|
731
780
|
refState.current.viewabilityConfigCallbackPairs = setupViewability(props);
|
|
@@ -767,6 +816,15 @@ var LegendListInner = React6.forwardRef(function LegendListInner2(props, forward
|
|
|
767
816
|
if (refState.current) {
|
|
768
817
|
refState.current.isEndReached = false;
|
|
769
818
|
}
|
|
819
|
+
const numContainers = peek$(ctx, "numContainers");
|
|
820
|
+
if (data.length < numContainers) {
|
|
821
|
+
for (let i = 0; i < numContainers; i++) {
|
|
822
|
+
const itemIndex = peek$(ctx, `containerIndex${i}`);
|
|
823
|
+
if (itemIndex >= data.length) {
|
|
824
|
+
set$(ctx, `containerIndex${i}`, -1);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
}
|
|
770
828
|
calculateItemsInView();
|
|
771
829
|
checkAtBottom();
|
|
772
830
|
}, [data]);
|
|
@@ -869,7 +927,8 @@ var LegendListInner = React6.forwardRef(function LegendListInner2(props, forward
|
|
|
869
927
|
onLayout,
|
|
870
928
|
recycleItems,
|
|
871
929
|
alignItemsAtEnd,
|
|
872
|
-
addTotalSize
|
|
930
|
+
addTotalSize,
|
|
931
|
+
ListEmptyComponent: data.length === 0 ? ListEmptyComponent : void 0
|
|
873
932
|
}
|
|
874
933
|
);
|
|
875
934
|
});
|
package/index.mjs
CHANGED
|
@@ -192,6 +192,8 @@ var ListComponent = React6.memo(function ListComponent2({
|
|
|
192
192
|
ListHeaderComponentStyle,
|
|
193
193
|
ListFooterComponent,
|
|
194
194
|
ListFooterComponentStyle,
|
|
195
|
+
ListEmptyComponent,
|
|
196
|
+
ListEmptyComponentStyle,
|
|
195
197
|
getRenderedItem,
|
|
196
198
|
updateItemSize,
|
|
197
199
|
addTotalSize,
|
|
@@ -233,6 +235,13 @@ var ListComponent = React6.memo(function ListComponent2({
|
|
|
233
235
|
},
|
|
234
236
|
getComponent(ListHeaderComponent)
|
|
235
237
|
),
|
|
238
|
+
ListEmptyComponent && /* @__PURE__ */ React6.createElement(
|
|
239
|
+
View,
|
|
240
|
+
{
|
|
241
|
+
style: ListEmptyComponentStyle
|
|
242
|
+
},
|
|
243
|
+
getComponent(ListEmptyComponent)
|
|
244
|
+
),
|
|
236
245
|
/* @__PURE__ */ React6.createElement(
|
|
237
246
|
Containers,
|
|
238
247
|
{
|
|
@@ -250,6 +259,9 @@ var ListComponent = React6.memo(function ListComponent2({
|
|
|
250
259
|
// src/viewability.ts
|
|
251
260
|
var mapViewabilityConfigCallbackPairs = /* @__PURE__ */ new Map();
|
|
252
261
|
var mapViewabilityCallbacks = /* @__PURE__ */ new Map();
|
|
262
|
+
var mapViewabilityValues = /* @__PURE__ */ new Map();
|
|
263
|
+
var mapViewabilityAmountCallbacks = /* @__PURE__ */ new Map();
|
|
264
|
+
var mapViewabilityAmountValues = /* @__PURE__ */ new Map();
|
|
253
265
|
function setupViewability(props) {
|
|
254
266
|
let { viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged } = props;
|
|
255
267
|
viewabilityConfigCallbackPairs = viewabilityConfigCallbackPairs || [
|
|
@@ -294,7 +306,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
|
|
|
294
306
|
const changed = [];
|
|
295
307
|
if (previousViewableItems) {
|
|
296
308
|
for (const viewToken of previousViewableItems) {
|
|
297
|
-
if (!isViewable(state, ctx, viewabilityConfig, viewToken.key, scrollSize)) {
|
|
309
|
+
if (!isViewable(state, ctx, viewabilityConfig, viewToken.key, scrollSize, viewToken.item, viewToken.index)) {
|
|
298
310
|
viewToken.isViewable = false;
|
|
299
311
|
changed.push(viewToken);
|
|
300
312
|
}
|
|
@@ -305,7 +317,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
|
|
|
305
317
|
const item = data[i];
|
|
306
318
|
if (item) {
|
|
307
319
|
const key = getId(i);
|
|
308
|
-
if (isViewable(state, ctx, viewabilityConfig, key, scrollSize)) {
|
|
320
|
+
if (isViewable(state, ctx, viewabilityConfig, key, scrollSize, item, i)) {
|
|
309
321
|
const viewToken = {
|
|
310
322
|
item,
|
|
311
323
|
key,
|
|
@@ -321,7 +333,6 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
|
|
|
321
333
|
}
|
|
322
334
|
Object.assign(viewabilityState, { viewableItems, previousStart: start, previousEnd: end });
|
|
323
335
|
if (changed.length > 0) {
|
|
324
|
-
console.log("changed", changed);
|
|
325
336
|
viewabilityState.viewableItems = viewableItems;
|
|
326
337
|
for (let i = 0; i < changed.length; i++) {
|
|
327
338
|
const change = changed[i];
|
|
@@ -332,7 +343,7 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
|
|
|
332
343
|
}
|
|
333
344
|
}
|
|
334
345
|
}
|
|
335
|
-
function isViewable(state, ctx, viewabilityConfig, key, scrollSize) {
|
|
346
|
+
function isViewable(state, ctx, viewabilityConfig, key, scrollSize, item, index) {
|
|
336
347
|
const { sizes, positions, scroll } = state;
|
|
337
348
|
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
338
349
|
const { itemVisiblePercentThreshold, viewAreaCoveragePercentThreshold } = viewabilityConfig;
|
|
@@ -342,25 +353,60 @@ function isViewable(state, ctx, viewabilityConfig, key, scrollSize) {
|
|
|
342
353
|
const size = sizes.get(key) || 0;
|
|
343
354
|
const bottom = top + size;
|
|
344
355
|
const isEntirelyVisible = top >= 0 && bottom <= scrollSize && bottom > top;
|
|
345
|
-
|
|
346
|
-
|
|
356
|
+
const sizeVisible = isEntirelyVisible ? size : Math.min(bottom, scrollSize) - Math.max(top, 0);
|
|
357
|
+
const percentVisible = size ? isEntirelyVisible ? 100 : 100 * (sizeVisible / size) : 0;
|
|
358
|
+
const percentOfScroller = size ? 100 * (sizeVisible / scrollSize) : 0;
|
|
359
|
+
const percent = isEntirelyVisible ? 100 : viewAreaMode ? percentOfScroller : percentVisible;
|
|
360
|
+
const isViewable2 = percent >= viewablePercentThreshold;
|
|
361
|
+
const containerId = findContainerId(state, ctx, index);
|
|
362
|
+
const value = {
|
|
363
|
+
index,
|
|
364
|
+
isViewable: isViewable2,
|
|
365
|
+
item,
|
|
366
|
+
key,
|
|
367
|
+
percentVisible,
|
|
368
|
+
percentOfScroller,
|
|
369
|
+
sizeVisible,
|
|
370
|
+
size,
|
|
371
|
+
position: top,
|
|
372
|
+
scrollSize
|
|
373
|
+
};
|
|
374
|
+
mapViewabilityAmountValues.set(containerId, value);
|
|
375
|
+
const cb = mapViewabilityAmountCallbacks.get(containerId);
|
|
376
|
+
if (cb) {
|
|
377
|
+
cb(value);
|
|
378
|
+
}
|
|
379
|
+
return isViewable2;
|
|
380
|
+
}
|
|
381
|
+
function findContainerId(state, ctx, index) {
|
|
382
|
+
const numContainers = peek$(ctx, "numContainers");
|
|
383
|
+
for (let i = 0; i < numContainers; i++) {
|
|
384
|
+
const itemIndex = peek$(ctx, `containerIndex${i}`);
|
|
385
|
+
if (itemIndex === index) {
|
|
386
|
+
return i;
|
|
387
|
+
}
|
|
347
388
|
}
|
|
348
|
-
|
|
349
|
-
const percent = 100 * (visibleHeight / (viewAreaMode ? scrollSize : size));
|
|
350
|
-
return percent >= viewablePercentThreshold;
|
|
389
|
+
return -1;
|
|
351
390
|
}
|
|
352
391
|
function maybeUpdateViewabilityCallback(configId, viewToken) {
|
|
353
392
|
const key = viewToken.key + configId;
|
|
393
|
+
mapViewabilityValues.set(key, viewToken);
|
|
354
394
|
const cb = mapViewabilityCallbacks.get(key);
|
|
355
395
|
cb == null ? void 0 : cb(viewToken);
|
|
356
396
|
}
|
|
357
|
-
function registerViewabilityCallback(
|
|
358
|
-
const key =
|
|
397
|
+
function registerViewabilityCallback(containerId, configId, callback) {
|
|
398
|
+
const key = containerId + configId;
|
|
359
399
|
mapViewabilityCallbacks.set(key, callback);
|
|
360
400
|
return () => {
|
|
361
401
|
mapViewabilityCallbacks.delete(key);
|
|
362
402
|
};
|
|
363
403
|
}
|
|
404
|
+
function registerViewabilityAmountCallback(containerId, callback) {
|
|
405
|
+
mapViewabilityAmountCallbacks.set(containerId, callback);
|
|
406
|
+
return () => {
|
|
407
|
+
mapViewabilityAmountCallbacks.delete(containerId);
|
|
408
|
+
};
|
|
409
|
+
}
|
|
364
410
|
|
|
365
411
|
// src/LegendList.tsx
|
|
366
412
|
var DEFAULT_SCROLL_BUFFER = 0;
|
|
@@ -390,7 +436,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
390
436
|
estimatedItemSize,
|
|
391
437
|
getEstimatedItemSize,
|
|
392
438
|
onEndReached,
|
|
393
|
-
|
|
439
|
+
ListEmptyComponent,
|
|
394
440
|
...rest
|
|
395
441
|
} = props;
|
|
396
442
|
const ctx = useStateContext();
|
|
@@ -488,9 +534,23 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
488
534
|
if (!data2) {
|
|
489
535
|
return null;
|
|
490
536
|
}
|
|
491
|
-
const itemKey = getId(index);
|
|
492
537
|
const useViewability = (configId, callback) => {
|
|
493
|
-
|
|
538
|
+
useMemo(() => {
|
|
539
|
+
const value = mapViewabilityValues.get(containerIndex + configId);
|
|
540
|
+
if (value) {
|
|
541
|
+
callback(value);
|
|
542
|
+
}
|
|
543
|
+
}, []);
|
|
544
|
+
useEffect(() => registerViewabilityCallback(containerIndex, configId, callback), []);
|
|
545
|
+
};
|
|
546
|
+
const useViewabilityAmount = (callback) => {
|
|
547
|
+
useMemo(() => {
|
|
548
|
+
const value = mapViewabilityAmountValues.get(containerIndex);
|
|
549
|
+
if (value) {
|
|
550
|
+
callback(value);
|
|
551
|
+
}
|
|
552
|
+
}, []);
|
|
553
|
+
useEffect(() => registerViewabilityAmountCallback(containerIndex, callback), []);
|
|
494
554
|
};
|
|
495
555
|
const useRecyclingEffect = (effect) => {
|
|
496
556
|
useEffect(() => {
|
|
@@ -528,7 +588,6 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
528
588
|
);
|
|
529
589
|
useRecyclingEffect((state) => {
|
|
530
590
|
const newState = updateState(state);
|
|
531
|
-
console.log("setting state", newState);
|
|
532
591
|
stateInfo[1](newState);
|
|
533
592
|
});
|
|
534
593
|
return stateInfo;
|
|
@@ -537,6 +596,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
537
596
|
item: data2[index],
|
|
538
597
|
index,
|
|
539
598
|
useViewability,
|
|
599
|
+
useViewabilityAmount,
|
|
540
600
|
useRecyclingEffect,
|
|
541
601
|
useRecyclingState
|
|
542
602
|
});
|
|
@@ -680,31 +740,20 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
680
740
|
}
|
|
681
741
|
}
|
|
682
742
|
}
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
if (refState.current.viewabilityConfigCallbackPairs) {
|
|
695
|
-
updateViewableItems(
|
|
696
|
-
refState.current,
|
|
697
|
-
ctx,
|
|
698
|
-
refState.current.viewabilityConfigCallbackPairs,
|
|
699
|
-
getId,
|
|
700
|
-
scrollLength,
|
|
701
|
-
startNoBuffer,
|
|
702
|
-
endNoBuffer
|
|
703
|
-
);
|
|
704
|
-
}
|
|
743
|
+
}
|
|
744
|
+
if (refState.current.viewabilityConfigCallbackPairs) {
|
|
745
|
+
updateViewableItems(
|
|
746
|
+
refState.current,
|
|
747
|
+
ctx,
|
|
748
|
+
refState.current.viewabilityConfigCallbackPairs,
|
|
749
|
+
getId,
|
|
750
|
+
scrollLength,
|
|
751
|
+
startNoBuffer,
|
|
752
|
+
endNoBuffer
|
|
753
|
+
);
|
|
705
754
|
}
|
|
706
755
|
});
|
|
707
|
-
}, [
|
|
756
|
+
}, []);
|
|
708
757
|
useMemo(() => {
|
|
709
758
|
var _a2, _b2;
|
|
710
759
|
refState.current.viewabilityConfigCallbackPairs = setupViewability(props);
|
|
@@ -746,6 +795,15 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
746
795
|
if (refState.current) {
|
|
747
796
|
refState.current.isEndReached = false;
|
|
748
797
|
}
|
|
798
|
+
const numContainers = peek$(ctx, "numContainers");
|
|
799
|
+
if (data.length < numContainers) {
|
|
800
|
+
for (let i = 0; i < numContainers; i++) {
|
|
801
|
+
const itemIndex = peek$(ctx, `containerIndex${i}`);
|
|
802
|
+
if (itemIndex >= data.length) {
|
|
803
|
+
set$(ctx, `containerIndex${i}`, -1);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
}
|
|
749
807
|
calculateItemsInView();
|
|
750
808
|
checkAtBottom();
|
|
751
809
|
}, [data]);
|
|
@@ -848,7 +906,8 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
848
906
|
onLayout,
|
|
849
907
|
recycleItems,
|
|
850
908
|
alignItemsAtEnd,
|
|
851
|
-
addTotalSize
|
|
909
|
+
addTotalSize,
|
|
910
|
+
ListEmptyComponent: data.length === 0 ? ListEmptyComponent : void 0
|
|
852
911
|
}
|
|
853
912
|
);
|
|
854
913
|
});
|