@legendapp/list 1.0.0-beta.12 → 1.0.0-beta.14

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 CHANGED
@@ -7,12 +7,15 @@ import Animated from 'react-native-reanimated';
7
7
  declare class ScrollAdjustHandler {
8
8
  private ctx;
9
9
  private appliedAdjust;
10
- private pendingAdjust;
11
10
  private busy;
12
11
  private context;
12
+ private isPaused;
13
13
  constructor(ctx: any);
14
+ private doAjdust;
14
15
  requestAdjust(adjust: number, onAdjusted: (diff: number) => void): void;
15
16
  getAppliedAdjust(): number;
17
+ pauseAdjust(): void;
18
+ unPauseAdjust(): boolean;
16
19
  }
17
20
 
18
21
  type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof ScrollView> | ComponentProps<typeof Animated.ScrollView>> = Omit<TScrollView, "contentOffset" | "contentInset" | "maintainVisibleContentPosition" | "stickyHeaderIndices"> & {
package/index.d.ts CHANGED
@@ -7,12 +7,15 @@ import Animated from 'react-native-reanimated';
7
7
  declare class ScrollAdjustHandler {
8
8
  private ctx;
9
9
  private appliedAdjust;
10
- private pendingAdjust;
11
10
  private busy;
12
11
  private context;
12
+ private isPaused;
13
13
  constructor(ctx: any);
14
+ private doAjdust;
14
15
  requestAdjust(adjust: number, onAdjusted: (diff: number) => void): void;
15
16
  getAppliedAdjust(): number;
17
+ pauseAdjust(): void;
18
+ unPauseAdjust(): boolean;
16
19
  }
17
20
 
18
21
  type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof ScrollView> | ComponentProps<typeof Animated.ScrollView>> = Omit<TScrollView, "contentOffset" | "contentInset" | "maintainVisibleContentPosition" | "stickyHeaderIndices"> & {
package/index.js CHANGED
@@ -191,10 +191,11 @@ function useInterval(callback, delay) {
191
191
  return () => clearInterval(interval);
192
192
  }, [delay]);
193
193
  }
