@legendapp/list 0.6.2 → 0.6.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/index.d.mts +13 -4
- package/index.d.ts +13 -4
- package/index.js +130 -84
- package/index.mjs +132 -86
- package/package.json +1 -1
- package/reanimated.d.mts +1 -1
- package/reanimated.d.ts +1 -1
package/index.d.mts
CHANGED
|
@@ -29,6 +29,7 @@ type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof Scroll
|
|
|
29
29
|
maintainVisibleContentPosition?: boolean;
|
|
30
30
|
numColumns?: number;
|
|
31
31
|
refScrollView?: React.Ref<ScrollView>;
|
|
32
|
+
waitForInitialLayout?: boolean;
|
|
32
33
|
estimatedItemSize?: number;
|
|
33
34
|
getEstimatedItemSize?: (index: number, item: ItemT) => number;
|
|
34
35
|
onStartReached?: ((info: {
|
|
@@ -49,6 +50,13 @@ type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof Scroll
|
|
|
49
50
|
viewabilityConfigCallbackPairs?: ViewabilityConfigCallbackPairs | undefined;
|
|
50
51
|
viewabilityConfig?: ViewabilityConfig;
|
|
51
52
|
onViewableItemsChanged?: OnViewableItemsChanged | undefined;
|
|
53
|
+
onItemSizeChanged?: (info: {
|
|
54
|
+
size: number;
|
|
55
|
+
previous: number;
|
|
56
|
+
index: number;
|
|
57
|
+
itemKey: string;
|
|
58
|
+
itemData: ItemT;
|
|
59
|
+
}) => void;
|
|
52
60
|
};
|
|
53
61
|
type LegendListProps<ItemT> = LegendListPropsBase<ItemT, ComponentProps<typeof ScrollView>>;
|
|
54
62
|
interface InternalState {
|
|
@@ -89,10 +97,6 @@ interface InternalState {
|
|
|
89
97
|
timeoutSizeMessage: any;
|
|
90
98
|
nativeMarginTop: number;
|
|
91
99
|
indexByKey: Map<string, number>;
|
|
92
|
-
contentSize: {
|
|
93
|
-
width: number;
|
|
94
|
-
height: number;
|
|
95
|
-
};
|
|
96
100
|
viewabilityConfigCallbackPairs: ViewabilityConfigCallbackPairs | undefined;
|
|
97
101
|
renderItem: (props: LegendListRenderItemProps<any>) => ReactNode;
|
|
98
102
|
scrollHistory: Array<{
|
|
@@ -101,6 +105,11 @@ interface InternalState {
|
|
|
101
105
|
}>;
|
|
102
106
|
scrollTimer: Timer | undefined;
|
|
103
107
|
startReachedBlockedByTimer: boolean;
|
|
108
|
+
layoutsPending: Set<number>;
|
|
109
|
+
scrollForNextCalculateItemsInView: {
|
|
110
|
+
top: number;
|
|
111
|
+
bottom: number;
|
|
112
|
+
} | undefined;
|
|
104
113
|
}
|
|
105
114
|
interface ViewableRange<T> {
|
|
106
115
|
startBuffered: number;
|
package/index.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof Scroll
|
|
|
29
29
|
maintainVisibleContentPosition?: boolean;
|
|
30
30
|
numColumns?: number;
|
|
31
31
|
refScrollView?: React.Ref<ScrollView>;
|
|
32
|
+
waitForInitialLayout?: boolean;
|
|
32
33
|
estimatedItemSize?: number;
|
|
33
34
|
getEstimatedItemSize?: (index: number, item: ItemT) => number;
|
|
34
35
|
onStartReached?: ((info: {
|
|
@@ -49,6 +50,13 @@ type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof Scroll
|
|
|
49
50
|
viewabilityConfigCallbackPairs?: ViewabilityConfigCallbackPairs | undefined;
|
|
50
51
|
viewabilityConfig?: ViewabilityConfig;
|
|
51
52
|
onViewableItemsChanged?: OnViewableItemsChanged | undefined;
|
|
53
|
+
onItemSizeChanged?: (info: {
|
|
54
|
+
size: number;
|
|
55
|
+
previous: number;
|
|
56
|
+
index: number;
|
|
57
|
+
itemKey: string;
|
|
58
|
+
itemData: ItemT;
|
|
59
|
+
}) => void;
|
|
52
60
|
};
|
|
53
61
|
type LegendListProps<ItemT> = LegendListPropsBase<ItemT, ComponentProps<typeof ScrollView>>;
|
|
54
62
|
interface InternalState {
|
|
@@ -89,10 +97,6 @@ interface InternalState {
|
|
|
89
97
|
timeoutSizeMessage: any;
|
|
90
98
|
nativeMarginTop: number;
|
|
91
99
|
indexByKey: Map<string, number>;
|
|
92
|
-
contentSize: {
|
|
93
|
-
width: number;
|
|
94
|
-
height: number;
|
|
95
|
-
};
|
|
96
100
|
viewabilityConfigCallbackPairs: ViewabilityConfigCallbackPairs | undefined;
|
|
97
101
|
renderItem: (props: LegendListRenderItemProps<any>) => ReactNode;
|
|
98
102
|
scrollHistory: Array<{
|
|
@@ -101,6 +105,11 @@ interface InternalState {
|
|
|
101
105
|
}>;
|
|
102
106
|
scrollTimer: Timer | undefined;
|
|
103
107
|
startReachedBlockedByTimer: boolean;
|
|
108
|
+
layoutsPending: Set<number>;
|
|
109
|
+
scrollForNextCalculateItemsInView: {
|
|
110
|
+
top: number;
|
|
111
|
+
bottom: number;
|
|
112
|
+
} | undefined;
|
|
104
113
|
}
|
|
105
114
|
interface ViewableRange<T> {
|
|
106
115
|
startBuffered: number;
|
package/index.js
CHANGED
|
@@ -39,12 +39,16 @@ function StateProvider({ children }) {
|
|
|
39
39
|
function useStateContext() {
|
|
40
40
|
return React4__namespace.useContext(ContextState);
|
|
41
41
|
}
|
|
42
|
+
function createSelectorFunctions(ctx, signalName) {
|
|
43
|
+
return {
|
|
44
|
+
subscribe: (cb) => listen$(ctx, signalName, cb),
|
|
45
|
+
get: () => peek$(ctx, signalName)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
42
48
|
function use$(signalName) {
|
|
43
49
|
const ctx = React4__namespace.useContext(ContextState);
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
() => ctx.values.get(signalName)
|
|
47
|
-
);
|
|
50
|
+
const { subscribe, get } = React4__namespace.useMemo(() => createSelectorFunctions(ctx, signalName), []);
|
|
51
|
+
const value = React4.useSyncExternalStore(subscribe, get);
|
|
48
52
|
return value;
|
|
49
53
|
}
|
|
50
54
|
function listen$(ctx, signalName, cb) {
|
|
@@ -73,10 +77,13 @@ function set$(ctx, signalName, value) {
|
|
|
73
77
|
}
|
|
74
78
|
}
|
|
75
79
|
}
|
|
80
|
+
|
|
81
|
+
// src/Container.tsx
|
|
76
82
|
var Container = ({
|
|
77
83
|
id,
|
|
78
84
|
recycleItems,
|
|
79
85
|
horizontal,
|
|
86
|
+
waitForInitialLayout,
|
|
80
87
|
getRenderedItem,
|
|
81
88
|
updateItemSize,
|
|
82
89
|
ItemSeparatorComponent
|
|
@@ -84,11 +91,10 @@ var Container = ({
|
|
|
84
91
|
const ctx = useStateContext();
|
|
85
92
|
const position = use$(`containerPosition${id}`);
|
|
86
93
|
const column = use$(`containerColumn${id}`) || 0;
|
|
87
|
-
const visible = use$(`containerDidLayout${id}`);
|
|
88
94
|
const numColumns = use$("numColumns");
|
|
89
95
|
const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
|
|
90
96
|
const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
|
|
91
|
-
|
|
97
|
+
const style = horizontal ? {
|
|
92
98
|
flexDirection: "row",
|
|
93
99
|
position: "absolute",
|
|
94
100
|
top: otherAxisPos,
|
|
@@ -102,7 +108,8 @@ var Container = ({
|
|
|
102
108
|
width: otherAxisSize,
|
|
103
109
|
top: position
|
|
104
110
|
};
|
|
105
|
-
{
|
|
111
|
+
if (waitForInitialLayout) {
|
|
112
|
+
const visible = use$(`containerDidLayout${id}`);
|
|
106
113
|
style.opacity = visible ? 1 : 0;
|
|
107
114
|
}
|
|
108
115
|
const lastItemKey = use$("lastItemKey");
|
|
@@ -118,14 +125,6 @@ var Container = ({
|
|
|
118
125
|
if (key !== void 0) {
|
|
119
126
|
const size = Math.floor(event.nativeEvent.layout[horizontal ? "width" : "height"] * 8) / 8;
|
|
120
127
|
updateItemSize(id, key, size);
|
|
121
|
-
const otherAxisSize2 = horizontal ? event.nativeEvent.layout.width : event.nativeEvent.layout.height;
|
|
122
|
-
set$(ctx, "otherAxisSize", Math.max(otherAxisSize2, peek$(ctx, "otherAxisSize") || 0));
|
|
123
|
-
const measured = peek$(ctx, `containerDidLayout${id}`);
|
|
124
|
-
if (!measured) {
|
|
125
|
-
requestAnimationFrame(() => {
|
|
126
|
-
set$(ctx, `containerDidLayout${id}`, true);
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
128
|
}
|
|
130
129
|
}
|
|
131
130
|
},
|
|
@@ -150,6 +149,7 @@ var Containers = React4__namespace.memo(function Containers2({
|
|
|
150
149
|
horizontal,
|
|
151
150
|
recycleItems,
|
|
152
151
|
ItemSeparatorComponent,
|
|
152
|
+
waitForInitialLayout,
|
|
153
153
|
updateItemSize,
|
|
154
154
|
getRenderedItem
|
|
155
155
|
}) {
|
|
@@ -165,6 +165,7 @@ var Containers = React4__namespace.memo(function Containers2({
|
|
|
165
165
|
key: i,
|
|
166
166
|
recycleItems,
|
|
167
167
|
horizontal,
|
|
168
|
+
waitForInitialLayout,
|
|
168
169
|
getRenderedItem,
|
|
169
170
|
updateItemSize,
|
|
170
171
|
ItemSeparatorComponent
|
|
@@ -194,6 +195,7 @@ var ListComponent = React4__namespace.memo(function ListComponent2({
|
|
|
194
195
|
recycleItems,
|
|
195
196
|
ItemSeparatorComponent,
|
|
196
197
|
alignItemsAtEnd,
|
|
198
|
+
waitForInitialLayout,
|
|
197
199
|
handleScroll,
|
|
198
200
|
onLayout,
|
|
199
201
|
ListHeaderComponent,
|
|
@@ -251,6 +253,7 @@ var ListComponent = React4__namespace.memo(function ListComponent2({
|
|
|
251
253
|
{
|
|
252
254
|
horizontal,
|
|
253
255
|
recycleItems,
|
|
256
|
+
waitForInitialLayout,
|
|
254
257
|
getRenderedItem,
|
|
255
258
|
ItemSeparatorComponent: ItemSeparatorComponent && getComponent(ItemSeparatorComponent),
|
|
256
259
|
updateItemSize
|
|
@@ -460,7 +463,7 @@ var LegendList = React4.forwardRef(function LegendList2(props, forwardedRef) {
|
|
|
460
463
|
return /* @__PURE__ */ React4__namespace.createElement(StateProvider, null, /* @__PURE__ */ React4__namespace.createElement(LegendListInner, { ...props, ref: forwardedRef }));
|
|
461
464
|
});
|
|
462
465
|
var LegendListInner = React4.forwardRef(function LegendListInner2(props, forwardedRef) {
|
|
463
|
-
var _a, _b, _c, _d
|
|
466
|
+
var _a, _b, _c, _d;
|
|
464
467
|
const {
|
|
465
468
|
data,
|
|
466
469
|
initialScrollIndex,
|
|
@@ -484,6 +487,8 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
484
487
|
onEndReached,
|
|
485
488
|
onStartReached,
|
|
486
489
|
ListEmptyComponent,
|
|
490
|
+
onItemSizeChanged,
|
|
491
|
+
scrollEventThrottle,
|
|
487
492
|
refScrollView,
|
|
488
493
|
...rest
|
|
489
494
|
} = props;
|
|
@@ -561,13 +566,14 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
561
566
|
indexByKey: /* @__PURE__ */ new Map(),
|
|
562
567
|
scrollHistory: [],
|
|
563
568
|
scrollVelocity: 0,
|
|
564
|
-
contentSize: { width: 0, height: 0 },
|
|
565
569
|
sizesLaidOut: __DEV__ ? /* @__PURE__ */ new Map() : void 0,
|
|
566
570
|
timeoutSizeMessage: 0,
|
|
567
571
|
scrollTimer: void 0,
|
|
568
572
|
belowAnchorElementPositions: void 0,
|
|
569
573
|
rowHeights: /* @__PURE__ */ new Map(),
|
|
570
|
-
startReachedBlockedByTimer: false
|
|
574
|
+
startReachedBlockedByTimer: false,
|
|
575
|
+
layoutsPending: /* @__PURE__ */ new Set(),
|
|
576
|
+
scrollForNextCalculateItemsInView: void 0
|
|
571
577
|
};
|
|
572
578
|
refState.current.idsInFirstRender = new Set(data.map((_, i) => getId(i)));
|
|
573
579
|
if (maintainVisibleContentPosition) {
|
|
@@ -621,21 +627,18 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
621
627
|
state.belowAnchorElementPositions = buildElementPositionsBelowAnchor();
|
|
622
628
|
state.rowHeights.clear();
|
|
623
629
|
}
|
|
624
|
-
const
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
}
|
|
637
|
-
};
|
|
638
|
-
doAdd();
|
|
630
|
+
const totalSize = state.totalSize;
|
|
631
|
+
let resultSize = totalSize;
|
|
632
|
+
if (applyAdjustValue !== void 0) {
|
|
633
|
+
resultSize -= applyAdjustValue;
|
|
634
|
+
refState.current.scrollAdjustHandler.requestAdjust(applyAdjustValue, (diff) => {
|
|
635
|
+
state.scroll -= diff;
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
set$(ctx, "totalSize", resultSize);
|
|
639
|
+
if (alignItemsAtEnd) {
|
|
640
|
+
doUpdatePaddingTop();
|
|
641
|
+
}
|
|
639
642
|
}, []);
|
|
640
643
|
const getRowHeight = (n) => {
|
|
641
644
|
const { rowHeights } = refState.current;
|
|
@@ -698,7 +701,8 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
698
701
|
startBufferedId: startBufferedIdOrig,
|
|
699
702
|
positions,
|
|
700
703
|
columns,
|
|
701
|
-
scrollAdjustHandler
|
|
704
|
+
scrollAdjustHandler,
|
|
705
|
+
layoutsPending
|
|
702
706
|
} = state;
|
|
703
707
|
if (state.animFrameLayout) {
|
|
704
708
|
cancelAnimationFrame(state.animFrameLayout);
|
|
@@ -711,6 +715,12 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
711
715
|
const previousScrollAdjust = scrollAdjustHandler.getAppliedAdjust();
|
|
712
716
|
const scrollExtra = Math.max(-16, Math.min(16, speed)) * 16;
|
|
713
717
|
const scroll = scrollState - previousScrollAdjust - topPad - scrollExtra;
|
|
718
|
+
if (refState.current.scrollForNextCalculateItemsInView) {
|
|
719
|
+
const { top: top2, bottom } = refState.current.scrollForNextCalculateItemsInView;
|
|
720
|
+
if (scroll > top2 && scroll < bottom) {
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
714
724
|
const scrollBottom = scroll + scrollLength;
|
|
715
725
|
let startNoBuffer = null;
|
|
716
726
|
let startBuffered = null;
|
|
@@ -804,6 +814,14 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
804
814
|
endBuffered,
|
|
805
815
|
endNoBuffer
|
|
806
816
|
});
|
|
817
|
+
const nextTop = Math.ceil(startBuffered ? positions.get(startBufferedId) + scrollBuffer : 0);
|
|
818
|
+
const nextBottom = Math.floor(
|
|
819
|
+
endBuffered ? (positions.get(getId(endBuffered + 1)) || 0) - scrollLength - scrollBuffer : 0
|
|
820
|
+
);
|
|
821
|
+
refState.current.scrollForNextCalculateItemsInView = nextTop >= 0 && nextBottom >= 0 ? {
|
|
822
|
+
top: nextTop,
|
|
823
|
+
bottom: nextBottom
|
|
824
|
+
} : void 0;
|
|
807
825
|
if (startBuffered !== null && endBuffered !== null) {
|
|
808
826
|
const prevNumContainers = ctx.values.get("numContainers");
|
|
809
827
|
let numContainers = prevNumContainers;
|
|
@@ -846,7 +864,7 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
846
864
|
numContainers++;
|
|
847
865
|
set$(ctx, `containerItemKey${containerId}`, id);
|
|
848
866
|
const index = (_c2 = refState.current) == null ? void 0 : _c2.indexByKey.get(id);
|
|
849
|
-
set$(ctx, `containerItemData${
|
|
867
|
+
set$(ctx, `containerItemData${containerId}`, data2[index]);
|
|
850
868
|
set$(ctx, `containerPosition${containerId}`, POSITION_OUT_OF_VIEW);
|
|
851
869
|
set$(ctx, `containerColumn${containerId}`, -1);
|
|
852
870
|
if (__DEV__ && numContainers > peek$(ctx, "numContainersPooled")) {
|
|
@@ -896,6 +914,12 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
896
914
|
}
|
|
897
915
|
}
|
|
898
916
|
}
|
|
917
|
+
if (layoutsPending.size > 0) {
|
|
918
|
+
for (const containerId of layoutsPending) {
|
|
919
|
+
set$(ctx, `containerDidLayout${containerId}`, true);
|
|
920
|
+
}
|
|
921
|
+
layoutsPending.clear();
|
|
922
|
+
}
|
|
899
923
|
if (refState.current.viewabilityConfigCallbackPairs) {
|
|
900
924
|
updateViewableItems(
|
|
901
925
|
refState.current,
|
|
@@ -917,25 +941,25 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
917
941
|
}
|
|
918
942
|
};
|
|
919
943
|
const doMaintainScrollAtEnd = (animated) => {
|
|
920
|
-
|
|
921
|
-
if ((
|
|
922
|
-
|
|
944
|
+
const state = refState.current;
|
|
945
|
+
if ((state == null ? void 0 : state.isAtBottom) && maintainScrollAtEnd) {
|
|
946
|
+
state.scroll = state.totalSize - state.scrollLength + peek$(ctx, "paddingTop");
|
|
923
947
|
requestAnimationFrame(() => {
|
|
924
|
-
var
|
|
925
|
-
(
|
|
948
|
+
var _a2;
|
|
949
|
+
(_a2 = refScroller.current) == null ? void 0 : _a2.scrollToEnd({
|
|
926
950
|
animated
|
|
927
951
|
});
|
|
928
952
|
});
|
|
953
|
+
return true;
|
|
929
954
|
}
|
|
930
955
|
};
|
|
931
956
|
const checkAtBottom = () => {
|
|
932
957
|
if (!refState.current) {
|
|
933
958
|
return;
|
|
934
959
|
}
|
|
935
|
-
const { scrollLength, scroll,
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
const distanceFromEnd = contentLength - scroll - scrollLength;
|
|
960
|
+
const { scrollLength, scroll, totalSize } = refState.current;
|
|
961
|
+
if (totalSize > 0) {
|
|
962
|
+
const distanceFromEnd = totalSize - scroll - scrollLength;
|
|
939
963
|
if (refState.current) {
|
|
940
964
|
refState.current.isAtBottom = distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
941
965
|
}
|
|
@@ -977,6 +1001,35 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
977
1001
|
}
|
|
978
1002
|
}
|
|
979
1003
|
};
|
|
1004
|
+
const checkResetContainers = (reset) => {
|
|
1005
|
+
const state = refState.current;
|
|
1006
|
+
if (state) {
|
|
1007
|
+
state.data = data;
|
|
1008
|
+
if (reset) {
|
|
1009
|
+
refState.current.scrollForNextCalculateItemsInView = void 0;
|
|
1010
|
+
const numContainers = peek$(ctx, "numContainers");
|
|
1011
|
+
for (let i = 0; i < numContainers; i++) {
|
|
1012
|
+
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1013
|
+
if (!keyExtractorProp || itemKey && state.indexByKey.get(itemKey) === void 0) {
|
|
1014
|
+
set$(ctx, `containerItemKey${i}`, void 0);
|
|
1015
|
+
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
1016
|
+
set$(ctx, `containerColumn${i}`, -1);
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
if (!keyExtractorProp) {
|
|
1020
|
+
state.sizes.clear();
|
|
1021
|
+
state.positions;
|
|
1022
|
+
}
|
|
1023
|
+
calculateItemsInView(state.scrollVelocity);
|
|
1024
|
+
}
|
|
1025
|
+
const didMaintainScrollAtEnd = doMaintainScrollAtEnd(false);
|
|
1026
|
+
if (!didMaintainScrollAtEnd && data.length > state.data.length) {
|
|
1027
|
+
state.isEndReached = false;
|
|
1028
|
+
}
|
|
1029
|
+
checkAtTop();
|
|
1030
|
+
checkAtBottom();
|
|
1031
|
+
}
|
|
1032
|
+
};
|
|
980
1033
|
const isFirst = !refState.current.renderItem;
|
|
981
1034
|
if (isFirst || data !== refState.current.data || numColumnsProp !== peek$(ctx, "numColumns")) {
|
|
982
1035
|
if (!keyExtractorProp && !isFirst && data !== refState.current.data) {
|
|
@@ -1010,40 +1063,25 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
1010
1063
|
}
|
|
1011
1064
|
}
|
|
1012
1065
|
addTotalSize(null, totalSize, totalSizeBelowIndex);
|
|
1013
|
-
if (!isFirst) {
|
|
1014
|
-
if (data.length > refState.current.data.length) {
|
|
1015
|
-
refState.current.isEndReached = false;
|
|
1016
|
-
}
|
|
1017
|
-
refState.current.data = data;
|
|
1018
|
-
const numContainers = peek$(ctx, "numContainers");
|
|
1019
|
-
for (let i = 0; i < numContainers; i++) {
|
|
1020
|
-
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1021
|
-
if (!keyExtractorProp || itemKey && ((_a = refState.current) == null ? void 0 : _a.indexByKey.get(itemKey)) === void 0) {
|
|
1022
|
-
set$(ctx, `containerItemKey${i}`, void 0);
|
|
1023
|
-
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
1024
|
-
set$(ctx, `containerColumn${i}`, -1);
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
if (!keyExtractorProp) {
|
|
1028
|
-
refState.current.sizes.clear();
|
|
1029
|
-
refState.current.positions;
|
|
1030
|
-
}
|
|
1031
|
-
setTimeout(() => {
|
|
1032
|
-
calculateItemsInView(refState.current.scrollVelocity);
|
|
1033
|
-
doMaintainScrollAtEnd(false);
|
|
1034
|
-
checkAtTop();
|
|
1035
|
-
checkAtBottom();
|
|
1036
|
-
}, 0);
|
|
1037
|
-
}
|
|
1038
1066
|
}
|
|
1067
|
+
React4.useEffect(() => {
|
|
1068
|
+
checkResetContainers(
|
|
1069
|
+
/*reset*/
|
|
1070
|
+
!isFirst
|
|
1071
|
+
);
|
|
1072
|
+
}, [isFirst, data, numColumnsProp]);
|
|
1039
1073
|
refState.current.renderItem = renderItem;
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
ctx,
|
|
1044
|
-
"
|
|
1045
|
-
(
|
|
1046
|
-
|
|
1074
|
+
const lastItemKey = getId(data[data.length - 1]);
|
|
1075
|
+
const stylePaddingTop = (_d = (_c = (_a = reactNative.StyleSheet.flatten(style)) == null ? void 0 : _a.paddingTop) != null ? _c : (_b = reactNative.StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _b.paddingTop) != null ? _d : 0;
|
|
1076
|
+
const initalizeStateVars = () => {
|
|
1077
|
+
set$(ctx, "lastItemKey", lastItemKey);
|
|
1078
|
+
set$(ctx, "numColumns", numColumnsProp);
|
|
1079
|
+
set$(ctx, "stylePaddingTop", stylePaddingTop);
|
|
1080
|
+
};
|
|
1081
|
+
if (isFirst) {
|
|
1082
|
+
initalizeStateVars();
|
|
1083
|
+
}
|
|
1084
|
+
React4.useEffect(initalizeStateVars, [lastItemKey, numColumnsProp, stylePaddingTop]);
|
|
1047
1085
|
const getRenderedItem = React4.useCallback((key, containerId) => {
|
|
1048
1086
|
var _a2, _b2;
|
|
1049
1087
|
const state = refState.current;
|
|
@@ -1111,7 +1149,7 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
1111
1149
|
}
|
|
1112
1150
|
};
|
|
1113
1151
|
run();
|
|
1114
|
-
listen$(ctx, signal, run);
|
|
1152
|
+
return listen$(ctx, signal, run);
|
|
1115
1153
|
}, []);
|
|
1116
1154
|
};
|
|
1117
1155
|
const useRecyclingState = (valueOrFun) => {
|
|
@@ -1165,6 +1203,10 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
1165
1203
|
const numColumns = peek$(ctx, "numColumns");
|
|
1166
1204
|
const row = Math.floor(index / numColumns);
|
|
1167
1205
|
const prevSize = getRowHeight(row);
|
|
1206
|
+
const measured = peek$(ctx, `containerDidLayout${containerId}`);
|
|
1207
|
+
if (!measured) {
|
|
1208
|
+
state.layoutsPending.add(containerId);
|
|
1209
|
+
}
|
|
1168
1210
|
if (!prevSize || Math.abs(prevSize - size) > 0.5) {
|
|
1169
1211
|
let diff;
|
|
1170
1212
|
if (numColumns > 1) {
|
|
@@ -1202,6 +1244,7 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
1202
1244
|
);
|
|
1203
1245
|
}, 1e3);
|
|
1204
1246
|
}
|
|
1247
|
+
refState.current.scrollForNextCalculateItemsInView = void 0;
|
|
1205
1248
|
addTotalSize(itemKey, diff, 0);
|
|
1206
1249
|
doMaintainScrollAtEnd(true);
|
|
1207
1250
|
const scrollVelocity = state.scrollVelocity;
|
|
@@ -1215,6 +1258,11 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
1215
1258
|
calculateItemsInView(state.scrollVelocity);
|
|
1216
1259
|
}
|
|
1217
1260
|
}
|
|
1261
|
+
if (onItemSizeChanged) {
|
|
1262
|
+
onItemSizeChanged({ size, previous: prevSize, index, itemKey, itemData: data2[index] });
|
|
1263
|
+
}
|
|
1264
|
+
} else {
|
|
1265
|
+
set$(ctx, `containerDidLayout${containerId}`, true);
|
|
1218
1266
|
}
|
|
1219
1267
|
}, []);
|
|
1220
1268
|
const handleScrollDebounced = React4.useCallback((velocity) => {
|
|
@@ -1225,12 +1273,10 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
1225
1273
|
const onLayout = React4.useCallback((event) => {
|
|
1226
1274
|
const scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
1227
1275
|
refState.current.scrollLength = scrollLength;
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
checkAtTop();
|
|
1233
|
-
}
|
|
1276
|
+
doMaintainScrollAtEnd(false);
|
|
1277
|
+
doUpdatePaddingTop();
|
|
1278
|
+
checkAtBottom();
|
|
1279
|
+
checkAtTop();
|
|
1234
1280
|
if (__DEV__) {
|
|
1235
1281
|
const isWidthZero = event.nativeEvent.layout.width === 0;
|
|
1236
1282
|
const isHeightZero = event.nativeEvent.layout.height === 0;
|
|
@@ -1249,7 +1295,6 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
1249
1295
|
}
|
|
1250
1296
|
const state = refState.current;
|
|
1251
1297
|
state.hasScrolled = true;
|
|
1252
|
-
state.contentSize = event.nativeEvent.contentSize;
|
|
1253
1298
|
const currentTime = performance.now();
|
|
1254
1299
|
const newScroll = event.nativeEvent.contentOffset[horizontal ? "x" : "y"];
|
|
1255
1300
|
if (!(state.scrollHistory.length === 0 && newScroll === initialContentOffset)) {
|
|
@@ -1337,6 +1382,7 @@ var LegendListInner = React4.forwardRef(function LegendListInner2(props, forward
|
|
|
1337
1382
|
alignItemsAtEnd,
|
|
1338
1383
|
ListEmptyComponent: data.length === 0 ? ListEmptyComponent : void 0,
|
|
1339
1384
|
maintainVisibleContentPosition,
|
|
1385
|
+
scrollEventThrottle: scrollEventThrottle != null ? scrollEventThrottle : reactNative.Platform.OS === "web" ? 16 : void 0,
|
|
1340
1386
|
style
|
|
1341
1387
|
}
|
|
1342
1388
|
);
|
package/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React4 from 'react';
|
|
2
|
-
import React4__default, { forwardRef, useRef, useMemo, useCallback, useImperativeHandle, useSyncExternalStore,
|
|
3
|
-
import { Animated, ScrollView, View, Dimensions, StyleSheet, useAnimatedValue as useAnimatedValue$1 } from 'react-native';
|
|
2
|
+
import React4__default, { forwardRef, useRef, useMemo, useCallback, useEffect, useImperativeHandle, useSyncExternalStore, useState } from 'react';
|
|
3
|
+
import { Animated, ScrollView, View, Dimensions, StyleSheet, Platform, useAnimatedValue as useAnimatedValue$1 } from 'react-native';
|
|
4
4
|
|
|
5
5
|
// src/LegendList.tsx
|
|
6
6
|
var ContextState = React4.createContext(null);
|
|
@@ -18,12 +18,16 @@ function StateProvider({ children }) {
|
|
|
18
18
|
function useStateContext() {
|
|
19
19
|
return React4.useContext(ContextState);
|
|
20
20
|
}
|
|
21
|
+
function createSelectorFunctions(ctx, signalName) {
|
|
22
|
+
return {
|
|
23
|
+
subscribe: (cb) => listen$(ctx, signalName, cb),
|
|
24
|
+
get: () => peek$(ctx, signalName)
|
|
25
|
+
};
|
|
26
|
+
}
|
|
21
27
|
function use$(signalName) {
|
|
22
28
|
const ctx = React4.useContext(ContextState);
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
() => ctx.values.get(signalName)
|
|
26
|
-
);
|
|
29
|
+
const { subscribe, get } = React4.useMemo(() => createSelectorFunctions(ctx, signalName), []);
|
|
30
|
+
const value = useSyncExternalStore(subscribe, get);
|
|
27
31
|
return value;
|
|
28
32
|
}
|
|
29
33
|
function listen$(ctx, signalName, cb) {
|
|
@@ -52,10 +56,13 @@ function set$(ctx, signalName, value) {
|
|
|
52
56
|
}
|
|
53
57
|
}
|
|
54
58
|
}
|
|
59
|
+
|
|
60
|
+
// src/Container.tsx
|
|
55
61
|
var Container = ({
|
|
56
62
|
id,
|
|
57
63
|
recycleItems,
|
|
58
64
|
horizontal,
|
|
65
|
+
waitForInitialLayout,
|
|
59
66
|
getRenderedItem,
|
|
60
67
|
updateItemSize,
|
|
61
68
|
ItemSeparatorComponent
|
|
@@ -63,11 +70,10 @@ var Container = ({
|
|
|
63
70
|
const ctx = useStateContext();
|
|
64
71
|
const position = use$(`containerPosition${id}`);
|
|
65
72
|
const column = use$(`containerColumn${id}`) || 0;
|
|
66
|
-
const visible = use$(`containerDidLayout${id}`);
|
|
67
73
|
const numColumns = use$("numColumns");
|
|
68
74
|
const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
|
|
69
75
|
const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
|
|
70
|
-
|
|
76
|
+
const style = horizontal ? {
|
|
71
77
|
flexDirection: "row",
|
|
72
78
|
position: "absolute",
|
|
73
79
|
top: otherAxisPos,
|
|
@@ -81,7 +87,8 @@ var Container = ({
|
|
|
81
87
|
width: otherAxisSize,
|
|
82
88
|
top: position
|
|
83
89
|
};
|
|
84
|
-
{
|
|
90
|
+
if (waitForInitialLayout) {
|
|
91
|
+
const visible = use$(`containerDidLayout${id}`);
|
|
85
92
|
style.opacity = visible ? 1 : 0;
|
|
86
93
|
}
|
|
87
94
|
const lastItemKey = use$("lastItemKey");
|
|
@@ -97,14 +104,6 @@ var Container = ({
|
|
|
97
104
|
if (key !== void 0) {
|
|
98
105
|
const size = Math.floor(event.nativeEvent.layout[horizontal ? "width" : "height"] * 8) / 8;
|
|
99
106
|
updateItemSize(id, key, size);
|
|
100
|
-
const otherAxisSize2 = horizontal ? event.nativeEvent.layout.width : event.nativeEvent.layout.height;
|
|
101
|
-
set$(ctx, "otherAxisSize", Math.max(otherAxisSize2, peek$(ctx, "otherAxisSize") || 0));
|
|
102
|
-
const measured = peek$(ctx, `containerDidLayout${id}`);
|
|
103
|
-
if (!measured) {
|
|
104
|
-
requestAnimationFrame(() => {
|
|
105
|
-
set$(ctx, `containerDidLayout${id}`, true);
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
107
|
}
|
|
109
108
|
}
|
|
110
109
|
},
|
|
@@ -129,6 +128,7 @@ var Containers = React4.memo(function Containers2({
|
|
|
129
128
|
horizontal,
|
|
130
129
|
recycleItems,
|
|
131
130
|
ItemSeparatorComponent,
|
|
131
|
+
waitForInitialLayout,
|
|
132
132
|
updateItemSize,
|
|
133
133
|
getRenderedItem
|
|
134
134
|
}) {
|
|
@@ -144,6 +144,7 @@ var Containers = React4.memo(function Containers2({
|
|
|
144
144
|
key: i,
|
|
145
145
|
recycleItems,
|
|
146
146
|
horizontal,
|
|
147
|
+
waitForInitialLayout,
|
|
147
148
|
getRenderedItem,
|
|
148
149
|
updateItemSize,
|
|
149
150
|
ItemSeparatorComponent
|
|
@@ -173,6 +174,7 @@ var ListComponent = React4.memo(function ListComponent2({
|
|
|
173
174
|
recycleItems,
|
|
174
175
|
ItemSeparatorComponent,
|
|
175
176
|
alignItemsAtEnd,
|
|
177
|
+
waitForInitialLayout,
|
|
176
178
|
handleScroll,
|
|
177
179
|
onLayout,
|
|
178
180
|
ListHeaderComponent,
|
|
@@ -230,6 +232,7 @@ var ListComponent = React4.memo(function ListComponent2({
|
|
|
230
232
|
{
|
|
231
233
|
horizontal,
|
|
232
234
|
recycleItems,
|
|
235
|
+
waitForInitialLayout,
|
|
233
236
|
getRenderedItem,
|
|
234
237
|
ItemSeparatorComponent: ItemSeparatorComponent && getComponent(ItemSeparatorComponent),
|
|
235
238
|
updateItemSize
|
|
@@ -439,7 +442,7 @@ var LegendList = forwardRef(function LegendList2(props, forwardedRef) {
|
|
|
439
442
|
return /* @__PURE__ */ React4.createElement(StateProvider, null, /* @__PURE__ */ React4.createElement(LegendListInner, { ...props, ref: forwardedRef }));
|
|
440
443
|
});
|
|
441
444
|
var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef) {
|
|
442
|
-
var _a, _b, _c, _d
|
|
445
|
+
var _a, _b, _c, _d;
|
|
443
446
|
const {
|
|
444
447
|
data,
|
|
445
448
|
initialScrollIndex,
|
|
@@ -463,6 +466,8 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
463
466
|
onEndReached,
|
|
464
467
|
onStartReached,
|
|
465
468
|
ListEmptyComponent,
|
|
469
|
+
onItemSizeChanged,
|
|
470
|
+
scrollEventThrottle,
|
|
466
471
|
refScrollView,
|
|
467
472
|
...rest
|
|
468
473
|
} = props;
|
|
@@ -540,13 +545,14 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
540
545
|
indexByKey: /* @__PURE__ */ new Map(),
|
|
541
546
|
scrollHistory: [],
|
|
542
547
|
scrollVelocity: 0,
|
|
543
|
-
contentSize: { width: 0, height: 0 },
|
|
544
548
|
sizesLaidOut: __DEV__ ? /* @__PURE__ */ new Map() : void 0,
|
|
545
549
|
timeoutSizeMessage: 0,
|
|
546
550
|
scrollTimer: void 0,
|
|
547
551
|
belowAnchorElementPositions: void 0,
|
|
548
552
|
rowHeights: /* @__PURE__ */ new Map(),
|
|
549
|
-
startReachedBlockedByTimer: false
|
|
553
|
+
startReachedBlockedByTimer: false,
|
|
554
|
+
layoutsPending: /* @__PURE__ */ new Set(),
|
|
555
|
+
scrollForNextCalculateItemsInView: void 0
|
|
550
556
|
};
|
|
551
557
|
refState.current.idsInFirstRender = new Set(data.map((_, i) => getId(i)));
|
|
552
558
|
if (maintainVisibleContentPosition) {
|
|
@@ -600,21 +606,18 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
600
606
|
state.belowAnchorElementPositions = buildElementPositionsBelowAnchor();
|
|
601
607
|
state.rowHeights.clear();
|
|
602
608
|
}
|
|
603
|
-
const
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
}
|
|
616
|
-
};
|
|
617
|
-
doAdd();
|
|
609
|
+
const totalSize = state.totalSize;
|
|
610
|
+
let resultSize = totalSize;
|
|
611
|
+
if (applyAdjustValue !== void 0) {
|
|
612
|
+
resultSize -= applyAdjustValue;
|
|
613
|
+
refState.current.scrollAdjustHandler.requestAdjust(applyAdjustValue, (diff) => {
|
|
614
|
+
state.scroll -= diff;
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
set$(ctx, "totalSize", resultSize);
|
|
618
|
+
if (alignItemsAtEnd) {
|
|
619
|
+
doUpdatePaddingTop();
|
|
620
|
+
}
|
|
618
621
|
}, []);
|
|
619
622
|
const getRowHeight = (n) => {
|
|
620
623
|
const { rowHeights } = refState.current;
|
|
@@ -677,7 +680,8 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
677
680
|
startBufferedId: startBufferedIdOrig,
|
|
678
681
|
positions,
|
|
679
682
|
columns,
|
|
680
|
-
scrollAdjustHandler
|
|
683
|
+
scrollAdjustHandler,
|
|
684
|
+
layoutsPending
|
|
681
685
|
} = state;
|
|
682
686
|
if (state.animFrameLayout) {
|
|
683
687
|
cancelAnimationFrame(state.animFrameLayout);
|
|
@@ -690,6 +694,12 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
690
694
|
const previousScrollAdjust = scrollAdjustHandler.getAppliedAdjust();
|
|
691
695
|
const scrollExtra = Math.max(-16, Math.min(16, speed)) * 16;
|
|
692
696
|
const scroll = scrollState - previousScrollAdjust - topPad - scrollExtra;
|
|
697
|
+
if (refState.current.scrollForNextCalculateItemsInView) {
|
|
698
|
+
const { top: top2, bottom } = refState.current.scrollForNextCalculateItemsInView;
|
|
699
|
+
if (scroll > top2 && scroll < bottom) {
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
693
703
|
const scrollBottom = scroll + scrollLength;
|
|
694
704
|
let startNoBuffer = null;
|
|
695
705
|
let startBuffered = null;
|
|
@@ -783,6 +793,14 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
783
793
|
endBuffered,
|
|
784
794
|
endNoBuffer
|
|
785
795
|
});
|
|
796
|
+
const nextTop = Math.ceil(startBuffered ? positions.get(startBufferedId) + scrollBuffer : 0);
|
|
797
|
+
const nextBottom = Math.floor(
|
|
798
|
+
endBuffered ? (positions.get(getId(endBuffered + 1)) || 0) - scrollLength - scrollBuffer : 0
|
|
799
|
+
);
|
|
800
|
+
refState.current.scrollForNextCalculateItemsInView = nextTop >= 0 && nextBottom >= 0 ? {
|
|
801
|
+
top: nextTop,
|
|
802
|
+
bottom: nextBottom
|
|
803
|
+
} : void 0;
|
|
786
804
|
if (startBuffered !== null && endBuffered !== null) {
|
|
787
805
|
const prevNumContainers = ctx.values.get("numContainers");
|
|
788
806
|
let numContainers = prevNumContainers;
|
|
@@ -825,7 +843,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
825
843
|
numContainers++;
|
|
826
844
|
set$(ctx, `containerItemKey${containerId}`, id);
|
|
827
845
|
const index = (_c2 = refState.current) == null ? void 0 : _c2.indexByKey.get(id);
|
|
828
|
-
set$(ctx, `containerItemData${
|
|
846
|
+
set$(ctx, `containerItemData${containerId}`, data2[index]);
|
|
829
847
|
set$(ctx, `containerPosition${containerId}`, POSITION_OUT_OF_VIEW);
|
|
830
848
|
set$(ctx, `containerColumn${containerId}`, -1);
|
|
831
849
|
if (__DEV__ && numContainers > peek$(ctx, "numContainersPooled")) {
|
|
@@ -875,6 +893,12 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
875
893
|
}
|
|
876
894
|
}
|
|
877
895
|
}
|
|
896
|
+
if (layoutsPending.size > 0) {
|
|
897
|
+
for (const containerId of layoutsPending) {
|
|
898
|
+
set$(ctx, `containerDidLayout${containerId}`, true);
|
|
899
|
+
}
|
|
900
|
+
layoutsPending.clear();
|
|
901
|
+
}
|
|
878
902
|
if (refState.current.viewabilityConfigCallbackPairs) {
|
|
879
903
|
updateViewableItems(
|
|
880
904
|
refState.current,
|
|
@@ -896,25 +920,25 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
896
920
|
}
|
|
897
921
|
};
|
|
898
922
|
const doMaintainScrollAtEnd = (animated) => {
|
|
899
|
-
|
|
900
|
-
if ((
|
|
901
|
-
|
|
923
|
+
const state = refState.current;
|
|
924
|
+
if ((state == null ? void 0 : state.isAtBottom) && maintainScrollAtEnd) {
|
|
925
|
+
state.scroll = state.totalSize - state.scrollLength + peek$(ctx, "paddingTop");
|
|
902
926
|
requestAnimationFrame(() => {
|
|
903
|
-
var
|
|
904
|
-
(
|
|
927
|
+
var _a2;
|
|
928
|
+
(_a2 = refScroller.current) == null ? void 0 : _a2.scrollToEnd({
|
|
905
929
|
animated
|
|
906
930
|
});
|
|
907
931
|
});
|
|
932
|
+
return true;
|
|
908
933
|
}
|
|
909
934
|
};
|
|
910
935
|
const checkAtBottom = () => {
|
|
911
936
|
if (!refState.current) {
|
|
912
937
|
return;
|
|
913
938
|
}
|
|
914
|
-
const { scrollLength, scroll,
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
const distanceFromEnd = contentLength - scroll - scrollLength;
|
|
939
|
+
const { scrollLength, scroll, totalSize } = refState.current;
|
|
940
|
+
if (totalSize > 0) {
|
|
941
|
+
const distanceFromEnd = totalSize - scroll - scrollLength;
|
|
918
942
|
if (refState.current) {
|
|
919
943
|
refState.current.isAtBottom = distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
|
|
920
944
|
}
|
|
@@ -956,6 +980,35 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
956
980
|
}
|
|
957
981
|
}
|
|
958
982
|
};
|
|
983
|
+
const checkResetContainers = (reset) => {
|
|
984
|
+
const state = refState.current;
|
|
985
|
+
if (state) {
|
|
986
|
+
state.data = data;
|
|
987
|
+
if (reset) {
|
|
988
|
+
refState.current.scrollForNextCalculateItemsInView = void 0;
|
|
989
|
+
const numContainers = peek$(ctx, "numContainers");
|
|
990
|
+
for (let i = 0; i < numContainers; i++) {
|
|
991
|
+
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
992
|
+
if (!keyExtractorProp || itemKey && state.indexByKey.get(itemKey) === void 0) {
|
|
993
|
+
set$(ctx, `containerItemKey${i}`, void 0);
|
|
994
|
+
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
995
|
+
set$(ctx, `containerColumn${i}`, -1);
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
if (!keyExtractorProp) {
|
|
999
|
+
state.sizes.clear();
|
|
1000
|
+
state.positions;
|
|
1001
|
+
}
|
|
1002
|
+
calculateItemsInView(state.scrollVelocity);
|
|
1003
|
+
}
|
|
1004
|
+
const didMaintainScrollAtEnd = doMaintainScrollAtEnd(false);
|
|
1005
|
+
if (!didMaintainScrollAtEnd && data.length > state.data.length) {
|
|
1006
|
+
state.isEndReached = false;
|
|
1007
|
+
}
|
|
1008
|
+
checkAtTop();
|
|
1009
|
+
checkAtBottom();
|
|
1010
|
+
}
|
|
1011
|
+
};
|
|
959
1012
|
const isFirst = !refState.current.renderItem;
|
|
960
1013
|
if (isFirst || data !== refState.current.data || numColumnsProp !== peek$(ctx, "numColumns")) {
|
|
961
1014
|
if (!keyExtractorProp && !isFirst && data !== refState.current.data) {
|
|
@@ -989,40 +1042,25 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
989
1042
|
}
|
|
990
1043
|
}
|
|
991
1044
|
addTotalSize(null, totalSize, totalSizeBelowIndex);
|
|
992
|
-
if (!isFirst) {
|
|
993
|
-
if (data.length > refState.current.data.length) {
|
|
994
|
-
refState.current.isEndReached = false;
|
|
995
|
-
}
|
|
996
|
-
refState.current.data = data;
|
|
997
|
-
const numContainers = peek$(ctx, "numContainers");
|
|
998
|
-
for (let i = 0; i < numContainers; i++) {
|
|
999
|
-
const itemKey = peek$(ctx, `containerItemKey${i}`);
|
|
1000
|
-
if (!keyExtractorProp || itemKey && ((_a = refState.current) == null ? void 0 : _a.indexByKey.get(itemKey)) === void 0) {
|
|
1001
|
-
set$(ctx, `containerItemKey${i}`, void 0);
|
|
1002
|
-
set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
|
|
1003
|
-
set$(ctx, `containerColumn${i}`, -1);
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
if (!keyExtractorProp) {
|
|
1007
|
-
refState.current.sizes.clear();
|
|
1008
|
-
refState.current.positions;
|
|
1009
|
-
}
|
|
1010
|
-
setTimeout(() => {
|
|
1011
|
-
calculateItemsInView(refState.current.scrollVelocity);
|
|
1012
|
-
doMaintainScrollAtEnd(false);
|
|
1013
|
-
checkAtTop();
|
|
1014
|
-
checkAtBottom();
|
|
1015
|
-
}, 0);
|
|
1016
|
-
}
|
|
1017
1045
|
}
|
|
1046
|
+
useEffect(() => {
|
|
1047
|
+
checkResetContainers(
|
|
1048
|
+
/*reset*/
|
|
1049
|
+
!isFirst
|
|
1050
|
+
);
|
|
1051
|
+
}, [isFirst, data, numColumnsProp]);
|
|
1018
1052
|
refState.current.renderItem = renderItem;
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
ctx,
|
|
1023
|
-
"
|
|
1024
|
-
(
|
|
1025
|
-
|
|
1053
|
+
const lastItemKey = getId(data[data.length - 1]);
|
|
1054
|
+
const stylePaddingTop = (_d = (_c = (_a = StyleSheet.flatten(style)) == null ? void 0 : _a.paddingTop) != null ? _c : (_b = StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _b.paddingTop) != null ? _d : 0;
|
|
1055
|
+
const initalizeStateVars = () => {
|
|
1056
|
+
set$(ctx, "lastItemKey", lastItemKey);
|
|
1057
|
+
set$(ctx, "numColumns", numColumnsProp);
|
|
1058
|
+
set$(ctx, "stylePaddingTop", stylePaddingTop);
|
|
1059
|
+
};
|
|
1060
|
+
if (isFirst) {
|
|
1061
|
+
initalizeStateVars();
|
|
1062
|
+
}
|
|
1063
|
+
useEffect(initalizeStateVars, [lastItemKey, numColumnsProp, stylePaddingTop]);
|
|
1026
1064
|
const getRenderedItem = useCallback((key, containerId) => {
|
|
1027
1065
|
var _a2, _b2;
|
|
1028
1066
|
const state = refState.current;
|
|
@@ -1090,7 +1128,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1090
1128
|
}
|
|
1091
1129
|
};
|
|
1092
1130
|
run();
|
|
1093
|
-
listen$(ctx, signal, run);
|
|
1131
|
+
return listen$(ctx, signal, run);
|
|
1094
1132
|
}, []);
|
|
1095
1133
|
};
|
|
1096
1134
|
const useRecyclingState = (valueOrFun) => {
|
|
@@ -1144,6 +1182,10 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1144
1182
|
const numColumns = peek$(ctx, "numColumns");
|
|
1145
1183
|
const row = Math.floor(index / numColumns);
|
|
1146
1184
|
const prevSize = getRowHeight(row);
|
|
1185
|
+
const measured = peek$(ctx, `containerDidLayout${containerId}`);
|
|
1186
|
+
if (!measured) {
|
|
1187
|
+
state.layoutsPending.add(containerId);
|
|
1188
|
+
}
|
|
1147
1189
|
if (!prevSize || Math.abs(prevSize - size) > 0.5) {
|
|
1148
1190
|
let diff;
|
|
1149
1191
|
if (numColumns > 1) {
|
|
@@ -1181,6 +1223,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1181
1223
|
);
|
|
1182
1224
|
}, 1e3);
|
|
1183
1225
|
}
|
|
1226
|
+
refState.current.scrollForNextCalculateItemsInView = void 0;
|
|
1184
1227
|
addTotalSize(itemKey, diff, 0);
|
|
1185
1228
|
doMaintainScrollAtEnd(true);
|
|
1186
1229
|
const scrollVelocity = state.scrollVelocity;
|
|
@@ -1194,6 +1237,11 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1194
1237
|
calculateItemsInView(state.scrollVelocity);
|
|
1195
1238
|
}
|
|
1196
1239
|
}
|
|
1240
|
+
if (onItemSizeChanged) {
|
|
1241
|
+
onItemSizeChanged({ size, previous: prevSize, index, itemKey, itemData: data2[index] });
|
|
1242
|
+
}
|
|
1243
|
+
} else {
|
|
1244
|
+
set$(ctx, `containerDidLayout${containerId}`, true);
|
|
1197
1245
|
}
|
|
1198
1246
|
}, []);
|
|
1199
1247
|
const handleScrollDebounced = useCallback((velocity) => {
|
|
@@ -1204,12 +1252,10 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1204
1252
|
const onLayout = useCallback((event) => {
|
|
1205
1253
|
const scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
1206
1254
|
refState.current.scrollLength = scrollLength;
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
checkAtTop();
|
|
1212
|
-
}
|
|
1255
|
+
doMaintainScrollAtEnd(false);
|
|
1256
|
+
doUpdatePaddingTop();
|
|
1257
|
+
checkAtBottom();
|
|
1258
|
+
checkAtTop();
|
|
1213
1259
|
if (__DEV__) {
|
|
1214
1260
|
const isWidthZero = event.nativeEvent.layout.width === 0;
|
|
1215
1261
|
const isHeightZero = event.nativeEvent.layout.height === 0;
|
|
@@ -1228,7 +1274,6 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1228
1274
|
}
|
|
1229
1275
|
const state = refState.current;
|
|
1230
1276
|
state.hasScrolled = true;
|
|
1231
|
-
state.contentSize = event.nativeEvent.contentSize;
|
|
1232
1277
|
const currentTime = performance.now();
|
|
1233
1278
|
const newScroll = event.nativeEvent.contentOffset[horizontal ? "x" : "y"];
|
|
1234
1279
|
if (!(state.scrollHistory.length === 0 && newScroll === initialContentOffset)) {
|
|
@@ -1316,6 +1361,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
|
|
|
1316
1361
|
alignItemsAtEnd,
|
|
1317
1362
|
ListEmptyComponent: data.length === 0 ? ListEmptyComponent : void 0,
|
|
1318
1363
|
maintainVisibleContentPosition,
|
|
1364
|
+
scrollEventThrottle: scrollEventThrottle != null ? scrollEventThrottle : Platform.OS === "web" ? 16 : void 0,
|
|
1319
1365
|
style
|
|
1320
1366
|
}
|
|
1321
1367
|
);
|
package/package.json
CHANGED
package/reanimated.d.mts
CHANGED
|
@@ -2,7 +2,7 @@ import { LegendListRef, LegendListPropsBase } from '@legendapp/list';
|
|
|
2
2
|
import React__default, { ComponentProps } from 'react';
|
|
3
3
|
import Animated from 'react-native-reanimated';
|
|
4
4
|
|
|
5
|
-
type KeysToOmit = "getEstimatedItemSize" | "keyExtractor" | "animatedProps" | "renderItem";
|
|
5
|
+
type KeysToOmit = "getEstimatedItemSize" | "keyExtractor" | "animatedProps" | "renderItem" | "onItemSizeChanged";
|
|
6
6
|
type PropsBase<ItemT> = LegendListPropsBase<ItemT, ComponentProps<typeof Animated.ScrollView>>;
|
|
7
7
|
interface AnimatedLegendListProps<ItemT> extends Omit<PropsBase<ItemT>, KeysToOmit> {
|
|
8
8
|
refScrollView?: React__default.Ref<Animated.ScrollView>;
|
package/reanimated.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { LegendListRef, LegendListPropsBase } from '@legendapp/list';
|
|
|
2
2
|
import React__default, { ComponentProps } from 'react';
|
|
3
3
|
import Animated from 'react-native-reanimated';
|
|
4
4
|
|
|
5
|
-
type KeysToOmit = "getEstimatedItemSize" | "keyExtractor" | "animatedProps" | "renderItem";
|
|
5
|
+
type KeysToOmit = "getEstimatedItemSize" | "keyExtractor" | "animatedProps" | "renderItem" | "onItemSizeChanged";
|
|
6
6
|
type PropsBase<ItemT> = LegendListPropsBase<ItemT, ComponentProps<typeof Animated.ScrollView>>;
|
|
7
7
|
interface AnimatedLegendListProps<ItemT> extends Omit<PropsBase<ItemT>, KeysToOmit> {
|
|
8
8
|
refScrollView?: React__default.Ref<Animated.ScrollView>;
|