@legendapp/list 1.0.0-beta.16 → 1.0.0-beta.18
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/animated.d.mts +6 -1
- package/animated.d.ts +6 -1
- package/index.d.mts +19 -5
- package/index.d.ts +19 -5
- package/index.js +184 -110
- package/index.mjs +185 -111
- package/package.json +1 -1
- package/reanimated.d.mts +1 -1
- package/reanimated.d.ts +1 -1
package/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React6 from 'react';
|
|
2
2
|
import React6__default, { createContext, memo, useReducer, useEffect, useMemo, useRef, useCallback, useImperativeHandle, useSyncExternalStore, useContext, useState, forwardRef, useLayoutEffect } from 'react';
|
|
3
|
-
import { View, Text, Platform, Animated, ScrollView, Dimensions, StyleSheet } from 'react-native';
|
|
3
|
+
import { View, Text, Platform, Animated, ScrollView, Dimensions, StyleSheet, RefreshControl } from 'react-native';
|
|
4
4
|
|
|
5
5
|
// src/LegendList.tsx
|
|
6
6
|
var ContextState = React6.createContext(null);
|
|
@@ -57,6 +57,14 @@ function set$(ctx, signalName, value) {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
+
function getContentSize(ctx) {
|
|
61
|
+
const { values } = ctx;
|
|
62
|
+
const stylePaddingTop = values.get("stylePaddingTop") || 0;
|
|
63
|
+
const headerSize = values.get("headerSize") || 0;
|
|
64
|
+
const footerSize = values.get("footerSize") || 0;
|
|
65
|
+
const totalSize = values.get("totalSize") || 0;
|
|
66
|
+
return headerSize + footerSize + totalSize + stylePaddingTop;
|
|
67
|
+
}
|
|
60
68
|
var symbolFirst = Symbol();
|
|
61
69
|
function useInit(cb) {
|
|
62
70
|
const refValue = useRef(symbolFirst);
|
|
@@ -143,7 +151,9 @@ function useRecyclingState(valueOrFun) {
|
|
|
143
151
|
return stateInfo;
|
|
144
152
|
}
|
|
145
153
|
var DebugView = memo(function DebugView2({ state }) {
|
|
146
|
-
const
|
|
154
|
+
const ctx = useStateContext();
|
|
155
|
+
const totalSize = use$("totalSize");
|
|
156
|
+
const contentSize = getContentSize(ctx);
|
|
147
157
|
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
148
158
|
useInterval(() => {
|
|
149
159
|
forceUpdate();
|
|
@@ -161,7 +171,8 @@ var DebugView = memo(function DebugView2({ state }) {
|
|
|
161
171
|
backgroundColor: "#FFFFFFCC"
|
|
162
172
|
}
|
|
163
173
|
},
|
|
164
|
-
/* @__PURE__ */ React6.createElement(Text, null, "
|
|
174
|
+
/* @__PURE__ */ React6.createElement(Text, null, "TotalSize: ", totalSize),
|
|
175
|
+
/* @__PURE__ */ React6.createElement(Text, null, "ContentSize: ", contentSize),
|
|
165
176
|
/* @__PURE__ */ React6.createElement(Text, null, "At end: ", String(state.isAtBottom))
|
|
166
177
|
);
|
|
167
178
|
});
|
|
@@ -203,13 +214,17 @@ var Container = ({
|
|
|
203
214
|
const position = use$(`containerPosition${id}`) || ANCHORED_POSITION_OUT_OF_VIEW;
|
|
204
215
|
const column = use$(`containerColumn${id}`) || 0;
|
|
205
216
|
const numColumns = use$("numColumns");
|
|
217
|
+
const lastItemKeys = use$("lastItemKeys");
|
|
218
|
+
const itemKey = use$(`containerItemKey${id}`);
|
|
219
|
+
const data = use$(`containerItemData${id}`);
|
|
220
|
+
const extraData = use$("extraData");
|
|
206
221
|
const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
|
|
207
222
|
const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
|
|
208
223
|
let verticalPaddingStyles;
|
|
209
224
|
if (columnWrapperStyle && !horizontal && numColumns > 1) {
|
|
210
225
|
const { columnGap, rowGap, gap } = columnWrapperStyle;
|
|
211
226
|
verticalPaddingStyles = {
|
|
212
|
-
|
|
227
|
+
paddingBottom: !lastItemKeys.has(itemKey) ? rowGap || gap || void 0 : void 0,
|
|
213
228
|
// Apply horizontal padding based on column position (first, middle, or last)
|
|
214
229
|
paddingLeft: column > 1 ? (columnGap || gap || 0) / 2 : void 0,
|
|
215
230
|
paddingRight: column < numColumns ? (columnGap || gap || 0) / 2 : void 0
|
|
@@ -230,12 +245,8 @@ var Container = ({
|
|
|
230
245
|
top: position.relativeCoordinate,
|
|
231
246
|
...verticalPaddingStyles || {}
|
|
232
247
|
};
|
|
233
|
-
const lastItemKey = use$("lastItemKey");
|
|
234
|
-
const itemKey = use$(`containerItemKey${id}`);
|
|
235
|
-
const data = use$(`containerItemData${id}`);
|
|
236
|
-
const extraData = use$("extraData");
|
|
237
248
|
const renderedItemInfo = useMemo(
|
|
238
|
-
() => itemKey !== void 0
|
|
249
|
+
() => itemKey !== void 0 ? getRenderedItem(itemKey) : null,
|
|
239
250
|
[itemKey, data, extraData]
|
|
240
251
|
);
|
|
241
252
|
const { index, renderedItem } = renderedItemInfo || {};
|
|
@@ -244,7 +255,7 @@ var Container = ({
|
|
|
244
255
|
const layout = event.nativeEvent.layout;
|
|
245
256
|
const size = Math.floor(layout[horizontal ? "width" : "height"] * 8) / 8;
|
|
246
257
|
if (size === 0) {
|
|
247
|
-
if (layout.
|
|
258
|
+
if (layout.x !== POSITION_OUT_OF_VIEW && layout.y !== POSITION_OUT_OF_VIEW) {
|
|
248
259
|
console.log(
|
|
249
260
|
"[WARN] Container 0 height reported, possible bug in LegendList",
|
|
250
261
|
id,
|
|
@@ -276,7 +287,7 @@ var Container = ({
|
|
|
276
287
|
() => ({ containerId: id, itemKey, index, value: data }),
|
|
277
288
|
[id, itemKey, index, data]
|
|
278
289
|
);
|
|
279
|
-
const contentFragment = /* @__PURE__ */ React6__default.createElement(React6__default.Fragment, { key: recycleItems ? void 0 : itemKey }, /* @__PURE__ */ React6__default.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem,
|
|
290
|
+
const contentFragment = /* @__PURE__ */ React6__default.createElement(React6__default.Fragment, { key: recycleItems ? void 0 : itemKey }, /* @__PURE__ */ React6__default.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && !lastItemKeys.has(itemKey) && /* @__PURE__ */ React6__default.createElement(ItemSeparatorComponent, { leadingItem: renderedItemInfo.item })));
|
|
280
291
|
if (maintainVisibleContentPosition) {
|
|
281
292
|
const anchorStyle = position.type === "top" ? { position: "absolute", top: 0, left: 0, right: 0 } : { position: "absolute", bottom: 0, left: 0, right: 0 };
|
|
282
293
|
if (ENABLE_DEVMODE) {
|
|
@@ -287,6 +298,8 @@ var Container = ({
|
|
|
287
298
|
}
|
|
288
299
|
return /* @__PURE__ */ React6__default.createElement(LeanView, { style, onLayout, ref }, contentFragment);
|
|
289
300
|
};
|
|
301
|
+
var typedForwardRef = forwardRef;
|
|
302
|
+
var typedMemo = memo;
|
|
290
303
|
var useAnimatedValue = (initialValue) => {
|
|
291
304
|
return useRef(new Animated.Value(initialValue)).current;
|
|
292
305
|
};
|
|
@@ -315,7 +328,7 @@ function useValue$(key, getValue, useMicrotask) {
|
|
|
315
328
|
}
|
|
316
329
|
|
|
317
330
|
// src/Containers.tsx
|
|
318
|
-
var Containers =
|
|
331
|
+
var Containers = typedMemo(function Containers2({
|
|
319
332
|
horizontal,
|
|
320
333
|
recycleItems,
|
|
321
334
|
ItemSeparatorComponent,
|
|
@@ -325,7 +338,7 @@ var Containers = React6.memo(function Containers2({
|
|
|
325
338
|
}) {
|
|
326
339
|
const numContainers = use$("numContainersPooled");
|
|
327
340
|
const animSize = useValue$(
|
|
328
|
-
"
|
|
341
|
+
"totalSizeWithScrollAdjust",
|
|
329
342
|
void 0,
|
|
330
343
|
/*useMicrotask*/
|
|
331
344
|
true
|
|
@@ -334,7 +347,7 @@ var Containers = React6.memo(function Containers2({
|
|
|
334
347
|
const containers = [];
|
|
335
348
|
for (let i = 0; i < numContainers; i++) {
|
|
336
349
|
containers.push(
|
|
337
|
-
/* @__PURE__ */
|
|
350
|
+
/* @__PURE__ */ React.createElement(
|
|
338
351
|
Container,
|
|
339
352
|
{
|
|
340
353
|
id: i,
|
|
@@ -349,7 +362,7 @@ var Containers = React6.memo(function Containers2({
|
|
|
349
362
|
);
|
|
350
363
|
}
|
|
351
364
|
const style = horizontal ? { width: animSize, opacity: animOpacity } : { height: animSize, opacity: animOpacity };
|
|
352
|
-
return /* @__PURE__ */
|
|
365
|
+
return /* @__PURE__ */ React.createElement(Animated.View, { style }, containers);
|
|
353
366
|
});
|
|
354
367
|
|
|
355
368
|
// src/ListComponent.tsx
|
|
@@ -413,7 +426,7 @@ var PaddingAndAdjustDevMode = () => {
|
|
|
413
426
|
}
|
|
414
427
|
));
|
|
415
428
|
};
|
|
416
|
-
var ListComponent =
|
|
429
|
+
var ListComponent = typedMemo(function ListComponent2({
|
|
417
430
|
style,
|
|
418
431
|
contentContainerStyle,
|
|
419
432
|
horizontal,
|
|
@@ -434,6 +447,9 @@ var ListComponent = React6.memo(function ListComponent2({
|
|
|
434
447
|
refScrollView,
|
|
435
448
|
maintainVisibleContentPosition,
|
|
436
449
|
renderScrollComponent,
|
|
450
|
+
onRefresh,
|
|
451
|
+
refreshing,
|
|
452
|
+
progressViewOffset,
|
|
437
453
|
...rest
|
|
438
454
|
}) {
|
|
439
455
|
const ctx = useStateContext();
|
|
@@ -461,15 +477,12 @@ var ListComponent = React6.memo(function ListComponent2({
|
|
|
461
477
|
},
|
|
462
478
|
ENABLE_DEVMODE ? /* @__PURE__ */ React6.createElement(PaddingAndAdjustDevMode, null) : /* @__PURE__ */ React6.createElement(PaddingAndAdjust, null),
|
|
463
479
|
ListHeaderComponent && /* @__PURE__ */ React6.createElement(
|
|
464
|
-
|
|
480
|
+
View,
|
|
465
481
|
{
|
|
466
482
|
style: ListHeaderComponentStyle,
|
|
467
483
|
onLayout: (event) => {
|
|
468
484
|
const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
469
|
-
|
|
470
|
-
if (size !== prevSize) {
|
|
471
|
-
set$(ctx, "headerSize", size);
|
|
472
|
-
}
|
|
485
|
+
set$(ctx, "headerSize", size);
|
|
473
486
|
}
|
|
474
487
|
},
|
|
475
488
|
getComponent(ListHeaderComponent)
|
|
@@ -482,11 +495,21 @@ var ListComponent = React6.memo(function ListComponent2({
|
|
|
482
495
|
recycleItems,
|
|
483
496
|
waitForInitialLayout,
|
|
484
497
|
getRenderedItem,
|
|
485
|
-
ItemSeparatorComponent
|
|
498
|
+
ItemSeparatorComponent,
|
|
486
499
|
updateItemSize
|
|
487
500
|
}
|
|
488
501
|
),
|
|
489
|
-
ListFooterComponent && /* @__PURE__ */ React6.createElement(
|
|
502
|
+
ListFooterComponent && /* @__PURE__ */ React6.createElement(
|
|
503
|
+
View,
|
|
504
|
+
{
|
|
505
|
+
style: ListFooterComponentStyle,
|
|
506
|
+
onLayout: (event) => {
|
|
507
|
+
const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
508
|
+
set$(ctx, "footerSize", size);
|
|
509
|
+
}
|
|
510
|
+
},
|
|
511
|
+
getComponent(ListFooterComponent)
|
|
512
|
+
)
|
|
490
513
|
);
|
|
491
514
|
});
|
|
492
515
|
|
|
@@ -531,7 +554,6 @@ var ScrollAdjustHandler = class {
|
|
|
531
554
|
return false;
|
|
532
555
|
}
|
|
533
556
|
};
|
|
534
|
-
var typedForwardRef = forwardRef;
|
|
535
557
|
var useCombinedRef = (...refs) => {
|
|
536
558
|
const callback = useCallback((element) => {
|
|
537
559
|
for (const ref of refs) {
|
|
@@ -731,6 +753,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
731
753
|
waitForInitialLayout = true,
|
|
732
754
|
extraData,
|
|
733
755
|
onLayout: onLayoutProp,
|
|
756
|
+
onRefresh,
|
|
757
|
+
refreshing,
|
|
758
|
+
progressViewOffset,
|
|
734
759
|
...rest
|
|
735
760
|
} = props;
|
|
736
761
|
const { style, contentContainerStyle } = props;
|
|
@@ -796,13 +821,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
796
821
|
positions: /* @__PURE__ */ new Map(),
|
|
797
822
|
columns: /* @__PURE__ */ new Map(),
|
|
798
823
|
pendingAdjust: 0,
|
|
799
|
-
waitingForMicrotask: false,
|
|
800
824
|
isStartReached: initialContentOffset < initialScrollLength * onStartReachedThreshold,
|
|
801
825
|
isEndReached: false,
|
|
802
826
|
isAtBottom: false,
|
|
803
827
|
isAtTop: false,
|
|
804
828
|
data: dataProp,
|
|
805
|
-
idsInFirstRender: void 0,
|
|
806
829
|
hasScrolled: false,
|
|
807
830
|
scrollLength: initialScrollLength,
|
|
808
831
|
startBuffered: 0,
|
|
@@ -829,11 +852,12 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
829
852
|
belowAnchorElementPositions: void 0,
|
|
830
853
|
rowHeights: /* @__PURE__ */ new Map(),
|
|
831
854
|
startReachedBlockedByTimer: false,
|
|
855
|
+
endReachedBlockedByTimer: false,
|
|
832
856
|
scrollForNextCalculateItemsInView: void 0,
|
|
833
857
|
enableScrollForNextCalculateItemsInView: true,
|
|
834
|
-
minIndexSizeChanged: 0
|
|
858
|
+
minIndexSizeChanged: 0,
|
|
859
|
+
numPendingInitialLayout: 0
|
|
835
860
|
};
|
|
836
|
-
refState.current.idsInFirstRender = new Set(dataProp.map((_, i) => getId(i)));
|
|
837
861
|
if (maintainVisibleContentPosition) {
|
|
838
862
|
if (initialScrollIndex) {
|
|
839
863
|
refState.current.anchorElement = {
|
|
@@ -853,6 +877,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
853
877
|
set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
|
|
854
878
|
set$(ctx, "extraData", extraData);
|
|
855
879
|
}
|
|
880
|
+
const didDataChange = refState.current.data !== dataProp;
|
|
881
|
+
refState.current.data = dataProp;
|
|
856
882
|
const getAnchorElementIndex = () => {
|
|
857
883
|
const state = refState.current;
|
|
858
884
|
if (state.anchorElement) {
|
|
@@ -894,7 +920,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
894
920
|
});
|
|
895
921
|
}
|
|
896
922
|
}
|
|
897
|
-
set$(ctx, "totalSize",
|
|
923
|
+
set$(ctx, "totalSize", state.totalSize);
|
|
924
|
+
set$(ctx, "totalSizeWithScrollAdjust", resultSize);
|
|
898
925
|
if (alignItemsAtEnd) {
|
|
899
926
|
doUpdatePaddingTop();
|
|
900
927
|
}
|
|
@@ -964,10 +991,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
964
991
|
columns,
|
|
965
992
|
scrollAdjustHandler
|
|
966
993
|
} = state;
|
|
967
|
-
if (
|
|
968
|
-
state.waitingForMicrotask = false;
|
|
969
|
-
}
|
|
970
|
-
if (!data) {
|
|
994
|
+
if (!data || scrollLength === 0) {
|
|
971
995
|
return;
|
|
972
996
|
}
|
|
973
997
|
const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
|
|
@@ -1200,7 +1224,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1200
1224
|
}
|
|
1201
1225
|
}
|
|
1202
1226
|
}
|
|
1203
|
-
|
|
1227
|
+
if (state.numPendingInitialLayout === 0) {
|
|
1228
|
+
state.numPendingInitialLayout = state.endBuffered - state.startBuffered + 1;
|
|
1229
|
+
}
|
|
1204
1230
|
if (state.viewabilityConfigCallbackPairs) {
|
|
1205
1231
|
updateViewableItems(
|
|
1206
1232
|
state,
|
|
@@ -1215,9 +1241,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1215
1241
|
}, []);
|
|
1216
1242
|
const doUpdatePaddingTop = () => {
|
|
1217
1243
|
if (alignItemsAtEnd) {
|
|
1218
|
-
const { scrollLength
|
|
1219
|
-
const
|
|
1220
|
-
const paddingTop = Math.max(0, Math.floor(scrollLength -
|
|
1244
|
+
const { scrollLength } = refState.current;
|
|
1245
|
+
const contentSize = getContentSize(ctx);
|
|
1246
|
+
const paddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
|
|
1221
1247
|
set$(ctx, "paddingTop", paddingTop);
|
|
1222
1248
|
}
|
|
1223
1249
|
};
|
|
@@ -1237,29 +1263,48 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1237
1263
|
return true;
|
|
1238
1264
|
}
|
|
1239
1265
|
};
|
|
1266
|
+
const checkThreshold = (distance, threshold, isReached, isBlockedByTimer, onReached, blockTimer) => {
|
|
1267
|
+
const distanceAbs = Math.abs(distance);
|
|
1268
|
+
const isAtThreshold = distanceAbs < threshold;
|
|
1269
|
+
if (!isReached && !isBlockedByTimer) {
|
|
1270
|
+
if (isAtThreshold) {
|
|
1271
|
+
onReached == null ? void 0 : onReached(distance);
|
|
1272
|
+
blockTimer == null ? void 0 : blockTimer(true);
|
|
1273
|
+
setTimeout(() => {
|
|
1274
|
+
blockTimer == null ? void 0 : blockTimer(false);
|
|
1275
|
+
}, 700);
|
|
1276
|
+
return true;
|
|
1277
|
+
}
|
|
1278
|
+
} else {
|
|
1279
|
+
if (distance >= 1.3 * threshold) {
|
|
1280
|
+
return false;
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
return isReached;
|
|
1284
|
+
};
|
|
1240
1285
|
const checkAtBottom = () => {
|
|
1241
1286
|
if (!refState.current) {
|
|
1242
1287
|
return;
|
|
1243
1288
|
}
|
|
1244
|
-
const { scrollLength, scroll,
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
);
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
refState.current.
|
|
1289
|
+
const { scrollLength, scroll, hasScrolled } = refState.current;
|
|
1290
|
+
const contentSize = getContentSize(ctx);
|
|
1291
|
+
if (contentSize > 0 && hasScrolled) {
|
|
1292
|
+
const distanceFromEnd = contentSize - scroll - scrollLength;
|
|
1293
|
+
const distanceFromEndAbs = Math.abs(distanceFromEnd);
|
|
1294
|
+
refState.current.isAtBottom = distanceFromEndAbs < scrollLength * maintainScrollAtEndThreshold;
|
|
1295
|
+
refState.current.isEndReached = checkThreshold(
|
|
1296
|
+
distanceFromEnd,
|
|
1297
|
+
onEndReachedThreshold * scrollLength,
|
|
1298
|
+
refState.current.isEndReached,
|
|
1299
|
+
refState.current.endReachedBlockedByTimer,
|
|
1300
|
+
(distance) => {
|
|
1301
|
+
var _a2, _b2;
|
|
1302
|
+
return (_b2 = (_a2 = callbacks.current).onEndReached) == null ? void 0 : _b2.call(_a2, { distanceFromEnd: distance });
|
|
1303
|
+
},
|
|
1304
|
+
(block) => {
|
|
1305
|
+
refState.current.endReachedBlockedByTimer = block;
|
|
1261
1306
|
}
|
|
1262
|
-
|
|
1307
|
+
);
|
|
1263
1308
|
}
|
|
1264
1309
|
};
|
|
1265
1310
|
const checkAtTop = () => {
|
|
@@ -1268,22 +1313,21 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1268
1313
|
}
|
|
1269
1314
|
const { scrollLength, scroll } = refState.current;
|
|
1270
1315
|
const distanceFromTop = scroll;
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
}
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
refState.current.isStartReached = false;
|
|
1316
|
+
const distanceFromTopAbs = Math.abs(distanceFromTop);
|
|
1317
|
+
refState.current.isAtTop = distanceFromTopAbs < 0;
|
|
1318
|
+
refState.current.isStartReached = checkThreshold(
|
|
1319
|
+
distanceFromTop,
|
|
1320
|
+
onStartReachedThreshold * scrollLength,
|
|
1321
|
+
refState.current.isStartReached,
|
|
1322
|
+
refState.current.startReachedBlockedByTimer,
|
|
1323
|
+
(distance) => {
|
|
1324
|
+
var _a2, _b2;
|
|
1325
|
+
return (_b2 = (_a2 = callbacks.current).onStartReached) == null ? void 0 : _b2.call(_a2, { distanceFromStart: distance });
|
|
1326
|
+
},
|
|
1327
|
+
(block) => {
|
|
1328
|
+
refState.current.startReachedBlockedByTimer = block;
|
|
1285
1329
|
}
|
|
1286
|
-
|
|
1330
|
+
);
|
|
1287
1331
|
};
|
|
1288
1332
|
const checkResetContainers = (isFirst2) => {
|
|
1289
1333
|
const state = refState.current;
|
|
@@ -1394,12 +1438,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1394
1438
|
addTotalSize(null, totalSize, totalSizeBelowIndex);
|
|
1395
1439
|
};
|
|
1396
1440
|
const isFirst = !refState.current.renderItem;
|
|
1397
|
-
if (isFirst ||
|
|
1398
|
-
if (!keyExtractorProp && !isFirst &&
|
|
1441
|
+
if (isFirst || didDataChange || numColumnsProp !== peek$(ctx, "numColumns")) {
|
|
1442
|
+
if (!keyExtractorProp && !isFirst && didDataChange) {
|
|
1399
1443
|
refState.current.sizes.clear();
|
|
1400
1444
|
refState.current.positions.clear();
|
|
1401
1445
|
}
|
|
1402
|
-
refState.current.data = dataProp;
|
|
1403
1446
|
calcTotalSizesAndPositions({ forgetPositions: false });
|
|
1404
1447
|
}
|
|
1405
1448
|
useEffect(() => {
|
|
@@ -1412,17 +1455,22 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1412
1455
|
set$(ctx, "extraData", extraData);
|
|
1413
1456
|
}, [extraData]);
|
|
1414
1457
|
refState.current.renderItem = renderItem;
|
|
1415
|
-
const
|
|
1458
|
+
const memoizedLastItemKeys = useMemo(() => {
|
|
1459
|
+
if (!dataProp.length) return [];
|
|
1460
|
+
return new Set(
|
|
1461
|
+
Array.from({ length: Math.min(numColumnsProp, dataProp.length) }, (_, i) => getId(dataProp.length - 1 - i))
|
|
1462
|
+
);
|
|
1463
|
+
}, [dataProp.length, numColumnsProp, dataProp.slice(-numColumnsProp).toString()]);
|
|
1416
1464
|
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;
|
|
1417
1465
|
const initalizeStateVars = () => {
|
|
1418
|
-
set$(ctx, "
|
|
1466
|
+
set$(ctx, "lastItemKeys", memoizedLastItemKeys);
|
|
1419
1467
|
set$(ctx, "numColumns", numColumnsProp);
|
|
1420
1468
|
set$(ctx, "stylePaddingTop", stylePaddingTop);
|
|
1421
1469
|
};
|
|
1422
1470
|
if (isFirst) {
|
|
1423
1471
|
initalizeStateVars();
|
|
1424
1472
|
}
|
|
1425
|
-
useEffect(initalizeStateVars, [
|
|
1473
|
+
useEffect(initalizeStateVars, [memoizedLastItemKeys, numColumnsProp, stylePaddingTop]);
|
|
1426
1474
|
const getRenderedItem = useCallback((key) => {
|
|
1427
1475
|
var _a2, _b2;
|
|
1428
1476
|
const state = refState.current;
|
|
@@ -1454,34 +1502,40 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1454
1502
|
useRecyclingEffect: useRecyclingEffect2,
|
|
1455
1503
|
useRecyclingState: useRecyclingState2
|
|
1456
1504
|
});
|
|
1457
|
-
return { index, renderedItem };
|
|
1505
|
+
return { index, item: data[index], renderedItem };
|
|
1458
1506
|
}, []);
|
|
1459
|
-
|
|
1507
|
+
const doInitialAllocateContainers = () => {
|
|
1460
1508
|
var _a2;
|
|
1461
1509
|
const state = refState.current;
|
|
1462
|
-
const viewability = setupViewability(props);
|
|
1463
|
-
state.viewabilityConfigCallbackPairs = viewability;
|
|
1464
|
-
state.enableScrollForNextCalculateItemsInView = !viewability;
|
|
1465
1510
|
const scrollLength = state.scrollLength;
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1511
|
+
if (scrollLength > 0 && !peek$(ctx, "numContainers")) {
|
|
1512
|
+
const averageItemSize = (_a2 = estimatedItemSize != null ? estimatedItemSize : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(0, dataProp[0])) != null ? _a2 : DEFAULT_ITEM_SIZE;
|
|
1513
|
+
const numContainers = Math.ceil((scrollLength + scrollBuffer * 2) / averageItemSize) * numColumnsProp;
|
|
1514
|
+
for (let i = 0; i < numContainers; i++) {
|
|
1515
|
+
set$(ctx, `containerPosition${i}`, ANCHORED_POSITION_OUT_OF_VIEW);
|
|
1516
|
+
set$(ctx, `containerColumn${i}`, -1);
|
|
1517
|
+
}
|
|
1518
|
+
set$(ctx, "numContainers", numContainers);
|
|
1519
|
+
set$(ctx, "numContainersPooled", numContainers * 2);
|
|
1520
|
+
if (initialScrollIndex) {
|
|
1521
|
+
requestAnimationFrame(() => {
|
|
1522
|
+
calculateItemsInView(state.scrollVelocity);
|
|
1523
|
+
});
|
|
1524
|
+
} else {
|
|
1476
1525
|
calculateItemsInView(state.scrollVelocity);
|
|
1477
|
-
}
|
|
1478
|
-
} else {
|
|
1479
|
-
calculateItemsInView(state.scrollVelocity);
|
|
1526
|
+
}
|
|
1480
1527
|
}
|
|
1528
|
+
};
|
|
1529
|
+
useInit(() => {
|
|
1530
|
+
const state = refState.current;
|
|
1531
|
+
const viewability = setupViewability(props);
|
|
1532
|
+
state.viewabilityConfigCallbackPairs = viewability;
|
|
1533
|
+
state.enableScrollForNextCalculateItemsInView = !viewability;
|
|
1534
|
+
doInitialAllocateContainers();
|
|
1481
1535
|
});
|
|
1482
1536
|
const updateItemSize = useCallback((containerId, itemKey, size) => {
|
|
1483
1537
|
const state = refState.current;
|
|
1484
|
-
const { sizes, indexByKey,
|
|
1538
|
+
const { sizes, indexByKey, sizesLaidOut, data, rowHeights } = state;
|
|
1485
1539
|
if (!data) {
|
|
1486
1540
|
return;
|
|
1487
1541
|
}
|
|
@@ -1489,8 +1543,20 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1489
1543
|
const numColumns = peek$(ctx, "numColumns");
|
|
1490
1544
|
state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, index) : index;
|
|
1491
1545
|
const prevSize = getItemSize(itemKey, index, data);
|
|
1546
|
+
let needsCalculate = false;
|
|
1547
|
+
if (state.numPendingInitialLayout > 0) {
|
|
1548
|
+
state.numPendingInitialLayout--;
|
|
1549
|
+
if (state.numPendingInitialLayout === 0) {
|
|
1550
|
+
needsCalculate = true;
|
|
1551
|
+
state.numPendingInitialLayout = -1;
|
|
1552
|
+
queueMicrotask(() => {
|
|
1553
|
+
set$(ctx, "containersDidLayout", true);
|
|
1554
|
+
});
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1492
1557
|
if (!prevSize || Math.abs(prevSize - size) > 0.5) {
|
|
1493
1558
|
let diff;
|
|
1559
|
+
needsCalculate = true;
|
|
1494
1560
|
if (numColumns > 1) {
|
|
1495
1561
|
const rowNumber = Math.floor(index / numColumnsProp);
|
|
1496
1562
|
const prevSizeInRow = getRowHeight(rowNumber);
|
|
@@ -1524,22 +1590,20 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1524
1590
|
refState.current.scrollForNextCalculateItemsInView = void 0;
|
|
1525
1591
|
addTotalSize(itemKey, diff, 0);
|
|
1526
1592
|
doMaintainScrollAtEnd(true);
|
|
1527
|
-
const scrollVelocity = state.scrollVelocity;
|
|
1528
|
-
if (!state.waitingForMicrotask && (Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1)) {
|
|
1529
|
-
if (!peek$(ctx, "containersDidLayout")) {
|
|
1530
|
-
state.waitingForMicrotask = true;
|
|
1531
|
-
queueMicrotask(() => {
|
|
1532
|
-
if (state.waitingForMicrotask) {
|
|
1533
|
-
state.waitingForMicrotask = false;
|
|
1534
|
-
calculateItemsInView(state.scrollVelocity);
|
|
1535
|
-
}
|
|
1536
|
-
});
|
|
1537
|
-
} else {
|
|
1538
|
-
calculateItemsInView(state.scrollVelocity);
|
|
1539
|
-
}
|
|
1540
|
-
}
|
|
1541
1593
|
if (onItemSizeChanged) {
|
|
1542
|
-
onItemSizeChanged({
|
|
1594
|
+
onItemSizeChanged({
|
|
1595
|
+
size,
|
|
1596
|
+
previous: prevSize,
|
|
1597
|
+
index,
|
|
1598
|
+
itemKey,
|
|
1599
|
+
itemData: data[index]
|
|
1600
|
+
});
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
if (needsCalculate) {
|
|
1604
|
+
const scrollVelocity = state.scrollVelocity;
|
|
1605
|
+
if ((Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1) && (!waitForInitialLayout || state.numPendingInitialLayout < 0)) {
|
|
1606
|
+
calculateItemsInView(state.scrollVelocity);
|
|
1543
1607
|
}
|
|
1544
1608
|
}
|
|
1545
1609
|
}, []);
|
|
@@ -1551,7 +1615,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1551
1615
|
const onLayout = useCallback((event) => {
|
|
1552
1616
|
const scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
|
|
1553
1617
|
const didChange = scrollLength !== refState.current.scrollLength;
|
|
1618
|
+
refState.current.scrollLength;
|
|
1554
1619
|
refState.current.scrollLength = scrollLength;
|
|
1620
|
+
doInitialAllocateContainers();
|
|
1555
1621
|
doMaintainScrollAtEnd(false);
|
|
1556
1622
|
doUpdatePaddingTop();
|
|
1557
1623
|
checkAtBottom();
|
|
@@ -1671,7 +1737,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1671
1737
|
scrollToIndex({ index, animated });
|
|
1672
1738
|
}
|
|
1673
1739
|
},
|
|
1674
|
-
scrollToEnd: () => refScroller.current.scrollToEnd()
|
|
1740
|
+
scrollToEnd: (options) => refScroller.current.scrollToEnd(options)
|
|
1675
1741
|
};
|
|
1676
1742
|
},
|
|
1677
1743
|
[]
|
|
@@ -1704,6 +1770,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1704
1770
|
maintainVisibleContentPosition,
|
|
1705
1771
|
scrollEventThrottle: scrollEventThrottle != null ? scrollEventThrottle : Platform.OS === "web" ? 16 : void 0,
|
|
1706
1772
|
waitForInitialLayout,
|
|
1773
|
+
refreshControl: props.refreshControl == null ? /* @__PURE__ */ React6.createElement(
|
|
1774
|
+
RefreshControl,
|
|
1775
|
+
{
|
|
1776
|
+
refreshing: !!refreshing,
|
|
1777
|
+
onRefresh,
|
|
1778
|
+
progressViewOffset
|
|
1779
|
+
}
|
|
1780
|
+
) : props.refreshControl,
|
|
1707
1781
|
style
|
|
1708
1782
|
}
|
|
1709
1783
|
), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React6.createElement(DebugView, { state: refState.current }));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/list",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.18",
|
|
4
4
|
"description": "Legend List aims to be a drop-in replacement for FlatList with much better performance and supporting dynamically sized items.",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"private": false,
|
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" | "onItemSizeChanged";
|
|
5
|
+
type KeysToOmit = "getEstimatedItemSize" | "keyExtractor" | "animatedProps" | "renderItem" | "onItemSizeChanged" | "ItemSeparatorComponent";
|
|
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" | "onItemSizeChanged";
|
|
5
|
+
type KeysToOmit = "getEstimatedItemSize" | "keyExtractor" | "animatedProps" | "renderItem" | "onItemSizeChanged" | "ItemSeparatorComponent";
|
|
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>;
|