194
- var LeanView = React6__namespace.forwardRef((props, ref) => {
194
+ var LeanViewComponent = React6__namespace.forwardRef((props, ref) => {
195
195
  return React6__namespace.createElement("RCTView", { ...props, ref });
196
196
  });
197
- LeanView.displayName = "RCTView";
197
+ LeanViewComponent.displayName = "RCTView";
198
+ var LeanView = reactNative.Platform.OS === "android" || reactNative.Platform.OS === "ios" ? LeanViewComponent : reactNative.View;
198
199
 
199
200
  // src/constants.ts
200
201
  var POSITION_OUT_OF_VIEW = -1e7;
@@ -288,6 +289,8 @@ var Container = ({
288
289
  var useAnimatedValue = reactNative.useAnimatedValue || ((initialValue) => {
289
290
  return React6.useRef(new reactNative.Animated.Value(initialValue)).current;
290
291
  });
292
+
293
+ // src/useValue$.ts
291
294
  function useValue$(key, getValue, useMicrotask) {
292
295
  var _a;
293
296
  const ctx = useStateContext();
@@ -491,30 +494,41 @@ var ScrollAdjustHandler = class {
491
494
  constructor(ctx) {
492
495
  this.ctx = ctx;
493
496
  this.appliedAdjust = 0;
494
- this.pendingAdjust = 0;
495
497
  this.busy = false;
498
+ this.isPaused = false;
496
499
  this.context = ctx;
497
500
  }
501
+ doAjdust() {
502
+ set$(this.context, "scrollAdjust", this.appliedAdjust);
503
+ this.busy = false;
504
+ }
498
505
  requestAdjust(adjust, onAdjusted) {
499
506
  const oldAdjustTop = peek$(this.context, "scrollAdjust");
500
507
  if (oldAdjustTop === adjust) {
501
508
  return;
502
509
  }
503
510
  this.appliedAdjust = adjust;
504
- this.pendingAdjust = adjust;
505
- const doAjdust = () => {
506
- set$(this.context, "scrollAdjust", this.pendingAdjust);
507
- onAdjusted(oldAdjustTop - this.pendingAdjust);
508
- this.busy = false;
509
- };
510
- if (!this.busy) {
511
+ if (!this.busy && !this.isPaused) {
511
512
  this.busy = true;
512
- doAjdust();
513
+ this.doAjdust();
514
+ onAdjusted(oldAdjustTop - adjust);
513
515
  }
514
516
  }
515
517
  getAppliedAdjust() {
516
518
  return this.appliedAdjust;
517
519
  }
520
+ pauseAdjust() {
521
+ this.isPaused = true;
522
+ }
523
+ // return true if it was paused
524
+ unPauseAdjust() {
525
+ if (this.isPaused) {
526
+ this.isPaused = false;
527
+ this.doAjdust();
528
+ return true;
529
+ }
530
+ return false;
531
+ }
518
532
  };
519
533
  var typedForwardRef = React6.forwardRef;
520
534
  var useCombinedRef = (...refs) => {
@@ -687,7 +701,7 @@ var LegendList = typedForwardRef(function LegendList2(props, forwardedRef) {
687
701
  return /* @__PURE__ */ React6__namespace.createElement(StateProvider, null, /* @__PURE__ */ React6__namespace.createElement(LegendListInner, { ...props, ref: forwardedRef }));
688
702
  });
689
703
  var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
690
- var _a, _b, _c, _d, _e, _f, _g;
704
+ var _a, _b, _c, _d;
691
705
  const {
692
706
  data: dataProp,
693
707
  initialScrollIndex,
@@ -702,6 +716,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
702
716
  alignItemsAtEnd = false,
703
717
  maintainVisibleContentPosition = false,
704
718
  onScroll: onScrollProp,
719
+ onMomentumScrollEnd,
705
720
  numColumns: numColumnsProp = 1,
706
721
  keyExtractor: keyExtractorProp,
707
722
  renderItem,
@@ -748,13 +763,20 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
748
763
  refState.current.sizes.set(key, size);
749
764
  return size;
750
765
  };
751
- const calculateInitialOffset = (index = initialScrollIndex) => {
766
+ const calculateOffsetForIndex = (index = initialScrollIndex) => {
752
767
  const data = dataProp;
753
768
  if (index) {
754
769
  let offset = 0;
755
- if (getEstimatedItemSize) {
770
+ const canGetSize = !!refState.current;
771
+ if (canGetSize || getEstimatedItemSize) {
772
+ const sizeFn = (index2) => {
773
+ if (canGetSize) {
774
+ return getItemSize(getId(index2), index2, data[index2]);
775
+ }
776
+ return getEstimatedItemSize(index2, data[index2]);
777
+ };
756
778
  for (let i = 0; i < index; i++) {
757
- offset += getEstimatedItemSize(i, data[i]);
779
+ offset += sizeFn(i);
758
780
  }
759
781
  } else if (estimatedItemSize) {
760
782
  offset = index * estimatedItemSize;
@@ -763,7 +785,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
763
785
  }
764
786
  return 0;
765
787
  };
766
- const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : React6.useMemo(calculateInitialOffset, []);
788
+ const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : React6.useMemo(calculateOffsetForIndex, []);
767
789
  if (!refState.current) {
768
790
  const initialScrollLength = reactNative.Dimensions.get("window")[horizontal ? "width" : "height"];
769
791
  refState.current = {
@@ -915,17 +937,20 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
915
937
  return map;
916
938
  };
917
939
  const getElementPositionBelowAchor = (id) => {
940
+ var _a2;
918
941
  const state = refState.current;
919
942
  if (!refState.current.belowAnchorElementPositions) {
920
943
  state.belowAnchorElementPositions = buildElementPositionsBelowAnchor();
921
944
  }
922
945
  const res = state.belowAnchorElementPositions.get(id);
923
946
  if (res === void 0) {
924
- throw new Error("Undefined position below achor");
947
+ console.warn(`Undefined position below achor ${id} ${(_a2 = state.anchorElement) == null ? void 0 : _a2.id}`);
948
+ return 0;
925
949
  }
926
950
  return res;
927
951
  };
928
952
  const calculateItemsInView = React6.useCallback((speed) => {
953
+ var _a2;
929
954
  const state = refState.current;
930
955
  const {
931
956
  data,
@@ -1003,14 +1028,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1003
1028
  let column = 1;
1004
1029
  let maxSizeInRow = 0;
1005
1030
  const getInitialTop = (i) => {
1006
- var _a2;
1031
+ var _a3;
1007
1032
  const id = getId(i);
1008
1033
  let topOffset = 0;
1009
1034
  if (positions.get(id)) {
1010
1035
  topOffset = positions.get(id);
1011
1036
  }
1012
- if (id === ((_a2 = state.anchorElement) == null ? void 0 : _a2.id)) {
1013
- topOffset = initialContentOffset || 0;
1037
+ if (id === ((_a3 = state.anchorElement) == null ? void 0 : _a3.id)) {
1038
+ topOffset = state.anchorElement.coordinate;
1014
1039
  }
1015
1040
  return topOffset;
1016
1041
  };
@@ -1018,7 +1043,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1018
1043
  const id = getId(i);
1019
1044
  const size = getItemSize(id, i, data[i]);
1020
1045
  maxSizeInRow = Math.max(maxSizeInRow, size);
1021
- if (top === void 0) {
1046
+ if (top === void 0 || id === ((_a2 = state.anchorElement) == null ? void 0 : _a2.id)) {
1022
1047
  top = getInitialTop(i);
1023
1048
  }
1024
1049
  if (positions.get(id) !== top) {
@@ -1284,18 +1309,17 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1284
1309
  }
1285
1310
  }
1286
1311
  };
1287
- const isFirst = !refState.current.renderItem;
1288
- if (isFirst || dataProp !== refState.current.data || numColumnsProp !== peek$(ctx, "numColumns")) {
1289
- if (!keyExtractorProp && !isFirst && dataProp !== refState.current.data) {
1290
- refState.current.positions.clear();
1291
- }
1292
- refState.current.data = dataProp;
1312
+ const calcTotalSizesAndPositions = ({ forgetPositions = false }) => {
1313
+ var _a2, _b2, _c2;
1293
1314
  let totalSize = 0;
1294
1315
  let totalSizeBelowIndex = 0;
1295
1316
  const indexByKey = /* @__PURE__ */ new Map();
1296
1317
  const newPositions = /* @__PURE__ */ new Map();
1297
1318
  let column = 1;
1298
1319
  let maxSizeInRow = 0;
1320
+ if (!refState.current) {
1321
+ return;
1322
+ }
1299
1323
  for (let i = 0; i < dataProp.length; i++) {
1300
1324
  const key = getId(i);
1301
1325
  if (__DEV__) {
@@ -1306,13 +1330,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1306
1330
  }
1307
1331
  }
1308
1332
  indexByKey.set(key, i);
1309
- if (refState.current.positions.get(key) != null && refState.current.indexByKey.get(key) === i) {
1333
+ if (!forgetPositions && refState.current.positions.get(key) != null && refState.current.indexByKey.get(key) === i) {
1310
1334
  newPositions.set(key, refState.current.positions.get(key));
1311
1335
  }
1312
1336
  }
1313
1337
  refState.current.indexByKey = indexByKey;
1314
1338
  refState.current.positions = newPositions;
1315
- if (!isFirst) {
1339
+ if (!forgetPositions && !isFirst) {
1316
1340
  if (maintainVisibleContentPosition) {
1317
1341
  if (refState.current.anchorElement == null || indexByKey.get(refState.current.anchorElement.id) == null) {
1318
1342
  if (dataProp.length) {
@@ -1321,8 +1345,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1321
1345
  id: getId(0)
1322
1346
  };
1323
1347
  refState.current.anchorElement = newAnchorElement;
1324
- (_a = refState.current.belowAnchorElementPositions) == null ? void 0 : _a.clear();
1325
- (_b = refScroller.current) == null ? void 0 : _b.scrollTo({ x: 0, y: 0, animated: false });
1348
+ (_a2 = refState.current.belowAnchorElementPositions) == null ? void 0 : _a2.clear();
1349
+ (_b2 = refScroller.current) == null ? void 0 : _b2.scrollTo({ x: 0, y: 0, animated: false });
1326
1350
  setTimeout(() => {
1327
1351
  calculateItemsInView(0);
1328
1352
  }, 0);
@@ -1337,7 +1361,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1337
1361
  } else {
1338
1362
  refState.current.startBufferedId = void 0;
1339
1363
  }
1340
- (_c = refScroller.current) == null ? void 0 : _c.scrollTo({ x: 0, y: 0, animated: false });
1364
+ (_c2 = refScroller.current) == null ? void 0 : _c2.scrollTo({ x: 0, y: 0, animated: false });
1341
1365
  setTimeout(() => {
1342
1366
  calculateItemsInView(0);
1343
1367
  }, 0);
@@ -1363,6 +1387,21 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1363
1387
  totalSize += maxSizeInRow;
1364
1388
  }
1365
1389
  addTotalSize(null, totalSize, totalSizeBelowIndex);
1390
+ };
1391
+ const isFirst = !refState.current.renderItem;
1392
+ if (isFirst || dataProp !== refState.current.data || numColumnsProp !== peek$(ctx, "numColumns")) {
1393
+ if (!keyExtractorProp && !isFirst && dataProp !== refState.current.data) {
1394
+ refState.current.sizes.clear();
1395
+ refState.current.positions.clear();
1396
+ }
1397
+ refState.current.data = dataProp;
1398
+ const indexByKey = /* @__PURE__ */ new Map();
1399
+ for (let i = 0; i < dataProp.length; i++) {
1400
+ const key = getId(i);
1401
+ indexByKey.set(key, i);
1402
+ }
1403
+ refState.current.indexByKey = indexByKey;
1404
+ calcTotalSizesAndPositions({ forgetPositions: false });
1366
1405
  }
1367
1406
  React6.useEffect(() => {
1368
1407
  checkResetContainers(
@@ -1375,7 +1414,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1375
1414
  }, [extraData]);
1376
1415
  refState.current.renderItem = renderItem;
1377
1416
  const lastItemKey = dataProp.length > 0 ? getId(dataProp.length - 1) : void 0;
1378
- const stylePaddingTop = (_g = (_f = (_d = reactNative.StyleSheet.flatten(style)) == null ? void 0 : _d.paddingTop) != null ? _f : (_e = reactNative.StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _e.paddingTop) != null ? _g : 0;
1417
+ 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;
1379
1418
  const initalizeStateVars = () => {
1380
1419
  set$(ctx, "lastItemKey", lastItemKey);
1381
1420
  set$(ctx, "numColumns", numColumnsProp);
@@ -1579,10 +1618,42 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1579
1618
  React6.useImperativeHandle(
1580
1619
  forwardedRef,
1581
1620
  () => {
1582
- const scrollToIndex = ({ index, animated }) => {
1583
- const offsetObj = calculateInitialOffset(index);
1584
- const offset = horizontal ? { x: offsetObj, y: 0 } : { x: 0, y: offsetObj };
1585
- refScroller.current.scrollTo({ ...offset, animated });
1621
+ const scrollToIndex = ({ index, animated = true }) => {
1622
+ var _a2;
1623
+ const state = refState.current;
1624
+ const firstIndexOffset = calculateOffsetForIndex(index);
1625
+ let firstIndexScrollPostion = firstIndexOffset;
1626
+ if (maintainVisibleContentPosition) {
1627
+ const id = getId(index);
1628
+ state.anchorElement = { id, coordinate: firstIndexOffset };
1629
+ (_a2 = state.belowAnchorElementPositions) == null ? void 0 : _a2.clear();
1630
+ state.positions.clear();
1631
+ calcTotalSizesAndPositions({ forgetPositions: true });
1632
+ state.scrollForNextCalculateItemsInView = void 0;
1633
+ state.startBufferedId = id;
1634
+ state.minIndexSizeChanged = index;
1635
+ firstIndexScrollPostion = firstIndexOffset + state.scrollAdjustHandler.getAppliedAdjust();
1636
+ state.scrollAdjustHandler.pauseAdjust();
1637
+ setTimeout(
1638
+ () => {
1639
+ const wasAdjusted = state.scrollAdjustHandler.unPauseAdjust();
1640
+ if (wasAdjusted) {
1641
+ refState.current.scrollVelocity = 0;
1642
+ refState.current.scrollHistory = [];
1643
+ calculateItemsInView(0);
1644
+ }
1645
+ },
1646
+ animated ? 1e3 : 50
1647
+ );
1648
+ }
1649
+ const offset = horizontal ? { x: firstIndexScrollPostion, y: 0 } : { x: 0, y: firstIndexScrollPostion };
1650
+ if (maintainVisibleContentPosition) {
1651
+ setTimeout(() => {
1652
+ refScroller.current.scrollTo({ ...offset, animated });
1653
+ }, 50);
1654
+ } else {
1655
+ refScroller.current.scrollTo({ ...offset, animated });
1656
+ }
1586
1657
  };
1587
1658
  return {
1588
1659
  getNativeScrollRef: () => refScroller.current,
@@ -1616,6 +1687,17 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1616
1687
  getRenderedItem,
1617
1688
  updateItemSize,
1618
1689
  handleScroll,
1690
+ onMomentumScrollEnd: (event) => {
1691
+ const wasPaused = refState.current.scrollAdjustHandler.unPauseAdjust();
1692
+ if (wasPaused) {
1693
+ refState.current.scrollVelocity = 0;
1694
+ refState.current.scrollHistory = [];
1695
+ calculateItemsInView(0);
1696
+ }
1697
+ if (onMomentumScrollEnd) {
1698
+ onMomentumScrollEnd(event);
1699
+ }
1700
+ },
1619
1701
  onLayout,
1620
1702
  recycleItems,
1621
1703
  alignItemsAtEnd,
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, Animated, ScrollView, Dimensions, StyleSheet, Platform, useAnimatedValue as useAnimatedValue$1 } from 'react-native';
3
+ import { View, Text, Platform, Animated, ScrollView, Dimensions, StyleSheet, useAnimatedValue as useAnimatedValue$1 } from 'react-native';
4
4
 
5
5
  // src/LegendList.tsx
6
6
  var ContextState = React6.createContext(null);
@@ -170,10 +170,11 @@ function useInterval(callback, delay) {
170
170
  return () => clearInterval(interval);
171
171
  }, [delay]);
172
172
  }
173
- var LeanView = React6.forwardRef((props, ref) => {
173
+ var LeanViewComponent = React6.forwardRef((props, ref) => {
174
174
  return React6.createElement("RCTView", { ...props, ref });
175
175
  });
176
- LeanView.displayName = "RCTView";
176
+ LeanViewComponent.displayName = "RCTView";
177
+ var LeanView = Platform.OS === "android" || Platform.OS === "ios" ? LeanViewComponent : View;
177
178
 
178
179
  // src/constants.ts
179
180
  var POSITION_OUT_OF_VIEW = -1e7;
@@ -267,6 +268,8 @@ var Container = ({
267
268
  var useAnimatedValue = useAnimatedValue$1 || ((initialValue) => {
268
269
  return useRef(new Animated.Value(initialValue)).current;
269
270
  });
271
+
272
+ // src/useValue$.ts
270
273
  function useValue$(key, getValue, useMicrotask) {
271
274
  var _a;
272
275
  const ctx = useStateContext();
@@ -470,30 +473,41 @@ var ScrollAdjustHandler = class {
470
473
  constructor(ctx) {
471
474
  this.ctx = ctx;
472
475
  this.appliedAdjust = 0;
473
- this.pendingAdjust = 0;
474
476
  this.busy = false;
477
+ this.isPaused = false;
475
478
  this.context = ctx;
476
479
  }
480
+ doAjdust() {
481
+ set$(this.context, "scrollAdjust", this.appliedAdjust);
482
+ this.busy = false;
483
+ }
477
484
  requestAdjust(adjust, onAdjusted) {
478
485
  const oldAdjustTop = peek$(this.context, "scrollAdjust");
479
486
  if (oldAdjustTop === adjust) {
480
487
  return;
481
488
  }
482
489
  this.appliedAdjust = adjust;
483
- this.pendingAdjust = adjust;
484
- const doAjdust = () => {
485
- set$(this.context, "scrollAdjust", this.pendingAdjust);
486
- onAdjusted(oldAdjustTop - this.pendingAdjust);
487
- this.busy = false;
488
- };
489
- if (!this.busy) {
490
+ if (!this.busy && !this.isPaused) {
490
491
  this.busy = true;
491
- doAjdust();
492
+ this.doAjdust();
493
+ onAdjusted(oldAdjustTop - adjust);
492
494
  }
493
495
  }
494
496
  getAppliedAdjust() {
495
497
  return this.appliedAdjust;
496
498
  }
499
+ pauseAdjust() {
500
+ this.isPaused = true;
501
+ }
502
+ // return true if it was paused
503
+ unPauseAdjust() {
504
+ if (this.isPaused) {
505
+ this.isPaused = false;
506
+ this.doAjdust();
507
+ return true;
508
+ }
509
+ return false;
510
+ }
497
511
  };
498
512
  var typedForwardRef = forwardRef;
499
513
  var useCombinedRef = (...refs) => {
@@ -666,7 +680,7 @@ var LegendList = typedForwardRef(function LegendList2(props, forwardedRef) {
666
680
  return /* @__PURE__ */ React6.createElement(StateProvider, null, /* @__PURE__ */ React6.createElement(LegendListInner, { ...props, ref: forwardedRef }));
667
681
  });
668
682
  var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
669
- var _a, _b, _c, _d, _e, _f, _g;
683
+ var _a, _b, _c, _d;
670
684
  const {
671
685
  data: dataProp,
672
686
  initialScrollIndex,
@@ -681,6 +695,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
681
695
  alignItemsAtEnd = false,
682
696
  maintainVisibleContentPosition = false,
683
697
  onScroll: onScrollProp,
698
+ onMomentumScrollEnd,
684
699
  numColumns: numColumnsProp = 1,
685
700
  keyExtractor: keyExtractorProp,
686
701
  renderItem,
@@ -727,13 +742,20 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
727
742
  refState.current.sizes.set(key, size);
728
743
  return size;
729
744
  };
730
- const calculateInitialOffset = (index = initialScrollIndex) => {
745
+ const calculateOffsetForIndex = (index = initialScrollIndex) => {
731
746
  const data = dataProp;
732
747
  if (index) {
733
748
  let offset = 0;
734
- if (getEstimatedItemSize) {
749
+ const canGetSize = !!refState.current;
750
+ if (canGetSize || getEstimatedItemSize) {
751
+ const sizeFn = (index2) => {
752
+ if (canGetSize) {
753
+ return getItemSize(getId(index2), index2, data[index2]);
754
+ }
755
+ return getEstimatedItemSize(index2, data[index2]);
756
+ };
735
757
  for (let i = 0; i < index; i++) {
736
- offset += getEstimatedItemSize(i, data[i]);
758
+ offset += sizeFn(i);
737
759
  }
738
760
  } else if (estimatedItemSize) {
739
761
  offset = index * estimatedItemSize;
@@ -742,7 +764,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
742
764
  }
743
765
  return 0;
744
766
  };
745
- const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : useMemo(calculateInitialOffset, []);
767
+ const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : useMemo(calculateOffsetForIndex, []);
746
768
  if (!refState.current) {
747
769
  const initialScrollLength = Dimensions.get("window")[horizontal ? "width" : "height"];
748
770
  refState.current = {
@@ -894,17 +916,20 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
894
916
  return map;
895
917
  };
896
918
  const getElementPositionBelowAchor = (id) => {
919
+ var _a2;
897
920
  const state = refState.current;
898
921
  if (!refState.current.belowAnchorElementPositions) {
899
922
  state.belowAnchorElementPositions = buildElementPositionsBelowAnchor();
900
923
  }
901
924
  const res = state.belowAnchorElementPositions.get(id);
902
925
  if (res === void 0) {
903
- throw new Error("Undefined position below achor");
926
+ console.warn(`Undefined position below achor ${id} ${(_a2 = state.anchorElement) == null ? void 0 : _a2.id}`);
927
+ return 0;
904
928
  }
905
929
  return res;
906
930
  };
907
931
  const calculateItemsInView = useCallback((speed) => {
932
+ var _a2;
908
933
  const state = refState.current;
909
934
  const {
910
935
  data,
@@ -982,14 +1007,14 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
982
1007
  let column = 1;
983
1008
  let maxSizeInRow = 0;
984
1009
  const getInitialTop = (i) => {
985
- var _a2;
1010
+ var _a3;
986
1011
  const id = getId(i);
987
1012
  let topOffset = 0;
988
1013
  if (positions.get(id)) {
989
1014
  topOffset = positions.get(id);
990
1015
  }
991
- if (id === ((_a2 = state.anchorElement) == null ? void 0 : _a2.id)) {
992
- topOffset = initialContentOffset || 0;
1016
+ if (id === ((_a3 = state.anchorElement) == null ? void 0 : _a3.id)) {
1017
+ topOffset = state.anchorElement.coordinate;
993
1018
  }
994
1019
  return topOffset;
995
1020
  };
@@ -997,7 +1022,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
997
1022
  const id = getId(i);
998
1023
  const size = getItemSize(id, i, data[i]);
999
1024
  maxSizeInRow = Math.max(maxSizeInRow, size);
1000
- if (top === void 0) {
1025
+ if (top === void 0 || id === ((_a2 = state.anchorElement) == null ? void 0 : _a2.id)) {
1001
1026
  top = getInitialTop(i);
1002
1027
  }
1003
1028
  if (positions.get(id) !== top) {
@@ -1263,18 +1288,17 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1263
1288
  }
1264
1289
  }
1265
1290
  };
1266
- const isFirst = !refState.current.renderItem;
1267
- if (isFirst || dataProp !== refState.current.data || numColumnsProp !== peek$(ctx, "numColumns")) {
1268
- if (!keyExtractorProp && !isFirst && dataProp !== refState.current.data) {
1269
- refState.current.positions.clear();
1270
- }
1271
- refState.current.data = dataProp;
1291
+ const calcTotalSizesAndPositions = ({ forgetPositions = false }) => {
1292
+ var _a2, _b2, _c2;
1272
1293
  let totalSize = 0;
1273
1294
  let totalSizeBelowIndex = 0;
1274
1295
  const indexByKey = /* @__PURE__ */ new Map();
1275
1296
  const newPositions = /* @__PURE__ */ new Map();
1276
1297
  let column = 1;
1277
1298
  let maxSizeInRow = 0;
1299
+ if (!refState.current) {
1300
+ return;
1301
+ }
1278
1302
  for (let i = 0; i < dataProp.length; i++) {
1279
1303
  const key = getId(i);
1280
1304
  if (__DEV__) {
@@ -1285,13 +1309,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1285
1309
  }
1286
1310
  }
1287
1311
  indexByKey.set(key, i);
1288
- if (refState.current.positions.get(key) != null && refState.current.indexByKey.get(key) === i) {
1312
+ if (!forgetPositions && refState.current.positions.get(key) != null && refState.current.indexByKey.get(key) === i) {
1289
1313
  newPositions.set(key, refState.current.positions.get(key));
1290
1314
  }
1291
1315
  }
1292
1316
  refState.current.indexByKey = indexByKey;
1293
1317
  refState.current.positions = newPositions;
1294
- if (!isFirst) {
1318
+ if (!forgetPositions && !isFirst) {
1295
1319
  if (maintainVisibleContentPosition) {
1296
1320
  if (refState.current.anchorElement == null || indexByKey.get(refState.current.anchorElement.id) == null) {
1297
1321
  if (dataProp.length) {
@@ -1300,8 +1324,8 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1300
1324
  id: getId(0)
1301
1325
  };
1302
1326
  refState.current.anchorElement = newAnchorElement;
1303
- (_a = refState.current.belowAnchorElementPositions) == null ? void 0 : _a.clear();
1304
- (_b = refScroller.current) == null ? void 0 : _b.scrollTo({ x: 0, y: 0, animated: false });
1327
+ (_a2 = refState.current.belowAnchorElementPositions) == null ? void 0 : _a2.clear();
1328
+ (_b2 = refScroller.current) == null ? void 0 : _b2.scrollTo({ x: 0, y: 0, animated: false });
1305
1329
  setTimeout(() => {
1306
1330
  calculateItemsInView(0);
1307
1331
  }, 0);
@@ -1316,7 +1340,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1316
1340
  } else {
1317
1341
  refState.current.startBufferedId = void 0;
1318
1342
  }
1319
- (_c = refScroller.current) == null ? void 0 : _c.scrollTo({ x: 0, y: 0, animated: false });
1343
+ (_c2 = refScroller.current) == null ? void 0 : _c2.scrollTo({ x: 0, y: 0, animated: false });
1320
1344
  setTimeout(() => {
1321
1345
  calculateItemsInView(0);
1322
1346
  }, 0);
@@ -1342,6 +1366,21 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1342
1366
  totalSize += maxSizeInRow;
1343
1367
  }
1344
1368
  addTotalSize(null, totalSize, totalSizeBelowIndex);
1369
+ };
1370
+ const isFirst = !refState.current.renderItem;
1371
+ if (isFirst || dataProp !== refState.current.data || numColumnsProp !== peek$(ctx, "numColumns")) {
1372
+ if (!keyExtractorProp && !isFirst && dataProp !== refState.current.data) {
1373
+ refState.current.sizes.clear();
1374
+ refState.current.positions.clear();
1375
+ }
1376
+ refState.current.data = dataProp;
1377
+ const indexByKey = /* @__PURE__ */ new Map();
1378
+ for (let i = 0; i < dataProp.length; i++) {
1379
+ const key = getId(i);
1380
+ indexByKey.set(key, i);
1381
+ }
1382
+ refState.current.indexByKey = indexByKey;
1383
+ calcTotalSizesAndPositions({ forgetPositions: false });
1345
1384
  }
1346
1385
  useEffect(() => {
1347
1386
  checkResetContainers(
@@ -1354,7 +1393,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1354
1393
  }, [extraData]);
1355
1394
  refState.current.renderItem = renderItem;
1356
1395
  const lastItemKey = dataProp.length > 0 ? getId(dataProp.length - 1) : void 0;
1357
- const stylePaddingTop = (_g = (_f = (_d = StyleSheet.flatten(style)) == null ? void 0 : _d.paddingTop) != null ? _f : (_e = StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _e.paddingTop) != null ? _g : 0;
1396
+ 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;
1358
1397
  const initalizeStateVars = () => {
1359
1398
  set$(ctx, "lastItemKey", lastItemKey);
1360
1399
  set$(ctx, "numColumns", numColumnsProp);
@@ -1558,10 +1597,42 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1558
1597
  useImperativeHandle(
1559
1598
  forwardedRef,
1560
1599
  () => {
1561
- const scrollToIndex = ({ index, animated }) => {
1562
- const offsetObj = calculateInitialOffset(index);
1563
- const offset = horizontal ? { x: offsetObj, y: 0 } : { x: 0, y: offsetObj };
1564
- refScroller.current.scrollTo({ ...offset, animated });
1600
+ const scrollToIndex = ({ index, animated = true }) => {
1601
+ var _a2;
1602
+ const state = refState.current;
1603
+ const firstIndexOffset = calculateOffsetForIndex(index);
1604
+ let firstIndexScrollPostion = firstIndexOffset;
1605
+ if (maintainVisibleContentPosition) {
1606
+ const id = getId(index);
1607
+ state.anchorElement = { id, coordinate: firstIndexOffset };
1608
+ (_a2 = state.belowAnchorElementPositions) == null ? void 0 : _a2.clear();
1609
+ state.positions.clear();
1610
+ calcTotalSizesAndPositions({ forgetPositions: true });
1611
+ state.scrollForNextCalculateItemsInView = void 0;
1612
+ state.startBufferedId = id;
1613
+ state.minIndexSizeChanged = index;
1614
+ firstIndexScrollPostion = firstIndexOffset + state.scrollAdjustHandler.getAppliedAdjust();
1615
+ state.scrollAdjustHandler.pauseAdjust();
1616
+ setTimeout(
1617
+ () => {
1618
+ const wasAdjusted = state.scrollAdjustHandler.unPauseAdjust();
1619
+ if (wasAdjusted) {
1620
+ refState.current.scrollVelocity = 0;
1621
+ refState.current.scrollHistory = [];
1622
+ calculateItemsInView(0);
1623
+ }
1624
+ },
1625
+ animated ? 1e3 : 50
1626
+ );
1627
+ }
1628
+ const offset = horizontal ? { x: firstIndexScrollPostion, y: 0 } : { x: 0, y: firstIndexScrollPostion };
1629
+ if (maintainVisibleContentPosition) {
1630
+ setTimeout(() => {
1631
+ refScroller.current.scrollTo({ ...offset, animated });
1632
+ }, 50);
1633
+ } else {
1634
+ refScroller.current.scrollTo({ ...offset, animated });
1635
+ }
1565
1636
  };
1566
1637
  return {
1567
1638
  getNativeScrollRef: () => refScroller.current,
@@ -1595,6 +1666,17 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
1595
1666
  getRenderedItem,
1596
1667
  updateItemSize,
1597
1668
  handleScroll,
1669
+ onMomentumScrollEnd: (event) => {
1670
+ const wasPaused = refState.current.scrollAdjustHandler.unPauseAdjust();
1671
+ if (wasPaused) {
1672
+ refState.current.scrollVelocity = 0;
1673
+ refState.current.scrollHistory = [];
1674
+ calculateItemsInView(0);
1675
+ }
1676
+ if (onMomentumScrollEnd) {
1677
+ onMomentumScrollEnd(event);
1678
+ }
1679
+ },
1598
1680
  onLayout,
1599
1681
  recycleItems,
1600
1682
  alignItemsAtEnd,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/list",
3
- "version": "1.0.0-beta.12",
3
+ "version": "1.0.0-beta.14",
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,